Tonic 's lesson learned


DRF(Django Rest Framework) view vs generic view vs viewset 도대체 뭘 쓰면 좋을까요

목적

Django Rest Framework(이하 ‘DRF’)를 쓰다보면 데코레이터를 통한 함수 기반 구현부터 APIView, generic View, Viewset 등을 이용한 클래스 기반 구현까지 다양한 선택지가 있습니다. 뭘 쓰더라도 구현은 가능합니다만 어떤 경우에 뭘 쓰는게 좋을까요? 그리고 이들은 무슨 차이가 있을까요?


왜 DRF를 쓰나. Django로는 안되나?

DRF 없이도 Django로 API 구현이 가능합니다. 그런데 왜 DRF를 쓸까요? 편의성 때문입니다. API를 구현하다보면 접근 제어, JSON 데이터로 변환, 요청수 제한 등 다양한 기능 구현이 필요해지는데 DRF는 이런 기능을 이미 다 구현해두고 데코레이터나 클래스 상속, 믹스인 등으로 쉽고 빠르게 구현할 수 있도록 하고 있습니다.


어떤 방법이 있나?

  1. 그냥 장고로 JSONResponse를 리턴하면서 인증, 접근제어 등등을 한 땀 한 땀 구현하기.
  2. @api_view 데코레이터로 감싸거나 APIView를 클래스 상속하여 필요한 메소드 선언하며 구현하기
  3. generics.ListCreateAPIView와 같은 generic 클래스를 상속 받고 단순히 Serializer에 request 데이터를 넣고 리턴하는 중복, 반복 코드 없애고 간편하게 구현하기
  4. viewsets을 이용해 단 몇 줄로 CRUD(Create, Read, Update, Delete) 몽땅 구현하기

뭘 써야하나?

위 방법들을 저수준에서 고수준으로 나열해보면 아래와 같습니다. 저수준일수록 작성하는 코드가 많고 중복, 반복을 포함하고 있지만 상대적으로 로직이 이해하기 쉽고, 고수준으로 갈수록 코드가 짧아지고 중복, 반복 코드가 거의 없지만 동작 코드가 추상화되어 있기 때문에 초심자는 “이게 뭐야” “어떻게 동작하는 거야” 하는 것과 같이 마술처럼(이해가 안가고 어렵게) 느껴질 수 있습니다.

@api_view, APIView -> generics.* -> viewsets

__

이런 방법들중에서 딱 하나를 정해서 그걸로 모든 걸 통일해 구현할 필요는 없습니다. 예를 들어 페이지네이션(Pagination)이 필요한 경우 generics이나 viewsets 등으로 구현하면 설정 몇 개로 그냥 됩니다. 보통 페이지네이션은 전체 데이터 조회 등에 많이 쓰이니 이건 generics.ListCreateAPIView로 구현하고 업데이트나 기타 다른 것은 함수 기반이나 viewsets 등으로 구현할 수 있습니다.

뭘 선택해야 할지 모르겠다면 자신의 앱이 어떤 부류에 속하는지 한 번 생각해보세요.

별다른 커스터마이징된 동작이 없고 CRUD를 다 한다면 고민할 것 없이 viewsets을 쓰면 됩니다. CRUD 중 몇 개만 허용하거나 get, post 메소드에 간단한 커스터마이징 코드를 넣고 싶다면 @api_view 데코레이터나 generic.*을 쓰면 좋습니다. 그게 아니라 모든 동작을 다 커스터마이징하고 싶다면 APIView를 쓰면 됩니다.

헷갈린다면 generic.*이 결국 APIView를 상속받아 만들어진 클래스라는 걸 생각하면 쉽습니다. APIView가 포유류라고 가정하고 generic.*이 인간이라고 한다면 ‘검투사’ 캐릭터를 만들기 위해 포유류를 상속받는 것보다 인간을 상속 받는게 할 일이 휠씬 줄겠지요. 포유류를 상속 받는다면 인간의 속성을 하나 하나 내가 스스로 지정하고 만들어줘야 할겁니다. 이미 잘 만들어진 게 있는데도요. 시간도 많이 들고, 코드도 많아지고, 빠뜨리거나 실수도 늘겁니다. 검증도 필요할것이고요.

도움이 좀 되었나요?