Spring Boot로 REST API 서버 만들기

J_Eddy·2022년 6월 18일
5

회사 생활을 하면서 Spring Boot로 웹서버를 만들어 본 경험이 있다. 이를 바탕으로 팀을 꾸려 AWS + Spring Boot + Python 에 React를 곁들인 MAIB(Match for AI Bot)프로젝트를 구현하기로 하였다. 이 프로젝트는 Battle Ground라는 게임에서 친구들과 다같이 할 경우 자동적으로 밸런스에 맞는 팀을 생성하게 도와주는 프로젝트이다. 먼저 Spring Boot를 통해 Oracle과 Python, React를 통신하는 API 서버를 만들어 보려 한다.

Spring boot 2.6.8 + Gradle 7.4.1 + Java 11 의 스펙으로 만들고 DB는 Oralce XE 11G R2버전으로 구현하려 한다.

📌 Spring Boot 프로젝트 생성

먼저 Spring Initializr를 통해 Gradle 기반의 Spring Boot 프로젝트를 생성했다. 이름은 mas(Maib Api Server)로 지었다. 프로젝트를 생성했을 때 가장먼저 하는 작업은 java버전 및 gradle 버전을 확인 설정하는 과정을 한다. 이후 Maven Repository (https://mvnrepository.com/) 에서 필요한 라이브러리들을 추가하였다. 처음에 프로젝트를 만들 때 Spring Ititializr에서 추가 할 수 있지만, 어디에 사용되는지도 모르고 추가하는것보다는 필요한 라이브러리들을 찾아 그때 그때 추가하는 것을 선호한다(이게 공부에 더 좋은것 같다)👋. 나는 아래와 같이 라이브러리들을 추가하였다.

여기서 조금 헤매었던것이 롬복 관련설정이었다. 처음에는 compileOnly 'org.projectlombok:lombok:1.18.12' 만 추가해서 사용하는데 자꾸 Getter가 동작을 안하여 에러가 발생하였다. 그래서 찾아보니 Gradle 5버전 이상에서는 annotationProcessor 'org.projectlombok:lombok:1.18.12' 도 같이 추가해줘야 한다는것을 알고 같이 추가해줬다!
이후 나머지는 Oracle, JPA, MYBATIS관련 설정이다.

🔩 Oracle 연결하기

이 프로젝트는 AWS EC2환경에 Oracle을 올려 둔 상태이다. 따라서 application.properties에 아래와 같이 추가하였다. []에 들어가는 항목은 미리 설정해둔 Oracle 및 AWS설정에 맞게 입력하면 된다.

spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:[HOST]:[PORT]/XE
spring.datasource.username=[USSERNAME]
spring.datasource.password=[PASSWORD]

프로젝트 구조 잡기

보통 프로젝트를 생성하고 구조를 잡는데는 많은 스타일이 있다. 나도 처음 프로젝트를 진행 할 때에는 아래와 같이 프로젝트 구조를 잡았다.

project

    controller
     HomeController
     BoardController
     MemberController
     ...
   model
     HomeModel
     BoardModel
     MemberModel
     ...
   repository
     HomeRepositroy
     BoardRepositroy
     MemberRepositroy
     ...
   service
     HomeService
     BoardService
     MemberService
     ...

지금 다시봐도 정신이없다. BoardController를 찾으려면 controller 패키지를 열어 찾아야하며 지금은 3개만 보이지만 무수히 많은 컨틀로러가 있다고 하면.. 벌써 어지럽다..🤮
그래서 다음과 같이 프로젝트 구조를 변경하고 지금도 이 구조를 유지하며 사용하고 있다. 장점은 훨씬 깔끔하며 기능에 맞는 패키지를 찾아 그 안에서 해결할 수 있다.

project

   home
     controller
        HomeController
     model
        HomeModel
     repository
        HomeRepositroy
     service
        HomeService
  board
     controller
        BoardController
     model
        BoardModel
     repository
        BoardRepositroy
     service
        BoardService
  member
     controller
        MemberController
     model
        MemberModel
     repository
        MemberRepositroy
     service
        MemberService
   ...

Controller

먼저 테스트를 위해 TEST라는 스키마 안에 HELLO라는 테이블에서 정보를 가져온느 api를 만들어 보려한다. 컨트롤러는 아래와 같이 구현을 하였다.

(오 그냥 기본이네~ 그런데 ResponseEntity는 뭐지..?)
나도 처음에 ResponseEntity가 뭐지 생각했다. 그냥 ResponseDto를 넘겨 주면 안되나 싶었다. 정답은 없다. 다만 ResponseEntity를 사용하는 이유는 명확하다.

먼저 ResponseEntity는 httpentity를 상속받아 HttpStatus상태코드도 함께 넘겨준다. 내가 이 상태코드도 같이 넘겨주려 하는 이유는 Exception을 관리 하기 위해서이다. 프로젝트를 진행하다 보면 Exception관리가 상당히 중요하다. 그래서 이 프로젝트에도 따로 BizExceptionCode를 구현하여 코드 관리를 해주었다.

Model

Model에는 Entity, Response, Request 세가지를 사용하는데 이번에는 Request를 제외한 두가지만 사용하였다.
Entity에는 아래와 같이 스키마와 테이블을 명시해주었고, 그옆엔 Response이다.

JPA

JPA를 사용하기 위해 아래와 같이 Repository를 추가하였다.
그리고 JPA를 사용하면 쿼리를 잘 보지 않게 되는데 이를 방지하고 application.properties에 아래와 같이 추가하여 쿼리문을 log에서 볼 수 있게 하였다.

Service

서비스 단은 아래와 같이 구현아였다. 여기서 중요한 부분은 findById에서 orElseTrow를 통해 예외 관리를 해준 부분이다. 해당 코드를 보면 BizException이라는 커스텀 클래스를 통해 예외처리를 하고 있다.

Exception

Exception관리를 하기위해 아래 두 클래스를 생성하였다.
BizException에서는 RuntimeException을 상속받아 구현하였다.

BizExceptionCode에는 status, code, message를 통해 커스텀하게 에러관리를 할수 있게 구현하였다.

결론

이와 같이 처음에 프로젝트 구조를 잡는일은 매우 중요하며, 시간을 들일 가치가 충분히 있다. 마지막으로 위에서 작성한 api의 테스트 결과이다.

결과

쿼리 로그

profile
논리적으로 사고하고 해결하는 것을 좋아하는 개발자입니다.

2개의 댓글

comment-user-thumbnail
2023년 4월 19일

프로젝트 정말 멋지네요 MAIB 프로젝트 구경 할 수 있을까요?

답글 달기
comment-user-thumbnail
2024년 4월 23일

스프링부트로 api 서버를 구축해야하는데
덕분에 도움이 많이 되었습니다
혹시 서버구축하는데 소요기간은 어느정도 되었나요? 저기에 플러스로 토큰값도 관리를 위해
레디스 서버를 연결하고 시큐리티 설정도 해야하는데, 전부 다 한달안에 가능할까오?? 고수님의 조언 부탁드립니다!

답글 달기