본문 바로가기

IT/Programming

Java EE 7 만으로 REST API 만들기

요즘 어플리케이션의 화두는 단연 어떻게 빠르게 개발하여 Deploy할 수 있는가에 있는 듯 하다. 새로운 프로젝트를 Setup하고 Deploy하는 과정이 예전에 비해서 확연하게 간소해지고 빨라졌다. 이는 각종 SNS를 선두로 하고 있는 모바일 서비스와 언제든 새로운 서비스를 빠르고 간편하게 올리고 순위 경쟁에서 선두를 올려야 하는 스타트업 SW업계의 특성을 반영한다. 안정성보다는 빠른 배포, 변경점이 생길 때 재빨리 내리고 다시 올릴 수 있는 긴밀함이 더 우선인 경우가 많아졌다.


자바의 경우도 이런 특성을 반영하듯 빠른 Configuration이 가능하고 초기 설정은 최대한 줄일 수 있고, 배포는 빨리 할 수 플랫폼이 생겨났는데, Spring Boot가 대표적인 경우로, Spring Initializr(https://start.spring.io/)에서 프로젝트를 셋업하고 간단한 REST API를 만들어서 실행하기 까지 5분 정도면 충분하다. 


이는 예전 J2EE 기반의 서버환경에서 EJB기반의 Web Application을 개발하고, 이를 WAS에 올리기 위해 겪었던 노력에 비하면 엄청나게 간소하고 불필요하게 반복되는 작업을 획기적으로 줄여준 것이다. 


하지만 사실 Java EE 7만으로도 별다른 의존성 없이 간단하고 빠르게 REST API를 만들 수 있다. Spring Boot는 Dependency가 Spring Boot와 Spring에서 제공하는 Spring Framework (Data, Security, Web, 등)에 있기 때문에 Single Output으로 만들어진 JAR Package는 용량이 상당하다. 


이는 변경이 가능한 코드에 비해서, 차지하는 의존 라이브러리가 많기 때문에 민첩한 변경과 배포에 대해서는 단점이 될 수 있겠다. 컨테이너 기반의 Docker로의 배포를 예로 들자면, 적층적으로 필요한 라이브러리를 쌓아가는 (OS->WAS->APP) 형태에 대해서, 언제든 변경 가능한 APP의 용량이 더 많이 차지하게 되는 상황이 될 수도 있겠다.


이에 오늘은 순수 Java EE만을 가지고 REST API를 만드는 방법을 살펴보고자 한다. 


참고로, 예제에 사용된 환경은 다음과 같다. 



초기 프로젝트 셋업 - Maven으로 WebApp의 Skeleton 프로젝트를 만든다.

CLI (Command Line Interface)에서 Maven 명령어를 이용하여 만들거나, IDE에서 Maven프로젝트를 만들 수 있다. 여기서는 첫번째 방법(CLI Maven 명령어)을 프로젝트를 생성해 보겠다.


CLI에서 Maven 명령어를 이용하여 프로젝트 생성.

mvn archetype:generate -Dfilter=com.airhacks:javaee7-essentials-archetype


위와 같이 프로젝트를 생성하고자 하는 상위 디렉토리에서 입력한뒤 프로젝트를 생성할 수 있다. 



다음과 같이 빌드가 성공한다. 



다음과 같은 폴더 구조가 생성된다. (위에서 패키지를 com.moondeuk 으로 설정했지만 Archetype의 Group ID로 패키지가 만들어졌다.)




이를 IDE에서 Maven프로젝트로 Open하도록 하겠다.




생성되어진 프로젝트의 POM 파일 (pom.xml)은 다음과 같다. 의존성은 javaee-api 하나로, 그것도 provided로 WAS가 제공한다.


이제 본격적으로 Code를 작성해 보도록 하겠다. 이 프로젝트의 목적은 일단 2가지 API를 갖는 REST 서비스를 만드는 것이다. 


GET: /cars

POST: /cars


GET 메서드에서는 현재 가지고 있는 CAR를 JSON 형태로 보여주고, POST 메서드에서는 새로운 CAR를 생성할 수 있다.


Model Class인 Car를 정의해 보도록 하자.




다음 Controller 역할을 하는 Class를 우선 만들어 보도록 하겠다.



JAVA의 표준 REST API인 JAX-RS는 다음과 같은 Annotation을 사용할 수 있다. 


@Path - URI path를 지정한다.

@PathParam - URI path의 parameter를 나타낸다.

@Consumes - Resource Class의 메소드가 사용할 미디어 타입(XML, PLAIN, JSON, 등)을 지정한다.

@Produces - Resouce Class의 메소드가 생성할 미디어 타입(XML, PLAIN, JSON, 등)을 생성한다.

@GET - GET request에 반응하는 메소드

@POST - POST request에 반응하는 메소드

@PUT - PUT request에 반응하는 메소드

@HEAD - HEAD request에 반응하는 메소드

@DELETE - DELETE request에 반응하느 메소드

@QueryParam - URL의 Query String의 Parameter를 나타낸다.

@HeaderPAram - header의 parameter를 나타낸다.

@CookieParam - cookie의 parameter를 나타낸다.


참고 - https://www.javatpoint.com/jax-rs-annotations-example


이에 Cars를 반환하는 getCars() 메소드와 새로운 Car를 입력받을 수 있는 createCar(Car car) 메소드를 만들었다.

먼저 이렇게 Resource를 만들고, 에러가 나는 곳에서 IDE의 자동 생성 기능을 이용해 필요한 Resource들을 만들 수 있다. (TDD접근 방식과 비슷하다.)







그렇게 해서 CarService Class도 생성한다. CarService는 EJB로서 의존성 주입을 받기 위해 @Inject라는 Annotation을 사용한다. 이렇게 하면 WAS Container가 같은 Type의 EJB를 주입하여 준다.

CarService는 Controller에서 사용하기 위한 EJB이므로, @Stateless라는 EJB Annotation을 사용한다.



pono property 위에 있는 @NotNull Annotation은 validator로서 해당 property에 대해서 Null이 입력 되지 않도록 validation설정을 할 수 있다.  Resource에서 받은 값이 Null이면 에러를 return할 것이다.


마지막으로, 테스트 목적의 서비스이므로,  미리 데이터를 입력해 놓기 위해 service의 생성자에 아래와 같은 코드를 추가하도록 한다.



이렇게 하면 일차적으로 JAVA EE 7 Container가 실행할 수 있는 로직은 만들어진 셈이다. 오늘은 테스트 목적이므로 간단히 여기까지 작성한후 이제 WAS에 deploy해보도록 하겠다.


일단 JBOSS가 running되고 있지 않으면 먼저 서버를 실행하도록 한다.



처음 프로젝트를 생성할때 POM파일에는 javaee-api 외에 다른 의존성은 없었지만, JBOSS에 쉽고 빠른 deploy를 위해서 한가지 plug in을 추가하도록 하겠다.



JBOSS의 서버그룹을 설정한다. 별다른 설정없이 설치했으면, default로 설치되는 server group인 main-server-group을 입력하여 준다.


이렇게 하면, 이제 Maven의 플러그인으로 JBOSS에 손쉽게 WAR파일을 Deploy할 수 있게 된다. CLI창에서 다음을 입력한다.


mvn wildfly:deploy 



성공적으로 BUILD가 되었다는 결과가 나오면 정상적으로 build가 완료되고, deploy까지 완료되었다는 상태이다.


자 이제 실제 작동하는지 확인해보도록 하겠다.


REST API를 테스트하는 Tool인 Chrome App의 POSTMAN을 사용하여 URI에 기본포트인 8080과 Maven 프로젝트의 Final Name인 "car-build-javaee", JAXRSConfiguration에 설정된 ApplicationPath인 "resources", 그리고 resource클래스의 Path인 "cars"를 이용하여, 아래와 같은 URI를 입력한다.


http://localhost:8080/car-build-javavaee/resources/cars 


그리고 Method는 GET을 선택하여, SEND를 누르면 아래와 같은 결과가 나타난다.



POST 메서드도 테스트를 해보자. 다음과 같이 Body에 JSON 형식의 데이터를 넣고 미디어 타입을 JSON으로 해준다. 그리고 나서, SEND를 누르면, 204 No Content 가 나오면 정상이다.



그리고 나서 다시 GET 메서드로 데이터를 확인해보면, POST로 입력한 데이터가 정상적으로 입력되었음을 알 수 있다. 



이렇게 순수 Java EE로만 Code를 작성하여, WAR 패키지로 WAS에서 구동하는 방법을 간략히 살펴 보았다. 이렇게 초기구성과 간단한 API를 구성하는데, 많은 시간을 들이지 않고 개발할 수 있음을 알 수 있었다. 패키지된 war파일의 용량은 불과 7 KB에 불과하다.



테스트에 사용된 source code는 아래 Github에 있으니 참고하기 바란다.


https://github.com/moondeuk/car-build-javaee