Programming/Spring

[Spring] PUT API 사용하기

코끼리 개발자 2022. 12. 6. 17:25
728x90
SMALL

Put API는 CURD중 C(Create)/U(Update)의 역할을 수행하게 된다.

리소스가 없는 경우 생성하고, 있다면 업데이트 한다.

처음 한번은 생성되고, 그 다음은 계속해서 기존 것을 업데이트하기 때문에 데이터는 항상 하나이며 같은상태를 유지하기 때문에  멱등성을 지녔다.

하지만 잘못된 데이터가 전송되더라도 업데이트 시키기 때문에 안정성은 지니지 못한다.

 

[POST와 PUT의 차이]

Post는 매번 생성하고, Put은 없으면 생성하고 있으면 업데이트를 한다는 점에서 차이를 드러낸다.

이러한 역할의 차이 때문에 Post는 멱등성이 없고, Put은 멱등성을 가지고 있다.

 

 

Put 방식도 Json 방식으로 데이터를 주고 받게 되는데,

Json 방식에 대해 간결한 설명은 아래 포스팅에 있으니 참고하면 된다.

https://elephant-dev.tistory.com/30

 

[Spring] Post API 사용하기

Post API는 CURD 중 C(Create)의 역할을 수행하게 된다. 즉, 리소스의 생성 및 추가를 위해 사용하는 것이다. 또한 DataBody에 데이터를 담아서 보내고, 생성 된 데이터를 전달받기 때문에 QueryParameter를 사

elephant-dev.tistory.com

 

 

 

@PutMapping("/path")

: 이 Annotation은 @RequestMapping(path = " ", method = RequestMethod.PUT)과 동일한 기능을 한다.

데이터를 전달받기 위해 @RequestBody Annotation을 사용하고, 파라미터는 클래스를 통해 전달 받는 방식을 사용하였다.

Put 역시 @PathVariable Annotation을 사용할 수 있다.

Put은 데이터를 생성하고 업데이트하는 역할을 수행한다.

Put API를 만들 때 RequestBody는 클래스를 통해 파라미터로 받아 파싱하였다.

클래스를 생성하고 Json형태로 넣을 데이터는 클래스 내부에 선언하여 받도록 하였다.

@PutMapping Annotation 사용 시 변하는 userId값을 사용하기 위해 파라미터로 @PathVariable Annotation을 사용 해 주었고, 명시적으로 name을 지정해 주고 id를 받을 수 있도록 하였다.

<예시>

import com.example.erpsystem.dto.PostRequest;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/put")
public class PutApiController {
    @PutMapping("/put-request/{userId}")
    public PostRequest put(@RequestBody PostRequest request, @PathVariable(name = "userId") Long id){
        System.out.println(id);
        return request; // RestController에서 오브젝트를 return시 오브젝트 매퍼를 통해 Json형태로 변형시켜줌
    }
}

 

 

@JasonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)

:PostRequest class를 작성할 시 class위에 @JsonNaming Annotation을 사용 해 주었는데,

Json에서는 key값을 보통 snake case를 사용한다. (단어와 단어 사이를 _로 구분하는 방식)

하지만 아래 작성한 class에서는 네이밍을 camel case를 사용하여 작성했다. (단어와 단어를 대문자로 구분하는 방식)

이 두 방식을 호환하기 위해 클래스 위에 @JsonNaming Annotation을 사용해 주었는데, 클래스 위에 해당 Annotation을 사용하면,

내부의 변수들을 Json 형태로 파싱 시 snake case로 변경하여 파싱할 수 있다

클래스 내부의 모든 변수를 변형하기 위해서는 @JsonNaming Annotation을 사용하면 되며,

특정 변수만 변환하기 위해서는 변수 위에 @JsonProperty Annotation을 사용하면 된다. 

아래 CarDto 클래스에서는 @JsonProperty Annotation을 사용했으니 아래 코드를 참고하면 된다.

 

<PostRequest Class 코드>

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import java.util.List;

@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
public class PostRequest {
    private String name;
    private int age;

   private List<CarDto> carList;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<CarDto> getCarList() {
        return carList;
    }

    public void setCarList(List<CarDto> carList) {
        this.carList = carList;
    }

    @Override
    public String toString() {
        return "PostRequest{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", carList=" + carList +
                '}';
    }
}

 

<CarDto Class 코드>

import com.fasterxml.jackson.annotation.JsonProperty;


public class CarDto {
    private String name;
    @JsonProperty("car_number")
    private String carNumber;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCarNumber() {
        return carNumber;
    }

    public void setCarNumber(String carNumber) {
        this.carNumber = carNumber;
    }

    @Override
    public String toString() {
        return "CarDto{" +
                "name='" + name + '\'' +
                ", carNumber='" + carNumber + '\'' +
                '}';
    }
}

 

실습 시 테스트 하였던 데이터값은 다음과 같다.

이 때 데이터 형식을 틀리면 400번 에러가 발생하니 400번에러가 발생하였다면, 내가 지정 해 준 데이터 값이 정확한지 확인하여야한다.

{
  "name" : "elephant",
  "age" : 20,
  "car_list" : [
    {
      "name" : "BMW",
      "car_number" : "10허 1111"
    },
    {
      "name" : "hyundai",
      "car_number" : "12바 0000"
    }
  ]
}

 

 

테스트는 Chrome의 Talend API Test를 이용했다.

(System.out.println으로 출력한 데이터 값은 실행시킨 서버의 console창에서 확인할 수 있다)

728x90
LIST