글 작성자: 개발섭

왜 쓰게 되었는가?

제 블로그 중 가장 많이 사랑을 받은 게시글인 Spring Boot와 React를 연동하여 개발환경을 만들어보자 를 통해서 Spring Boot를 React와 동시에 구성하는 방식에 대해서 알아보았습니다.

 

Spring Boot와 React를 연동하여 개발환경을 만들어보자

이글을 읽어보기전에!! 한번 고려해볼 점을 제가 적어뒀습니다 한번 참고 해보고 프로젝트를 진행해주세요! [Java/Spring] - Spring Boot와 React를 통한 개발환경을 구성할때 고민해볼점 Spring Boot와 React

sundries-in-myidea.tistory.com

 

Spring Boot를 통해 개발 환경 구성하기

1. Spring Boot 기본 설정하기

스프링 부트를 설정하는 방법은 이전 포스트 처럼 https://start.spring.io/에서 설정했다. 별다른 의존성은 추가하지 않고, web mvc만 추가해서 가장 기초적인 기능만 추가하도록한다.

2.  API 구성하기 

Spring Boot를 API를 가장 간단한 모습으로 구현한다. 간단하게 서버 시간을 알려주는 Controller를 구현했다. 

package com.ventulus95.reactdemo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
public class HelloController {

    @GetMapping("/test")
    public String time(){
        return "안녕하세요. 현재 서버의 시간은 " + new Date() + " 입니다!";
    }

}

그리고 다음의 http://localhost:8080/test로 url을 브라우저로 전달하게되면 다음과 같은 화면이 뜹니다. 

3. CORS 문제 해결하기

react를 구성해두었던 폴더에 있는 Package.json에 Proxy를 설정해줘야합니다.

{
  "name": "fe",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "4.0.3",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:8080/",
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

이 상태에서 실행을 하게되면 http:localhost:3000/test를 하게되면, 다음과 같이 backend의 값이 그대로 전달되는 것을 확인해볼 수 있습니다. 

4. React에 Spring Boot의 API을 연결하기

React에 Spring Boot에서 생성한 API를 연결해서, 화면을 출력하는 것을 확인해봅니다. 

import logo from './logo.svg';
import './App.css';
import { useEffect, useState } from 'react';


function App() {
  const [message, setMessage] = useState("")

  useEffect(()=>{
    fetch("/test")
      .then(res => res.text())
      .then(m=>setMessage(m))
  }, [])

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          {message}
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

다음처럼 화면이 구성되는 것을 확인해볼 수 있습니다. 

5. Nginx에 연결시키기.

4번까지는 사실상 이전 포스팅과 동일한 방식으로 진행이 되었는데, 우리는 이전 포스팅에서 Frontend를 Nginx로 연결을 해놓은 상태이고 NPM을 통해서 운영하지 않기 때문에, nginx를 통해서 Spring Boot를 통해서 연결되는 것을 확인해보아야한다.

 

Frontend를 설정하기 위해서 미리 설정해두었던 파일을 수정해야한다.

vi /etc/nginx/sites-available/fe.conf

/test라는 api를 nginx에서도 사용해야하기때문에 다음처럼 Proxy를 생성해서 붙여야한다. 

location / {
  root /home/build; //build파일 폴더 위치 삽입할 것
  index index.html index.htm;
      try_files $uri $uri/ /index.html;
  }
  
  location /test  {
  	proxy_pass http://localhost:8080;
  }
}

이런식으로 연결을 하게되면, http://localhost를 통해서 이전과 같은 화면이 등장하게 된다. 

왜 이렇게 써야하는가?

[추후 작성]

 

결론

원래 방식보다 현재 이 방식으로 코드를 구성하는 것이 코드 관리를 훨씬 효율적으로 할 수 있다고 생각한다. 그리고, 이런 식으로 구성하게되면, 프론트는 프론트대로 백엔드는 백엔드대로 따로 구성할 수 있게 된다. 

이전에 작성했었던 포스팅을 참고하자면, 스스로도 너무나도 비효율적인 방법이라고 생각을 많이했었다.

특히, 여러 프로젝트를 많이 진행하면서, BE와 FE를 붙힐 이유도 없으며, 따로 구현하는 것이 코드 관리에 있어서 편리함을 많이 느꼈기도 했었다.

이 글을 처음 썼을 당시에는 연동기가 많이 없기도 했거니와... 내가 프로젝트 경험 자체가 너무 부족해서 Proxy는 뭐며.. React에서 왜 저런 코드를 사용해야하며와 같은 여러가지 미숙함으로 인해서 예상밖으로 많이 비효율적인 프로젝트 구성기가 되지 않았나 싶다.

그래서 이런 글을 다시 쓰게되었고, 물론 현재는 React+SpringBoot를 연동하는 게시물들이 많이 늘어났으며 방식도 여러가지로 늘어났지만, 유입되었던 글을 읽으면서 좀 더 개선 시킨 버전을 읽어볼 수 있으면 좋겠다.