‘Spring Initializr’를 통해 생성한 프로젝트에는 엔트리포인트 클래스가 이미 작성되어 있다.
@SpringBootApplication // (1)
public class Application {
public static void main(String[] args) {
// (2)
SpringApplication.run(Section3Week1Application.class, args);
}
}
(1) @SpringBootApplication
@SpringBootApplication
은 코드 상에서는 보이지 않지만 내부적으로 세가지 일을 해준다.
@Component
가 붙은 클래스를 검색한 후 (scan), Spring Bean으로 등록하는 기능을 활성화@Configuration
이 붙은 클래스를 자동으로 찾아주고, 추가적으로 Spring Bean을 등록하는 기능을 활성화(2) SpringApplication.run(Application.class, args);
Spring 애플리케이션을 부트스트랩하고, 실행하는 역할
부트스트랩(Bootstrap)
애플리케이션이 실행되기 전에 여러가지 설정 작업을 수행하여 실행 가능한 애플리케이션으로 만드는 단계를 의미
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // (1)
@RequestMapping("/v1/members") // (2)
public class MemberController {
}
(1) @RestController
@RestController
를 추가하면 해당 클래스가 REST API의 리소스(자원,Resource)를 처리하기 위한 API 엔드포인트로 동작함을 정의(2) @RequestMapping
@RequestMapping
은 클라이언트의 요청과 클라이언트 요청을 처리하는 핸들러 메서드(Handler Method)를 매핑 해주는 역할을 한다.@RequestMapping
은 Controller 클래스에 추가하여 클래스 전체에 사용되는 공통 URL(Base URL) 설정을 한다.
@PostMapping
은 클라이언트의 요청 데이터(request body)를 서버에 생성할 때 사용하는 애너테이션
@RequestParam
은 핸들러 메서드의 파라미터 종류 중 하나입니다.
주로 클라이언트 쪽에서 전송하는 요청 데이터를 쿼리 파라미터(Query Parmeter 또는 Query String), 폼 데이터(form-data), x-www-form-urlencoded 형식으로 전송하면 이를 서버 쪽에서 전달 받을 때 사용하는 애너테이션
@GetMapping("/{member-id}")
public String getMember(@PathVariable("member-id")long memberId) {
System.out.println("# memberId: " + memberId);
// not implementation
return null;
}
@GetMapping
은 클라이언트가 서버에 리소스를 조회할 때 사용하는 애너테이션
클라이언트 쪽에서 getMember() 핸들러 메서드에 요청을 보낼 경우, 최종 URI는 형태
”/v1/members/{member-id}”
@RequestMapping
에 설정된 URI와@GetMapping
에 설정한 URI가 합쳐진 형태
@PathVariable
의 괄호 안에 입력한 문자열 값은 @GetMapping("/{member-id}")
처럼 중괄호({ }) 안의 문자열과 동일해야 한다. 여기서는 두 문자열 모두 “member-id” 로 동일하게 지정
만약 두 문자열이 다르다면 MissingPathVariableException이 발생
@PostMapping
public ResponseEntity postMember(@RequestParam("email") String email,
@RequestParam("name") String name,
@RequestParam("phone") String phone) {
// (2) JSON 문자열 수작업을 Map 객체로 대체
Map<String, String> map = new HashMap<>();
map.put("email", email);
map.put("name", name);
map.put("phone", phone);
// (3) 리턴 값을 ResponseEntity 객체로 변경
return new ResponseEntity<>(map, HttpStatus.CREATED);
}
new ResponseEntity<>(map, HttpStatus.CREATED); 처럼 ResponseEntity 객체를 생성하면서 생성자 파라미터로 응답 데이터(map)와 HTTP 응답 상태를 함께 전달하고 있다.
리턴 값으로 단순히 Map
객체를 리턴해도 클라이언트 쪽에서는 정상적으로 JSON 형식의 응답 데이터를 받을 수 있습니다.
그런데 ResponseEntity
객체로 응답 데이터를 래핑함으로써 조금 더 세련된 방식으로 응답 데이터를 생성할 수 있다.
이처럼 HTTP 응답 상태를 명시적으로 함께 전달하면 클라이언트의 요청을 서버가 어떻게 처리했는지를 쉽게 알 수 있다.
클라이언트 쪽에서는 이 HTTP 응답 상태를 기반으로 정상적으로 다음 처리를 할지 에러 처리를 할지 결정하면 되는 것
ResponseEntity
를 적용하지 않았을 때의 응답 결과와 달라진 점은 응답 상태가 ‘200 OK’에서 ‘201 Created’로 바뀌었다는 것
ResponseEntity
에 HttpStatus.OK
를 지정할 수 도 있지만 HttpStatus.CREATED
를 지정함으로써 서버에서의 처리 결과를 조금 더 명확하게 알려주고 있습니다.