노트

DRF 파서·렌더러와 콘텐츠 협상

DRF Parsers, Renderers, and Content Negotiation

백엔드#django#http · 연결된 개념 5개

쉽게 말하면

DRF 파서와 렌더러는 서버 입구와 출구에 선 통역사예요. 들어온 JSON이나 폼을 파이썬 데이터로 옮기고, 나갈 땐 상대가 원하는 형식으로 옮겨 줘서 안쪽 코드는 형식을 신경 쓰지 않아도 되죠.

비유가 깨지는 곳 통역 언어는 감으로 고르지 않아요. 요청의 Accept 헤더로 렌더러를, Content-Type으로 파서를 골라요. 같은 URL이 형식별로 다른 응답을 주면 Vary: Accept로 캐시가 섞이지 않게 해요.

DRF에서 파서(Parser)는 요청 본문을 파이썬 자료형으로 바꾸고, 렌더러(Renderer)는 응답 데이터를 클라이언트가 받을 형식으로 바꾼다. 어떤 렌더러를 쓸지는 요청의 Accept 헤더를 보고 고르는데, 이를 콘텐츠 협상(content negotiation)이라 한다.

요청 본문(JSON·폼·멀티파트) ──Parser──▶ request.data
serializer.data ──Renderer──▶ 응답 본문(JSON·HTML·…)

기본값

REST_FRAMEWORK = {
    "DEFAULT_PARSER_CLASSES": [
        "rest_framework.parsers.JSONParser",
        "rest_framework.parsers.FormParser",
        "rest_framework.parsers.MultiPartParser",
    ],
    "DEFAULT_RENDERER_CLASSES": [
        "rest_framework.renderers.JSONRenderer",
        "rest_framework.renderers.BrowsableAPIRenderer",
    ],
}
  • 설정하지 않으면 위와 같은 값이 쓰인다. 파서는 요청의 Content-Type으로 고른다
  • BrowsableAPIRenderer는 브라우저로 API를 열면 HTML 탐색 화면을 보여준다. 운영에서 JSON만 내보내려면 렌더러를 JSONRenderer만 남긴다
  • 뷰마다 parser_classes, renderer_classes로 바꿀 수 있다. 파일 업로드 뷰는 MultiPartParser, 코드 하이라이트를 HTML로 주는 뷰는 StaticHTMLRenderer처럼
  • URL 끝에 .json 같은 포맷 접미사(format suffix)를 붙여 형식을 고르게 할 수도 있다(format_suffix_patterns)

시리얼라이저와의 경계

시리얼라이저는 "모델 ↔ 파이썬 dict"까지만 책임지고, "dict ↔ 바이트(JSON 문자열)"는 파서·렌더러가 맡는다(DRF 시리얼라이저). 그래서 같은 시리얼라이저로 JSON과 다른 형식을 모두 낼 수 있다. 관심사를 단계별로 나눈 구조라 단계 쪼개기와 닮았다.

HTTP 관점

콘텐츠 협상은 DRF만의 개념이 아니라 HTTP 표준(Accept, Content-Type)이다. 같은 URL이 형식에 따라 다른 응답을 주면 캐시가 섞이지 않게 Vary: Accept 헤더가 필요하다(브라우저 캐시). 스프링에서는 메시지 컨버터가 같은 일을 한다(Spring MVC 요청 흐름).

출처: DRF Parsers: How the parser is determined · DRF Renderers: Setting the renderers · BrowsableAPIRenderer · DRF Content negotiation

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • DRF 인증과 권한

    DRF는 요청 처리를 두 단계로 나눈다. 인증 클래스(authentication class)는 요청을 보낸 사용자가 누구인지 식별해 request.user·request.auth를 채우기만 하고, 권한 클래스(permission class)가 그 사용자에게 이 요청을 허용할지 결정한다. 인증만으로는 요청이 막히지 않는다(authn-authz).

  • DRF 필터·검색·정렬

    DRF의 목록 API는 쿼리 파라미터로 결과를 좁히는 세 가지 장치를 붙일 수 있다. 값이 정확히 맞는 것만 고르는 필터, 일부 문자열로 찾는 검색, 순서를 바꾸는 정렬이다. 모두 제네릭 뷰(GenericAPIView 계열)의 filter_backends로 적용된다.

  • 스프링 REST 컨트롤러

    @RestController는 메서드의 반환값을 뷰 이름이 아니라 HTTP 응답 본문(보통 JSON)으로 쓰는 컨트롤러다. @Controller에 @ResponseBody를 합친 것으로, 직렬화(serialization)는 Jackson이 맡는다.

  • 요청 제한 (Throttling)

    요청 제한(rate limiting, throttling)은 일정 시간 동안 한 클라이언트가 보낼 수 있는 요청 수를 묶어 두는 장치다. 한도를 넘으면 429 Too Many Requests로 거절하고, 보통 Retry-After 헤더로 언제 다시 시도하면 되는지 알려 준다.

  • CSRF

    CSRF(Cross-Site Request Forgery, 사이트 간 요청 위조)는 로그인한 사용자가 악성 사이트를 방문했을 때, 그 사이트가 사용자의 브라우저를 시켜 사용자 모르게 원래 사이트에 요청을 보내게 하는 공격이다. 공격자는 토큰을 훔치지 않는다. 브라우저가 쿠키를 알아서 붙여 준다는 점을 이용한다.

보기 옵션