[Spring boot] MVC 패턴을 이용한 REST API 개발

지난 포스트에서 REST API가 무엇인지, 어떻게 설계를 해야하는지에 대해서 다뤄봤습니다. REST API는 HTTP Method를 이용하여 행위를 정하고, URI를 이용해서 리소스를 정하는 방식으로 동작하는 서버였는데요.

이번 포스트에서는 MVC 패턴 + Spring boot 2.x 조합을 이용하여 간단한 REST API 서버를 개발해보도록 하겠습니다.

 

What is MVC ?

MVC 패턴에 대해서는 아래의 글에서 다뤄 본적이 있는데요. 혹시 MVC 패턴에 대해 다시 복습해보시거나, 잘 모르신다면, 아래의 글을 보시기 바랍니다.

2016/12/29 - [Programming/JavaFX] - MVC Pattern에 기반한 GUI 라이브러리 JavaFX

 

MVC Pattern에 기반한 GUI 라이브러리 JavaFX

Java GUI Programming 라이브러리에는 AWT, SWT, Swing, JavaFX가 있습니다. 저의 경우, AWT와 Swing으로만 프로그래밍 했었는데요. 아마 해보신 분들이라면, Java의 GUI 프로그래밍이 좀 답답함을 많이 느끼실 것

blog.neonkid.xyz

 

개발 환경 설정

이제 본격적인 서버 개발을 해보도록 하겠습니다. 먼저 개발을 위해 환경 설정을 진행할텐데, 그 전에 우리가 데이터를 저장하기 위해 어떤 데이터베이스를 사용할 것인지를 결정하는 게 좋겠죠? 이 포스트에서는 Java 8과 MySQL을 이용해보도록 하겠습니다.

인텔리J에서 제공하는 Spring Initializr를 이용해 Java 8과 Gradle Project로 맞춰주도록 합시다.

여기에서 REST API를 구현하기 위해 Spring Web 디펜던시를 추가하고, DB와의 연동을 위해 Spring Data JPA와 MySQL Driver를 선택해줍니다. 그리고 여기에 추가로 Lombok을 하나 더 추가하겠습니다.

Lombok은 데이터 모델링을 편리하게 해주는 라이브러리입니다. Getter, Setter 등을 어노테이션을 이용해 쉽게 구현할 수 있도록 하며, 빌드 패턴을 지원하여 컨버팅 등의 클래스 구현을 쉽게 해주는 기능을 가지고 있습니다.

Spring Data JPA는 Spring에서 Database와 연동하기 위한 디펜던시인데, 본래는 MyBatis라는 것이 있지만 Spring boot JPA는 Object-oriented Programming 형태로 DB에 접근할 수 있도록 하여, 더욱 더 쉽게 DB 연동을 구현해주는 라이브러리입니다. 차후, JPA와 Hibernate를 다루는 포스트에서 상세하게 이야기 하도록 하겠습니다.

개발 환경 설정을 좀 더 편하게 설정 하기 위해, application.properties를 application.yml 파일로 수정해줍니다.

이 설정을 진행하기 전에, 먼저 MySQL 서버가 구축되어 있는 상태여야 합니다. 이 부분에 대해서는 포스트에서 다루지 않을 것이며, 로컬 환경이라면 Docker 등의 컨테이너 환경을 사용하는 것을 권장드리고, 서버가 있다면 그것을 쓰는 것이 좋겠죠?

서버 설치가 끝났다면, 위의 설정대로 username, password를 입력하고, DB명을 정해줍니다. 단, DB는 만들어두지 않습니다.

JPA 옵션에서 ddl-auto 옵션을 create로 설정해주고, Database를 자동으로 만들어주도록 합시다.

설정이 끝났으면, 상품 데이터 모델을 저장할 Domain, API를 구현할 Controller와 Repository 이렇게 3가지 패키지를 만들어주면, 기본적인 프로젝트 설정이 모두 끝났습니다.

 

REST API 구현

개발 환경 설정이 끝났으니 이제 바로 REST API 구현을 시작해보도록 하죠. Spring boot에서 REST API를 구현할 때는 데이터베이스를 서버가 시작할 때 자동으로 생성해주고, 이제 남은 건 Entity를 구현해야 합니다. 상품에 대한 Entity를 만들어보도록 하겠습니다.

Spring boot JPA는 간단한 어노테이션 만으로도 테이블을 정의할 수 있고, 이를 커밋까지 해줍니다. 그리고, 이들 데이터에 접근하기 위해서 Getter와 Setter를 정의해야 하는데, Getter Setter는 인텔리J에서 Alt + Insert 단축키를 통해서도 쉽게 구현할 수 있지만, 그렇게 되면 코드가 길어지므로 Lombok 라이브러리에서 제공하는 Getter 어노테이션을 이용해서 한 번에 모든 변수들에 대한 Getter를 구현해주면 위와 같이 깔끔한 코드가 나오게 됩니다.

Setter의 경우, 각 멤버 변수별로 set 메소드를 일일이 불러와야 하기 때문에 코드가 지저분해지므로, 생성자에 Builder 어노테이션을 주고, 빌더 패턴을 사용해 데이터를 넣을 수 있도록 합니다.

마지막으로 NoArgusConstructor 어노테이션은 실제로 REST API를 이용하여 데이터를 가지고 올 때, 기본 생성자가 있어야 하는데, 이를 생성하지 않고, 어노테이션을 줌으로써 기본 생성자를 자동으로 만들도록 해주면 깔끔한 코드가 됩니다.

그 다음은 Repository를 인터페이스로 구현하고, Spring Data JPA에서 제공하는 JpaRepository를 상속받도록 합니다. Generic에는 위에서 만들어준 Item 클래스와 PK의 타입인 Long 타입으로 주면 됩니다.

본래 Repository를 구현해 준 뒤, 서비스 클래스를 구현하여, Repository 인터페이스를 주입한 다음, 서비스에서 데이터를 처리하는 방식으로 구현해야 하지만, 여기서 별도의 처리 로직이 필요없기 때문에 바로 Controller 구현으로 넘어가도록 하겠습니다.

설계 포스트에서 했던대로 GET, POST, PUT, DELETE 4개의 메소드를 만들었습니다. 각 메소드에 대해서는 **Mapping으로 끝나는 어노테이션을 붙여주면 되고, 반환되어야 하는 데이터 타입은 ResponseEntity를 통해 기본 타입을 사용할 수 있고, 커스텀 클래스를 이용하는 방법도 있지만, 여기서는 ResponseEntity 클래스를 이용하였습니다.

데이터베이스 I/O 작업은 Repository 인터페이스에서 처리됩니다. 기본적으로 JpaRepository에서는 save 메소드를 통해 INSERT 혹은 UPDATE 쿼리가 이루어지고, find** 메소드를 통해 SELECT가 이루어집니다.

 

Test

API 서버가 제대로 동작하는지 간단한 테스트를 진행하도록 하겠습니다. 테스트를 위해 Curl을 이용해보도록 하겠습니다.

$ curl http://localhost:8080/api/items | json_pp

처음에는 아무것도 나타나지 않습니다. 아무런 상품도 추가하지 않았기 때문입니다. 따라서 우리는 POST 메소드를 이용해 새롱누 상품을 추가 해보도록 하겠습니다.

 

$ curl -X POST -H "Content-Type: application/json" --data '{ "name": "apple", "price": 3000 }' http://localhost:8080/api/items | json_pp

POST 메소드를 이용해 위와 같이 명령어를 입력한 후, GET 메소드를 부르면, 위와 같이 새로 추가된 상품이 나타나고 있음을 알 수 있습니다.

 

$ curl -X PUT -H "Content-Type: application/json" --data '{ "name": "apple", "price": 1500 }' http://localhost:8080/api/items/1 | json_pp

같은 방법으로 PUT 메소드를 사용해보겠습니다. 상품의 가격이 비싸게 책정 되어, 가격을 내리고자 하는 경우, PUT 메소드를 이용해서 바꿀 수 있습니다.

PUT, POST를 이용해 JSON 데이터를 전달할 경우, Curl을 사용할 때는 Header에 반드시 application/json을 입력해야 합니다.

 

$ curl -X DELETE http://localhost:8080/api/items/1 | json_pp

마지막으로 데이터가 잘 삭제되는지도 확인해보죠.

ID 값을 이용해 정상적으로 데이터가 삭제 되어, GET 메소드를 이용하니 더 이상 나오지 않는 모습입니다.

 

 

마치며...

여기까지 아주 간단한 REST API 서버를 개발해봤습니다. 서비스에 따라서 어떤식으로 Controller 코드를 구현해야 하고, 모델링은 어떻게 하여야 하며, 반환 값이나 요청 값의 형태를 어떻게 줘야할지, 어떤 값은 제외하고, 어떤 값을 줘야 할지 등을 생각해야 하기 때문에 실제 실무에서는 이 포스트에서 다루는 것보다 다소 어려울 것입니다.

다음 포스트에서는 Spring Data Rest를 이용한 REST API 개발에 대해 적어보도록 하겠습니다.

comments powered by Disqus

Tistory Comments 0