의미 | CRUD | 멱등성 | 안정성 | Path Variable | Query Parameter | Data Body | |
---|---|---|---|---|---|---|---|
GET | 리소스 취득 | R | O | O | O | O | X |
POST | 리소스 생성, 추가 | C | X | X | O | △ | O |
PUT | 리소스 갱신, 생성 | C / U | O | X | O | △ | O |
DELETE | 리소스 삭제 | D | O | X | O | O | X |
HEAD | 헤더 데이터 취득 | - | O | O | - | - | - |
OPTIONS | 지원하는 메소드 취득 | - | O | - | - | - | - |
TRACE | 요청메시지 반환 | - | O | - | - | - | - |
CONNECT | 프록시 동작의 터널 접속으로 변경 | - | X | - | - | - | - |
- 주소 내에 정보를 전달 하는 방법.
- GET 메소드에서 특정한 리소스의 정보를 가져올때 사용한다.
- REST API에서 URI에 변수가 들어가는걸 실무에서 많이 볼 수 있다.
예를 들면, 아래 URI에서 숫자 부분이 @PathVariable로 처리해줄 수 있는 부분이다.
https://www.foo.bar/user-id/100
https://www.foo.bar/user-id/100/card-id/200
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;
}
}
// 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();
}
- 특정 정보의 필터링을 걸때 사용한다.
? 로 시작하고, 이어주는 형태는 &로 묶어준다.
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은 리소스를 식별하기 위해 사용하고,
데이터를 정렬, 필터링 등을 사용한다면 Query Parameter 가 더 적합하다.
정렬, 필터링을 하려다 404 에러가 나는 경우는 부적절하기 때문에 Query Parameter 가 적합하다고 할 수 있다.
HTTP 헤더는 HTTP 전송에 필요한 모든 부가정보를 담고 있다.
메시지 바디의 내용, 크기, 압축, 인증, 요청 클라이언트, 서버 정보 등등... 매우 많은 정보들이 들어있다.
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" : "유관순"
}
]
}
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);
}
}
결과
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);
}
}