Recent Posts
Recent Comments
Link
11-21 14:38
Today
Total
관리 메뉴

삶 가운데 남긴 기록 AACII.TISTORY.COM

Spring boot todo - REST API Controller 본문

DEV&OPS/Java

Spring boot todo - REST API Controller

ALEPH.GEM 2022. 8. 31. 14:17

REST 제약 조건

  1. Client - Server 구조를 따릅니다.
  2. stateless 클라이언트가 서버에 요청을 보낼 때 이전 요청의 영향을 받지 않습니다. 그래서 요청을 보낼 때 로그인(인증) 정보를 항상 함께 보내야 합니다. http는 기본적으로 staeless 구조입니다.
  3. Cacheable 캐시가 가능한지 명시할 수 있어야 합니다. http는 헤더에 cache-control 에서 캐시 여부를 명시할 수 있습니다.
  4. Uniform Interface 리소스를 URI를 통한 인터페이스로 관리합니다.
  5. Layered System 인증서버, 캐싱 서버, 로드 밸런서 등 여러 레이어로 된 서버들을 거치지만 클라이언트는 서버 사이의 레이어의 존재 유무를 알지 못합니다.
  6. Code on demand 클라이언트는 서버에 코드를 요청할 수 있고 서버가 리턴한 코드를 실행할 수 있습니다.

 

URI 매핑 예제

requestBody용 DTO 객체
package ds.co.kr.todo.dto;

import lombok.Data;

@Data
public class requestBodyDTO {
	private int id;
	private String message;
}​
response 용 DTO 객체
package ds.co.kr.todo.dto;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class ResponseDTO<T> {
	private String error;
	private List<T> data;
}​

 

Controller 예제

package ds.co.kr.todo.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import ds.co.kr.todo.dto.RequestBodyDTO;
import ds.co.kr.todo.dto.ResponseDTO;

@RestController
@RequestMapping("test")
public class TestController {
	@GetMapping
	public String testController() {
		//이 URI는 /test 으로 접근합니다.
		return "Hello Test";
	}
	
	@GetMapping("/get")
	public String getController() {
		//이 URI는 /test/get 으로 접근합니다.
		return "Hello Get";
	}
	
	@GetMapping("/{id}")
	public String getControllerWithPathVariables(@PathVariable(required=false) int id) {
		//이 URI는 /test/숫자 으로만 접근합니다. 
		//required = false 는 필수 입력 사항이 아니라는 의미입니다.
		return "Hello " + id;
	}
	
	@GetMapping("/requestParam")
	public String getControllerWithRequestParam(@RequestParam(required=true) int id) {
		//이 URI는 /test/requestParam?id=숫자  으로만 접근합니다.
		//required = true 는 필수 입력 사항이므로 입력하지 않으면 에러가 발생합니다.
		return "Hello " + id;
	}
	
	@GetMapping("requestBody")
	public String getControllerWithRequestBody(@RequestBody RequestBodyDTO requestBodyDTO) {
		//이 URI는 /test/requestBody 으로 접근합니다.
		//request body로 넘겨주는 JSON 객체는 RequestBodyDTO와 구조가 동일해야 합니다. 즉, id 는 int , message는 String 
		//테스트시 해당 URI로 request body에 JSON 객체를 전달해야합니다. 예: {"id" : 123, "message" : "my friend." }
		return "Hello " + requestBodyDTO.getId() +". You are "+requestBodyDTO.getMessage();
	}
	
	@GetMapping("responseBody")
	public ResponseDTO<String> getControllerWithResponseBody(){
		//이 URI는 /test/responseBody 으로 접근합니다.
		//json object를 반환합니다. 예 {"error": null, "data": ["Greeting", "This is ResponseDTO" ] }
		List<String> list = new ArrayList<>();
		list.add("Greeting");
		list.add("This is ResponseDTO");
		ResponseDTO<String> response = ResponseDTO.<String>builder().data(list).build();
		return response;
	}
	
	@GetMapping("responseEntity")
	public ResponseEntity<?> getControllerWithResponseEntity(){
		//이 URI는 /test/responseEntity 으로 접근합니다.
		//ResponseDTO와 다른점은 HTTP status를 조작할 수 있는 점입니다.
		List<String> list = new ArrayList<>();
		list.add("400 response");
		ResponseDTO<String> response = ResponseDTO.<String>builder().data(list).build();
		//http status 를 400으로 설정
		return ResponseEntity.badRequest().body(response);
		//정상응답인경우 아래처럼 리턴합니다.
		//return ResponseEntity.ok(null).body(response);
	}
	
}

실행 테스트

http://localhost:8080/test/requestBody 으로 json 전달 테스트
http://localhost:8080/test/responseEntity&nbsp; 응답 테스트

 

 

 

 

 

 

 

 

 

 

 

 

728x90