본문 바로가기
Spring Framework

콘텐츠 협상(Content Negotiation)

by xogns93 2024. 10. 15.

콘텐츠 협상(Content Negotiation)은 클라이언트와 서버 간의 통신에서 클라이언트가 수용할 수 있는 콘텐츠 형식을 결정하는 메커니즘입니다. HTTP 프로토콜에서 이 과정은 주로 HTTP 헤더를 통해 이루어지며, 서버는 클라이언트가 요청한 형식에 맞춰 응답을 보내게 됩니다.

콘텐츠 협상의 기본 개념:

  1. 클라이언트 요청: 클라이언트(브라우저 또는 API 소비자)는 서버에 요청할 때, 원하는 콘텐츠 형식을 명시할 수 있습니다. 이를 위해 HTTP 요청에 Accept 헤더를 포함시킵니다.
  2. 서버 응답: 서버는 Accept 헤더를 확인하고, 클라이언트가 요청한 형식에 맞춰 응답을 생성합니다. 만약 클라이언트가 요청한 형식이 지원되지 않으면, 서버는 기본 형식으로 응답하거나 406 Not Acceptable 상태 코드를 반환할 수 있습니다.

콘텐츠 협상 방식:

클라이언트가 수용할 수 있는 콘텐츠 형식을 서버에 전달하는 방법에는 주로 3가지가 있습니다.

1. Accept 헤더 사용 (주로 사용)

클라이언트는 HTTP 요청 시 Accept 헤더에 자신이 수용할 수 있는 콘텐츠 유형을 명시할 수 있습니다. 서버는 클라이언트가 선호하는 형식에 맞게 응답을 반환합니다.

  • Accept 헤더의 예:
    GET /resource HTTP/1.1
    Host: example.com
    Accept: application/json, application/xml;q=0.9, text/html;q=0.8
    여기서 application/json은 클라이언트가 가장 선호하는 형식이며, application/xml은 그 다음, text/html은 덜 선호된다는 의미입니다.

2. URL 패턴을 통한 콘텐츠 협상

URL의 확장자를 사용하여 클라이언트가 어떤 형식을 원하는지 나타내는 방식입니다. 예를 들어, 클라이언트가 JSON 데이터를 원하면 /resource.json과 같은 URL을 요청할 수 있습니다.

  • 예시:
    • /resource.json: JSON 형식으로 응답.
    • /resource.xml: XML 형식으로 응답.

3. 쿼리 파라미터를 통한 협상

특정 쿼리 파라미터를 사용하여 응답 형식을 요청하는 방식입니다. 예를 들어, format=json과 같은 쿼리 파라미터로 클라이언트가 원하는 형식을 지정할 수 있습니다.

  • 예시:
    • /resource?format=json: JSON 형식으로 응답.
    • /resource?format=xml: XML 형식으로 응답.

콘텐츠 협상의 동작 흐름:

  1. 클라이언트 요청: 클라이언트가 서버에 특정 자원에 대한 요청을 보냅니다. 이때 Accept 헤더에 요청할 수 있는 콘텐츠 형식(예: JSON, XML, HTML)을 명시할 수 있습니다.

  2. 서버 처리: 서버는 클라이언트의 요청을 받아, Accept 헤더의 정보를 확인합니다. 클라이언트가 요청한 형식 중 하나를 선택하거나 기본 형식을 사용합니다.

  3. 서버 응답: 서버는 요청한 자원에 대해 클라이언트가 요청한 형식으로 응답합니다. 형식을 찾을 수 없을 경우 406 Not Acceptable 상태 코드를 반환할 수 있습니다.

Spring에서의 콘텐츠 협상:

Spring에서는 콘텐츠 협상(Content Negotiation)을 매우 쉽게 처리할 수 있도록 지원합니다. 예를 들어, Spring MVC는 클라이언트가 JSON을 요청하면 JSON 형식으로, XML을 요청하면 XML 형식으로 응답할 수 있습니다.

1. Accept 헤더를 이용한 콘텐츠 협상

@GetMapping("/users")
public ResponseEntity<List<User>> getUsers() {
    List<User> users = userService.findAll();
    return ResponseEntity.ok(users);
}

클라이언트가 요청 시 Accept: application/json 헤더를 보내면, Spring은 자동으로 JSON 형식으로 응답을 생성합니다. Accept: application/xml로 요청하면 XML 형식으로 응답을 생성합니다.

2. URL 확장을 이용한 협상

Spring에서는 URL 확장을 통해서도 콘텐츠 형식을 결정할 수 있습니다.

  • /users.json: JSON 형식으로 응답.
  • /users.xml: XML 형식으로 응답.

이 방식은 ContentNegotiationManager를 설정하여 처리할 수 있습니다.

3. 쿼리 파라미터를 통한 협상

쿼리 파라미터를 사용하여 응답 형식을 지정할 수 있습니다.

  • /users?format=json: JSON 형식으로 응답.
  • /users?format=xml: XML 형식으로 응답.

이 방식 역시 ContentNegotiationManager에서 설정할 수 있습니다.

콘텐츠 협상의 장점:

  • 유연성: 클라이언트는 다양한 형식의 응답을 요청할 수 있고, 서버는 이 요청에 맞춰 적절한 형식으로 응답할 수 있습니다.
  • 확장성: 같은 리소스에 대해 여러 형식으로 응답을 제공함으로써 다양한 클라이언트(브라우저, 모바일 앱 등)를 지원할 수 있습니다.
  • REST API와의 통합: REST API에서 매우 유용하게 사용되며, 클라이언트가 JSON, XML 등 필요한 형식으로 데이터를 받을 수 있습니다.

요약:

  • 콘텐츠 협상은 클라이언트가 서버에 자신이 수용할 수 있는 콘텐츠 형식을 전달하고, 서버는 이 요청에 맞는 형식으로 응답하는 메커니즘입니다.
  • 주로 Accept 헤더를 통해 이루어지며, 서버는 클라이언트가 요청한 형식에 맞춰 응답을 생성합니다.
  • Spring에서는 Accept 헤더를 통한 협상 외에도 URL 확장자 또는 쿼리 파라미터를 이용한 협상도 지원합니다.