@RestController는 메서드의 반환값을 뷰 이름이 아니라 HTTP 응답 본문(보통 JSON)으로 쓰는 컨트롤러다. @Controller에 @ResponseBody를 합친 것으로, 직렬화(serialization)는 Jackson이 맡는다.
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@GetMapping("/{id}")
public OrderDto get(@PathVariable Long id) { return service.find(id); }
@PostMapping
public ResponseEntity<OrderDto> create(@Valid @RequestBody CreateOrder req) {
OrderDto created = service.create(req);
return ResponseEntity.created(URI.create("/api/orders/" + created.id())).body(created);
}
}@RequestBody: 요청 본문 JSON을 객체로 역직렬화(deserialization)한다.@RequestHeader로 헤더 하나를 받는다ResponseEntity<T>: 상태 코드·헤더·본문을 직접 정한다. 생성은 201과Location, 삭제는 204처럼 의미에 맞게- 반환 타입이 객체면 200과 그 JSON이 기본이다
- 예외는 스프링 전역 예외 처리에서, 입력 검증은 Bean Validation에서 다룬다
Jackson 어노테이션
public record UserDto(
@JsonProperty("user_id") Long id, // JSON 필드 이름 바꾸기
String name,
@JsonIgnore String passwordHash // 응답에서 빼기
) {}- 여러 필드를 빼려면 클래스에
@JsonIgnoreProperties({"a", "b"}) - 엔티티를 그대로 반환하면 민감 필드 노출, 양방향 연관관계(bidirectional association) 무한 순환, 지연 로딩 예외가 생기기 쉽다. 응답 전용 DTO(Data Transfer Object)를 둔다
Spring Data REST
리포지터리 인터페이스를 REST 엔드포인트로 자동 노출하는 모듈이다. HAL(Hypertext Application Language) 형식으로 링크를 담아 응답하고, @RepositoryRestResource(path = "courses")로 경로를, exported = false로 노출 여부를 정한다. 빠른 프로토타입엔 편하지만 도메인 로직과 응답 형태를 통제하기 어렵다.
다른 출처의 프런트에서 부르려면 CORS 설정이 필요하고, 외부 API를 부르는 쪽은 스프링에서 외부 API 호출, 요청이 이 메서드까지 오는 과정은 Spring MVC 요청 흐름를 본다. 상태 코드와 메서드의 의미는 멱등성와 함께 맞춘다.