[스프링] 5. API를 작성하는 다양한 방법(PUT)

PYOUNANI·2023년 10월 30일
0

Spring

목록 보기
7/31
post-thumbnail
📢 장정우님이 지음, 
[스프링부트 핵심가이드 : 스프링 부트를 활용한 애플리케이션 개발 실무] 책을 읽고 정리한 글입니다.

PUT API 만들기

PUT API는 웹 애플리케이션 서버를 통해 데이터베이스 같은 저장소에 존재하는 리소스 값을 업데이트하는 데 사용한다. POST API와 비교하면 요청을 받아 실제 데이터베이스에 반영하는 과정(서비스 로직)에서 차이가 있지만 컨트롤러 클래스를 구현하는 방법은 POST API와 거의 동일하다. 리소스를 서버에 전달하기 위해 HTTP Body를 활용해야 하기 때문이다. 먼저 아래와 같이 PutController 라는 컨트롤러 클래스를 작성한다.

package com.example.corner.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("api/v1/put-api")
public class PutController {
}

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

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

// http://localhost:8080/api/v1/put-api/member
    @PutMapping(value = "/member")
    public String putMember(@RequestBody Map<String, Object> putData){
        StringBuilder sb = new StringBuilder();

        putData.entrySet().forEach(map -> {
            sb.append(map.getKey() + " : " + map.getValue() + "\n");
        });

        return sb.toString();
    }

서버에 어떤 값이 들어올지 모르는 경우에는 Map 객체를 활용해 값을 받을 수 있다. 대부분의 경우 API를 개발한 쪽에서 작성한 명세(specification)를 웹 사이트를 통해 클라이언트나 사용자에게 올바른 사용법을 안내한다. 만약 서버에 들어오는 요청에 담겨 있는 값이 정해져 있는 경우에는 아래와 같이 DTO 객체를 활용해 구현한다.

// http://localhost:8080/api/v1/put-api/member1
    @PutMapping(value = "member1")
    public String putMemberDto1(@RequestBody MemberDto memberDto){
        return memberDto.toString();
    }
    
    // http://localhost:8080/api/v1/put-api/member2
    @PutMapping(value = "member2")
    public MemberDto putMemberDto2(@RequestBody MemberDto memberDto){
        return memberDto;
    }

위의 예쩨는 2개의 메서드로 구성돼 있다. 첫 번째 메서드인 putMemberDto1은 리턴 값이 String 타입이고, 두 번째 메서드인 putMemberDto2는 DTO객체 타입이다.

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

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

// HttpEntity 클래스 일부 발췌
public class HttpEntity<T> {
    public static final HttpEntity<?> EMPTY = new HttpEntity();
    private final HttpHeaders headers;
    @Nullable
    private final T body;
    
    ...
}

RequestEntity와 ResponseEntity는 HttpEntity를 상속 받아 구현한 클래스이다. 그중 ResponseEntity는 서버에 들어온 요청에 대해 응답 데이터를 구성해서 전달할 수 있게 한다. 다음과 같이 ResponseEntity는 HttpEntity로부터 HttpHeader와 Body를 가지고 자체적으로 HttpStatus를 구현한다.

public class ResponseEntity<T> extends HttpEntity<T> {
    private final Object status;

    ..생략..
}

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

다음은 기존 예제 메서드의 리턴 타입에 ResponseEntity를 적용한 예이다.

// http://localhost:8080/api/v1/put-api/member3
    @PutMapping(value = "member3")
    public ResponseEntity<MemberDto> postMemberDto3(@RequestBody MemberDto memberDto){
        return ResponseEntity
                .status(HttpStatus.ACCEPTED)
                .body(memberDto);
    }

0개의 댓글