HTTP와 JSON을 함께 사용하여 Open API를 구현하는 형태로 많이 사용되는 REST에 대해 간략히 살펴본다.
REST는 Representational State Transfer의 약어로 네트워크상에서 클라이언트와 서버 사이의 통신을 구현하는 방법 중 하나이며, 대부분의 Open API는 REST 아키텍쳐를 기반으로 만들어져 있다.
클라이언트가 서버로 요청을 보냈을 때 서버가 이에 대한 응답으로 보내주는 Resource의 상태를 Representation이라고 할 수 있으며, 하나의 Resource는 여러 형태의 Representation으로 전달할 수 있는 것을 말한다.
Representation 의 종류로는 json, xml, text, rss 등이 있다.
원래 REST의 의미는 서버 응답을 앞에서 언급한 다양한 형태로 전달하는 개념으로 웹, 즉 HTTP의 기본 응답이 HTML인데 이를 JSON 등 다른 규격을 사용하는 것으로 접근한 것이다.
이에 따라 웹을 단순히 브라우저에서 콘텐츠를 이용하는 브라우저 서비스가 아닌 데이터를 주고받기 위한 API 서비스의 형태로 발전시킨 계기가 된다.
이러한 접근의 장점은 안정되고 검증된 웹 기술을 그대로 사용할 수 있다는 점이다. 예를 들어 서버 프로그램으로 자바, 서블릿 등을 사용할 수 있고, 스프링 프레임 워크 혹은 IBM, Oracle 등의 서버 솔루션을 그대로 사용할 수도 있어 성능, 안정성, 보안, 백업, 분산 등 여러 인프라의 재활용이 가능하다.
이러한 REST 방식 이전에는 원격으로 데이터를 주고받는 서비스를 구현하기 위해 별도의 프로토콜을 가지는 클라이언트-서버 통신 프로그램을 개발해야 했다. 이 과정에서 인증이나 보안, 서버 프로그램의 성능과 안정성과 같은 여러 문제를 개발자에 의존해 해결해야 했다. 이러한 서버 프로그램에 기존 웹 기술을 사용하는 발상은 획기적이었고, 프론트엔드 중심 개발의 발전과 함께 REST 혹은 RESTful API 형태로 정착하게 되었다.
이러한 구조를 통해 날씨 정보를 제공하는 REST API 서비스를 활용하면 웹 화면은 물론이고 스마트폰 앱, 냉장고 모니터 등에서도 날씨 정보를 보여주는 것이 가능하다
자바에서 REST API 개발을 위한 서버 프로그램의 표준 규격이다. 현재 자바 웹 개발에서 REST API를 구현하는 방법은 JAX-RS 또는 스프링 프레임워크의 RestController를 사용하는 방법이 있다. 스프링 프레임워크 없이 개발한다면 JAX-RS를 사용해야 하고, 스프링 프레임워크를 사용한다면 두 방법 중 한 가지를 선택해서 사용할 수 있다.
호환성을 위해서라면 JAX-RS를 사용하는 것이 좋고 스프링만 사용한다면 스프링의 RestController를 사용하는 것이 편리하다. 세부적인 차이가 있지만 기본 구조나 방법은 유사하다.
// JAX-RS 방식
@Path("/addebook")
public class RestApiService {
Logger logger = Logger.getLogger("RestApiService");
AddrBookDAO dao = new AddrBookH2DAO();
@GET
@Path("list")
@Produces(MediaType.APPLICATION_JSON)
public List<AddrBook> getList() {
List<addrBook> datas = dao.getAll();
logger.info("API call: /list ");
return dats;
}
}
위의 코드와 같이 주로 @로 시작하는 자바 어노테이션을 사용해 클래스와 메서드에 필요한 정보를 제공하는 것만으로 별도의 데이터 변환 과정 없이 손쉽게 API 서버 프로그램 개발이 가능하다. 톰캣을 실행하는 것만으로 서버가 동작하고 기존의 다른 웹 서비스도 함께 운영이 가능하다.
앞의 코드를 그대로 사용하고 REST API만 스프링 프레임워크를 사용하는 경우 다음과 같이 작성할 수 있다.
// 스프링 프레임워크 방식
@RestController
@RequestMapping("/addrbook")
public class RestApiService {
Logger logger = Logger.getLogger("RestApiService");
AddrBookDAO dao = new AddrBookH2DAO();
@GetMapping("list")
public List<AddrBook> getList() {
List<addrBook> datas = dao.getAll();
logger.info("API call: /list ");
return dats;
}
}