HTTP에서 동일한 URI에서 리소스의 서로 다른 버전을 제공하기 위해 사용됨
클라이언트가 리소스를 내려받길 원하는 경우 URL을 사용하여 요청함
서버는 URL을 이용하여 리소스의 여러 변형(프레젠테이션)들중 하나를 선택
즉 이 리소스가 호출됐을 때 프레젠테이션을 선택하는 방법
HTTP 헤더를 이용(서버 주도 협상)
HTTP 응답 코드를 이용(에이전트 주도 협상, 리액티브 협상, 풀백 메커니즘으로써 사용)
브라우저는 URL을 이용하여 몇개의 HTTP헤더 전송
서버는 그것을 힌트로써 컨텐츠 선택
때때로 요청된 리소스의 특정 프레젠테이션을 전송하는데 사용되기도 함
이러한 알고리즘은 서버 특유의 것임
HTTP/1.1 표준 Accept, Accept-Charset, Accept-Encoding, Accept-Language
사용자 에이전트가 실행 중인 기기의 종류를 알려줌
에이전트가 처리하고자 하는 미디어 리소스의 MIME타입을 나열
쉽표로 구분, 풉질 인자 포함, 상대적 선호도를 나타냄
Accept-CH 헤더
적합한 응답을 선택하기 위해 서버가 사용할 수 있는 설정 데이터를 나열
Accept-Charset 헤더
사용자 에이전트가 어떤 종류의 캐릭터(문자) 인코딩을 이해 할 수 있는지 알려줌
Accept-Encoding 헤더
수용 가능한 인코딩(압축 지원)을 정의
값 - q인자 목록(우선순위를 가리킴)
Accept-Language 헤더
사용자가 선호하는 언어를 가리킴
User-Agent 헤더
요청을 전송하는 브라우저를 식별
이 협상에서 애매모호한 요청과 마주할 경우, 서버는 사용 가능한 대체 리소스들에 대한 링크를 포함하는 페이지 회신
HTTP는 이러한 페이지의 형식을 명시하지 않음
자바스크립트 리다이렉션과 거의 항상 같이 사용됨
하나의 리소스를 가져오는데 하나 이상의 요청이 필요함
부분적으로 client-driven, child-driven
REST_FRAMEWORK = {
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'myapp.negotiation.CustomNegotiatoin',
}
from myapp.negotiation import CustomNegotiation
from rest_framework.views import APIVew
from rest_framewor.response import Response
class sampleView(APIView):
content_negotiation_class = CustomNegotiation
def get(self, request, format=None):
return Response({
'accepted media type': request.accepted_renderer.media_type
})
from rest_framework.negotiation import BaseContentNegotiation
class CustomNegotiatoin(BaseContentNegotiation):
def select_parser(self, request, parsers):
"""
파서 인스턴스중 하나를 사용가능한 파서 목록에서 반환
혹은 파서가 들어오는 요청을 처리 할 수 없는 경우 None 반환
"""
return parsers[0]
def select_renderer(self, request, renderers, format_suffix):
"""
(renderer instance, media type)의 tuple반환 혹은 NotAcceptable 예외
"""
return (renderers[0], renderers[0].media_type)