밍쎄의 코딩공간

[스프링부트 핵심가이드] - 05. API를 작성하는 다양한 방법 본문

개발서적/IT

[스프링부트 핵심가이드] - 05. API를 작성하는 다양한 방법

밍쎄 2023. 9. 3. 22:25

5장은 각 HTTP 메서드에 해당하는 API를 개발해보고 그 과정에서 필요한 내용을 배운다.

 

5. API를 작성하는 다양한 방법

5.1 프로젝트 설정
5.2 GET API 만들기

 5.2.1 @RequestMapping으로 구현하기

 5.2.2 매개변수가 없는 GET 메서드 구현

 5.2.3 @PathVariable 을 활용한 GET 메서드 구현

 5.2.4 @RequestParam 을 활용한 GET 메서드 구현

 5.2.5 DTO 객체를 활용한 GET 메서드 구현

5.3 POST API 만들기

 5.3.1 @RequestMapping 으로 구현하기

 5.3.2 @RequestBody를 활용한 POST 메서드 구현

5.4 PUT API 만들기

 5.4.1 @RequestBody를 활용한 PUT 메서드 구현

 5.4.2 ResponseEntity를 활용한 PUT 메서드 구현

5.5 DELETE API 만들기

 5.5.1 @PathVariable과 @RequestParam을 활용한 DELETE 메서드 구현

5.6 REST API 명세를 문서화하는 방법 - Swagger
5.7 로깅 라이브러리 - Logback

 5.7.1 Logback 설정

 5.7.2 Logback 적용하기

 


GET API 만들기

- GET API : 웹 애플리케이션 서버에서 값을 가져올 때 사용하는 API

 

먼저 controller 패키지를 생성하고 GetController 클래스를 생성합니다.

컨트롤러에 @RestController와 @RequestMapping 을 붙여 내부에 선언되는 메서드에서 사용할 공통 URL생성한다.

@RequsetMapping 으로 구현하기

@RequestMapping 어노테이션을 별다른 설정 없이 선언하면 HTTP의 모든 요청을 받는다. 

거란 GET 형식의 요청만 받기 위해서는 어노테이션에 별도 설정이 필요하다.

 

별도의 매개변수 없는 GET API를 구현하는 경우 밑과 같이 구현할 수 있다.

@PathVariavble을 활용한 GET 메서드 구현

매개변수를 받을 때 자주 쓰이는 방법 중 하나는 URL 자체에 값을 담아 요청하는 것이다.

1번 줄에 있는 요청 예시 URL을 보면 이 메서드는 중괄호로 표시된 위치의 값을 받아 요청하는 것을 알 수 있다. 값을 간단히 전달할 때 주로 사용하는 방법이며, GET요청에서 많이 사용된다.

 이러한 코드를 작성할 땐 @GetMapping 어노테이션 값으로 URL을 입력할 때 중괄호를 사용해 어느 위치에서 값을 받을지 지정해야 한다. 또한 메서드의 메개변수와 그 값을 연결하기 위해 3번 줄과 같이 @PathVariable 을 명시하며, @GetMapping 어노테이션과 @PathVariable에 지정된 변수의 이름을 동일하게 맞추어야 한다.

 

@RequestParam을 활용한 GET 메서드 구현

URL에서 '?'의 기준으로 우측에 '(키)=(값)'형태로 구성된 요청을 전송하는 방법이다. 애플리케이션에서 이 같은 형식을 처리하려면 @RequestParam을 활용하면 되는데, 밑과 같이 @RequestParam 어노테이션을 명시해 쿼리 값과 매핑하면 된다.

1번 줄을 보면 '?' 오른쪽에 쿼리스트링이 명시 돼 있다. 쿼리스트랑에는 키가 모두 적혀있기 때문에 이 값을 기준으로 메서드의 매개변수에 이름을 매핑하면 값을 가져올 수 있다.

 

만약 쿼리스트링에 어떤 값이 들어올지 모른다면 밑과 같이 Map 객체를 활용할 수 있다.

이 형태로 코드를 작성하면 값에 상관없이 요청을 받을 수 있다. 

 

DTO객체를 활용한 GET 메서드 구현

DTO는 Data Transfer Object 의 약자로, 다른 레이어 간의 데이터 교환에 활용된다. 간략하게 설명하면 각 클래스 및 인터페이스를 호출하면서 전달하는 매개변수로 사용되는 객체이다. DTO는 데이터를 교환하는 용도로만 사용이 되므로, 별도의 로직이 포함되지 않는다.

 

DTO 클래스에는 전달하고자 하는 필드 객체를 선언하고 getter/setter메서드를 구현한다. DTO 클래스에 선언된 필드는 컨트롤러의 메서드에서 쿼리 파라미터의 키와 매핑된다. 

 

아래의 1번째 줄은 윗 코드와 동일한 형태의 쿼리스트링을 가진다. 다만 3번 줄과 같이 위에 비해 코드의 양을 줄일 수 있다.

POST API만들기

 웹 애플리케이션을 통해 데이터베이스 등의 저장소에 리소스를 저장할 때 사용되는 API이다. 

POST API에서는 저장하고자하는 리소스나 값을 HTTP 바디에 담아 서버에 전달한ㄷ. URI이 GET API에 비해 간단하다.

@RequestMapping으로 구현하기

 POST API에서 @RequestMapping을 사용하는 방법은 GET API와 크게 다르지 않다. 요청에서 메서드를 정의할 때 밑 코드처럼 method 요소를 RequestMethod.POST로 설정하는 부분을 제외하면 GET API와 동일하다.

 

@RequestBody를 활용한 POST 메서드 구현

2번 줄을 보면 @RequestMapping 대신 @PostMapping을 사용했다.이 어노테이션을 사용하면 method 요소를 정의하지 않아도 된다. @RequestBody라는 어노테이션을 사용했는데,  @RequestBody는 HTTP의 Body 내용을 해당 어노테이션이 지정된 객체에 매핑하는 역할을 한다.

 

*JSON 

-> 자바스크립트의 객체 문법을 따르는 문자 기반의 데이터 포맷이다. 현재 자바스크립트 외에도 다수의 프로그래밍 환경에서 사용한다. 대체로 네트워크를 통해 데이터를 전달할 때 사용하며, 문자열 형태로 작성되기 때문에 파싱하기도 쉽다는 장점이 있다.

 

Map 객체는 요청을 통해 어떤 값이 들어오게 될지 특정하기 어려울 때 주로 사용한다. 요청 메시지에 들어갈 값이 정해져 있다면 밑과 같이 작성할 수 있다.

 

PUT API 만들기

 웹 애플리케이션 서버를 통해 데이터베이스 같은 저장소에 존재하는 리소스 값을 업데이트 하는 데 사용 한다.

구현하는 방법은 POST API와 거의 동일하다. 리소스를 서버로 전달하기 위해 HTTP Body를 활용해야 하기 때문이다.

 

@RequestBody를 활용한 PUT 메서드 구현

 PUT API는 POST 메서드와 마찬가지로 값을 HTTP Body에 담아 전달한다. 서버에서는 이 값을 받기 위해 밑과 같이  @RequestBody를 사용한다. 

서버에 어떤 값이 들어올지 모르는 경우에는 Map객체를 활용해 값을  받을 수 있다. 만약 서버에 들어오는 요청에 담겨 있는 값이 정해져 있는 경우에는 밑과 같이 DTO객체를 활용해 구현한다.

 첫 번째 메서드인  postMemberDto1은 리턴 값이 String 타입이고, 두 번째 메서드인 postMemberDto2는 DTO객체이다.

-> 이 부분은 공부를 좀 더 한 뒤 추가로 기재하겠음. 완벽히 이해하지 못함

 

ResponseEntity를 활용한 PUT 메서드 구현 

 스프링 프레임워크에는 HttpEntity라는 클래스가 있다. HttpEntity는 다음과 같이 헤더와 바디로 구성된 HTTP요청과 응답을 구성하는 역학을 수행한다.

 RequestEntity와 ResponseEntity는 상속받아 구현한 클래스이다. 그중 ResponseEntity는 서버에 들어온 요청에 대해 응답 데이터를 구성해서 전달할 수 있게 한다.

이 클래스를 활용하면 응답 코드 변경을 물론이고 헤더와 바디를 더욱 쉽게 구성할 수 있다. 이 클래스는 PUT 메서드를 구현하는 이번 절에서 소개하고 있지만 다른 메서드에서도 모두 사용할 수 있는 클래스이다.

 

DELETE API 만들기

 웹 애플리케이션 서버를 거쳐 데이터베이스 등의 저장소에 있는 리소스를 삭제할 때 사용한다. 서버에서는 클라이언트로부터 식벽할 수 있는 값을 받아 데이터베이스나 캐시에 있는 리소스를 조회하고 삭제하는 역할을 수행한다. 이때 컨트롤러를 통해 값을 받는 단계에서는 간단한 값을 받기 때문에 GET 메서드와 같이 URI에 넣어 요청을 받는 형식으로 구현 된다.

 

@PathVariable과 @RequestParam을 활용한 DELETE 메서드 구현

 @PathVariable을 이용하면 밑과 같이 URI에 포함된 값을 받아 로직을 처리할 수 있다.

 @DeleteMapping 어노테이션에 정의한 value 의 이름과 메서드의 매개변수 이름을 동일하게 설정해야 삭제할 값이 주입됩니다.

 

한걸음 더 REST API 명세를 문서화 하는 방법 - Swagger

 API를  개발하면 명세를 관리해야 한다. 명세란 해당 API가 어떤 로직을 수행하는지 설명하고 이 로직을 수행하기 위해 어떤 값을 요청하며, 이에 따른 응답값으로는 무엇을 받을 수 있는 지를 정리한 자료이다.

 API는 개발 과정에서 계속 변경되므로 작성한 명세 문서도 주기적인 업데이트가 필요하다. 또한  작업은 번거롭고 시간 또한 오래 걸린다. 이 것을 해결하기 위해 등장한 것이 바로 Swawgger이다.

@ApiOperation : 대상 API의 설명을 작성하기 위한 어노테이션

@ApiParam : 매개변수에 대한 설명 및 설정을 위한 어노테이션이다. 메서드의 매개변수뿐 아니라 DTO 객체를 매개변수로 사용할 경우 DTO 클래스 내으 매개변수에도 정의할 수 있다.

 

[한걸음 더 ] 로깅 라이브러리

실무에서는 System.out.println() 같은 정보를 출력하지 않고, 로깅 라이브러리를 사용해서 로그를 출력한다.

스프링 부트 라이브러리를 사용하면 스프링 부트 로깅 라이브러리(spring-boot-starter-logging) 가 함께 포함되며, 대부분 Logback 라이브러리를 사용한다.

 


로그 사용

직접 사용해보기 위해 LogTestController 라는 컨트롤러를 생성하고

org.slf4j.Logger 패키지를 import 하여 로그를 선언한다.

// 로그 선언
private final Logger log = LoggerFactory.getLogger(getClass());

로그를 다음과 같이 호출하기 위해 코드를 작성하고 결과를 본다.

@RequestMapping("/log-test")
public String logTest() {

    String name = "Spring";

    log.trace("trace log = {}",name);
    log.debug("debug log = {}",name);
    log.info("info log = {}",name);
    log.warn("warn log = {}",name);
    log.error("error log = {}",name);

    return "ok";
}

프로젝트를 실행하고 http://localhost:8080/log-test에 들어가면
아래 사진처럼 로그가 찍히는 것을 볼 수 있다.


로그 출력 형식

위에 로그 결과를 보면

시간, 로그 레벨, 프로세스 ID, 쓰레드 명, 클래스명, 로그 메시지

순의 형식으로 찍히는 것을 볼 수 있다.


로그 레벨

그러나 위에 코드에서 분명 로그를 5번 호출 했는데, 실제 결과는 3개만 찍힌 것을 볼 수 있다.

왜냐하면 바로 로그 레벨 때문이다.

로그 레벨
TRACE > DEBUG > INFO > WARN > ERROR
개발 서버는 debug 출력
운영 서버는 info 출력

그래서 로그 레벨을 설정하여, 해당 패키지의 trace 레벨까지 보고 싶으면 application.properties 에서 다음과 같이 설정한다.

logging.level.hello.springmvc=trace

그러면 trace 레벨까지 log 결과를 볼 수 있게 된다.

전체 로그 레벨을 설정할 때엔 다음과 같이 작성하며, 기본적으로 info 레벨로 설정되어 있다.

logging.level.root=info

로그 사용 장점

  • 쓰레드 정보, 클래스 이름 같은 부가 정보를 볼 수 있음
  • 출력 모양 조정 가능
  • 상황에 맞게 로그 레벨에 따라 로그를 출력하고, 출력하지 않을 수 있음
  • 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있음
  • 일반 System.out보다 성능이 좋음 (내부 버퍼링, 멀티 쓰레드 등등)

 

 


로깅 참고 블로그

https://velog.io/@easyhyun00/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-%EB%A1%9C%EA%B9%85-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC

 

[Spring] 스프링 부트 로깅 라이브러리

스프링 부트 로깅 라이브러리

velog.io

 

728x90