나는 실내 식물을 기르는 것을 좋아한다. 물주기/액체 비료주기 스케줄과 분갈이, 고형비료 추비 날짜 등을 계산해서 알려주는 서비스를 만들어볼까 한다.
우선 백엔드는 Spring boot를 사용할 것이다. 나머지 계획은 다음과 같다.
Gradle
지난 프로젝트에선 Maven을 사용했다. (이런 소규모 프로젝트에서도 유효할진 모르겠지만) Gradle이 최대 100배 더 빠르다고도 하고 써보지 않은 기술을 배우는 것은 즐거운 일이므로 이번엔 Gradle을 사용할 것이다.
MariaDB
NoSQL을 써야할 좋은 이유를 발견하지 못했으므로 관계형 Database
JPA
지난 프로젝트는 MyBatis를, 그 이전은 Model1 학습을 위한 프로젝트라 PreparedStatement를 사용했다. 이번엔 ORM을 공부해보고 싶은 관계로 JPA를 사용할 것이다.
React.js
접해본 프론트엔드 라이브러리는 jQuery 뿐이다. 얕게나마 독학한 React.js를 연습할 겸 React.js를 접목해볼 것이다.
덧붙여, 지금까진 AWS Lightsail에 FileZilla 조합으로 배포하였다. 이번엔 Jenkins 자동배포를 도전해볼까 한다.
IntelliJ Community 버전에선 SpringInitializr를 사용할 수 없으므로 https://start.spring.io/ 에서 프로젝트를 생성한다.
Spring Boot의 릴리즈 버전에 붙은 접미사의 의미
1) M1: Milestone 1, 프리 알파 단계에 있는 한 종류. 특정한 집합의 기능이 포함되며, 완성되자마자 공개
2) RC: Release Candidate, 마지막 제품이 될 가능성이 있는 베타버전. 상당한 버그가 나타나지 않으면 출시할 준비가 되었음
3) GA: General Availability: 필요한 모든 상업화 활동이 완료되어 웹이나 물리매체를 통해 시장에서 이용할 수 있게 됨을 의미
4) SNAPSHOT: 아직 개발단계
Jar와 War
지난 프로젝트에선 JSTL과 JSP를 사용하여 화면을 구성한 관계로 War로 패키징하여 AWS에 배포하였다. 그러나 이번엔 React.js를 사용하였으므로 Jar를 선택한다.
node.js, yarn 등 설치 과정은 생략
npx create-react-app not-a-gardener
Spring 프로젝트에 간단 컨트롤러를 작성해 서버에서 미니 데이터를 보낸다.
package com.buckwheat.garden.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
public class TestController {
@GetMapping("/hello")
public String hello(){
System.out.println("hello() 호출");
return "What time is it now? -- " + new Date();
}
}
React 프로젝트의 package.json을 수정한다.
Spring은 기본적으로 8080 포트를, React.js는 기본적으로 3030 포트를 사용한다. 고로 CORS(cross-origin requests) 에러를 해결하기 위해 프론트 쪽에서 Proxy를 잡아준다.
"proxy": "http://localHost:8080",
이제 서버를 켜고 다음 명령어로 확인해보면
curl http://localhost:3000/hello
"What time is it now? -- " + new Date();
코드로 작성한 정보를 확인할 수 있을 것이다.
다른 출처의 리소스를 사용하는 것을 제한하는 보안 방식. CORS 에러의 원인이 되는 정책.
protocol(http, https...), host(domain), port가 같아야 같은 출처.
다른 출처의 자원을 공유할 수 있게 한다. SOP에서 허용하는 출처를 설정해준다.
CORS를 해결하기 위해선 Origin Allow 속성에 클라이언트에서 보내는 출처를 추가해주어야 한다. 배포하는 곳에서도 따로 설정을 해주어야 한다고 한다. 단, 개발 환경에서는 프록시 서버를 설정하여 해결할 수 있다.
이제 간단히 App.js를 수정하여 Rest API의 데이터 출력을 테스트해본다.
import './App.css';
import React, {useState, useEffect} from 'react';
function App() {
const [message, setMessage] = useState("");
useEffect(() => {
fetch('/hello')
.then(response => response.text())
.then(message => {
setMessage(message);
});
}, [])
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">{message}</h1>
</header>
</div>
)
}
export default App;
서버에서 넘어온 데이터가 잘 출력되는 걸 확인할 수 있다.
위의 Spring, React 연동 과정은 개발환경에서 Proxy 서버를 설정한 것이다. 배포 환경에선 추가 설정이 필요하다.
어쨌든 개발환경에선 Spring과 React 연동을 완료했으므로, 이제 개발만 하면 된다.
참고
https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#executable-jar
https://countryxide.tistory.com/41
https://sundries-in-myidea.tistory.com/71
https://7942yongdae.tistory.com/136
https://snupi.tistory.com/210