REST API

둥냥둥냥둥·2023년 7월 2일
0
post-thumbnail

REST API

의미CRUD멱등성안정성Path VariableQuery ParameterData Body
GET리소스 취득ROOOOX
POST리소스 생성, 추가CXXOO
PUT리소스 갱신, 생성C / UOXOO
DELETE리소스 삭제DOXOOX
HEAD헤더 데이터 취득-OO---
OPTIONS지원하는 메소드 취득-O----
TRACE요청메시지 반환-O----
CONNECT프록시 동작의 터널 접속으로 변경-X----

GET

  • GET는 CRUD 중에 R에 해당한다.
  • 멱등성에 해당한다.
  • 안전성이 있다.
  • 데이터 전달 방식으로 적절한 것은
    • Path Variable, Query Parameter

Path Variable

  • 주소 내에 정보를 전달 하는 방법.
  • GET 메소드에서 특정한 리소스의 정보를 가져올때 사용한다.
  • REST API에서 URI에 변수가 들어가는걸 실무에서 많이 볼 수 있다.

    예를 들면, 아래 URI에서 숫자 부분이 @PathVariable로 처리해줄 수 있는 부분이다.
https://www.foo.bar/user-id/100
https://www.foo.bar/user-id/100/card-id/200

특징

  • 이름처럼 경로를 변수로서 사용한다.
  • 원하는 기능에 맞게 HTTP메소드를 변경한다.
  • REST API에서 값을 호출 할 때 주로 사용한다.

사용법

Controller에서 아래와 같이 작성하면 간단하게 사용 가능하다.

1. @GetMapping {변수명}
(PostMapping, PutMapping 등 다 상관없음)

2. 메소드 정의에서 위에 쓴 변수명을 그대로 @PathVariable("변수명")

3.Parameter명
(아래에서 String name도 OK, String employName도 OK)

@RestController
public class MemberController { 
    
    // 기본
    @GetMapping("/member/{name}")
    public String findByName(
    		@PathVariable("name") String name 
    ){
        return "Name: " + name;
    }
    
    
    // 여러 개
    @GetMapping("/member/{id}/{name}")
	public String findByNameAndId(
    		@PathVariable("id") String id, 
    		@PathVariable("name") String name
    ){
    	return "ID: " + id + ", name: " + name;
    }   
}

기본적인 Path Variable 확인 코드

// http://localhost:8080/api/echo/hello

   @GetMapping(path = "/echo/{message}/age/{age}/is-man/{isMan}")
   public String echo(
           @PathVariable(name = "message") String msg,
           @PathVariable int age,
           @PathVariable boolean isMan
   ){
       System.out.println("echo message : "+msg);
       System.out.println("echo age : "+age);
       System.out.println("echo isMan : "+isMan);
       
       // TODO 대문자로 변환해서 RETURN => toUpperCase
       // boolean, integer

       return msg.toUpperCase();
   }

Query Parameter

  • 특정 정보의 필터링을 걸때 사용한다.
? 로 시작하고, 이어주는 형태는 &로 묶어준다.

https://www.foo.bar/book ? category=IT & issuedYear=2023 & issued-month=01 & issued_day=31
 
-, book종류중에 IT인 category 중에
- issuedYear 발행 년도가 2023 이고
- issued-month 발행 월이 01월 이고
- issued_day 발행 날자가 31일 정보를 받는다.

issuedYear   ->   camel case
issued-month ->   Hyphen
issued_day   ->   snake case

> 1번 http://localhost:8080/api/book?category=IT&issuedYear=2023&issued-month=01&issued_day=31
   
   @GetMapping(path = "/book")
   public void queryParam(
       @RequestParam String category,
       @RequestParam String issuedYear,
       @RequestParam(name = "issued-month") String issuedMonth,
       @RequestParam(name = "issued_day") String issuedDay
   ){
       System.out.println(category);
       System.out.println(issuedYear);
       System.out.println(issuedMonth);
       System.out.println(issuedDay);
   }
  • 결과

> 2번 model

@Data
@NoArgsConstructor
@AllArgsConstructor
public class BookQueryParam {

    private String category;
    private String issuedYear;
    private String issuedMonth;
    private String issueDay;
}


> 2번 http://localhost:8080/api/book2?category=IT&issuedYear=2023&issuedMonth=01&issuedDay=31
    
    @GetMapping(path = "/book2")
    public void queryParamDto(
            BookQueryParam bookQueryParam
    ){
        System.out.println(bookQueryParam);
    }
  • 결과

Path Variable VS Query Parameter

Path Variable은 리소스를 식별하기 위해 사용하고,
데이터를 정렬, 필터링 등을 사용한다면 Query Parameter 가 더 적합하다.

  • 예시로, Path Variable 인 경우 해당 경로의 리소스가 없는 경우 404 에러가 발생한다.
  • 하지만 Query Parameter 인 경우에는 빈 리스트를 반환할 것이다.

정렬, 필터링을 하려다 404 에러가 나는 경우는 부적절하기 때문에 Query Parameter 가 적합하다고 할 수 있다.


POST

  • POST는 CRUD 중에 C에 해당한다.
  • 멱등성에 해당하지 않는다.
  • 계속해서 데이터를 변화 시켜서 안정성이 없다.
  • post에서의 데이터 적절한 전달방식은
    • Path Variable, Data Body

Data Body

HTTP Body

HTTP Header

HTTP 헤더는 HTTP 전송에 필요한 모든 부가정보를 담고 있다.
메시지 바디의 내용, 크기, 압축, 인증, 요청 클라이언트, 서버 정보 등등... 매우 많은 정보들이 들어있다.

HTTP Body

TEXT, HTML, JSON 등.. 같은 것들이 들어있다.

실습

model => BookRequest

@Data
@AllArgsConstructor
@NoArgsConstructor
public class BookRequest {

    private String name;
    private String number;
    private String category;
}

Controller => PostApiController

@RestController
@RequestMapping("/api")
public class PostApiController {

    // http://localhost:8080/api/post
    @PostMapping("/post")
    public String post(
        @RequestBody BookRequest bookRequest
    ){
        System.out.println(bookRequest);
        return bookRequest.toString();
    }
  }

실습 문제

RequestBody로 사용자 이름, 전화번호, 이메일을 받는 POST Method 를 만들기

model => UserRequest

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserRequest {

    private String userName;
    private Integer userAge;
    private String email;

}
Controller => PostApiController

@RestController
@RequestMapping("/api")
public class PostApiController {

@PostMapping("/user")
    public UserRequest User(
        @RequestBody
        UserRequest userRequest
    ){
        System.out.println(userRequest);

        return userRequest;
    }
}
json

{
  "key" : "value",
  "array" : [10, 20, 30],
  "string_array" : ["홍길동","이순신","유관순"],
  "object_array" : [
    {
      "name" : "홍길동"
    },
    {
      "name" : "이순신"
    },
    {
      "name" : "유관순"
    }
  ]
}


PUT

  • 데이터가 있으면 갱신
  • 데이터가 없으면 생성
  • PUT은 CRUD중 C / D에 해당한다.
  • 멱등하며, 몇번이나 데이터를 생성하거나 갱신한다.
  • 데이터 요청시 데이터가 변함으로 안정성은 없다.
  • 데이터 전달 방식으로 적절한 것은
    • Path Variable, Data Body
model => UserRequest

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserRequest {

    private String userName;
    private Integer userAge;
    private String email;
    private Boolean isKorean; // is_korean

}
Controller => PutApiController

@Slf4j
@RestController
@RequestMapping("/api")
public class PutApiController {

    @PutMapping("/put")
    public void put(
        @RequestBody
        UserRequest userRequest
    ){
        System.out.println("");
        log.info("Request : {}", userRequest);
    }
}

결과


DELETE

  • 리소스의 작제를 할때 사용.
  • CRUD에서 D에 해당한다.
  • 같은 결과를 가져오므로 멱등한다.
  • 안정성은 없다.
  • 데이터 전달 방식으로 적절한 것은
    • Path Variable, Query Parameter
Controller => RestApiController => delete

@Slf4j
@RestController
@RequestMapping("/api")
public class RestApiController {
@DeleteMapping(path = {
            "/user/{userName}/delete",
            "/user/{userName}/del"
        }
    )
    public void delete(
        @PathVariable String userName
    ){
        log.info("user-name : {}", userName);
    }
}
profile
Java 먹자

0개의 댓글