Django 로 개발을 하다보면 APIView 의 개념에 대해선 빼놓을 수 없을 것이고, 지금껏 저도 개발을 해오면서 정작 APIVIEW 에 대한 이론을 제대로 학습한 경험이 없습니다. 이번 기회에 핵심적인 부분들만 간단히 요약하여 정리해보고, 추후 포스트들에서 많은 개념들을 천천히 추가해보고자 합니다.
[Django] 클레스 기반 뷰(CBV) 와 함수 기반 뷰(FBV) 의 차이점은 무엇이고, 언제 사용하는게 좋을까? 에서도 다루었듯이, 장고로 개발할 수 있는 전형적인 구조는 2가지가 있습니다. 이 중에서 APIView
를 활용하는 방법이 바로 CBV
의 대표적인 구현 방식입니다.
그렇다면 클래스형 뷰의 특징은 뭐였는지 다시 상기해보면, 공통적인 함수들의 재사용이 가능하다는 특징이 있었습니다. 또한 이를 통해 같은 코드를 재사용해서는 안된다는 DRY
정책에 알맞게 코드를 작성하기도 쉬워집니다.
class MyPost(APIView):
def get(self, request, format=None):
post = Post.objects.all()
serializer = PostSerializer(post, many = true)
return Response(serializer.done)
def post(self, requuest, format=None)
serializer = PostSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(seializaer.data)
return Response(serializer.errors)
이는 함수형 뷰 @api_view
를 통해 HTTP 메소드를 지정해준 것 처럼, 동일한 이름의 내부 메소드를 정의해주면 됩니다. 덕분에 코드 흐름도 이해하기가 쉬워집니다.
지금부터 APIView 를 사용하기 위한 최소한의 핵심 동작원리만을 언급하겠습니다.
APIView를 url과 연결하기 위해서는 url_patterns 에 APIVIew.as_view()를 명시해야 합니다.
path("/hello", my.as_view(), name="user_detail")
이때 APIView 클래스의 disptach() 함수의 코드를 살펴봅시다.
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs) # 요청 정보 초기화 및 converting
self.request = request
self.headers = self.default_response_headers
try:
self.initial(request, *args, **kwargs)
# 적절한 핸들러 메소드 위임
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc) # 에러 핸들링
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
dispatch 함수는 django 프레임워크의 class based view의 dispatch와 비슷하지만, 예외 처리나 초기 permission check와 같은 훅을 제공합니다.
실행 흐름을 큰 틀에서 정리하면 다음과 같습니다.
정리를 해보자면, APIView
는 클래스 기반의 CBV(class base view) 의 개발 방식이며, 반대로 @api_view
는 함수기반의 FBV(function base view) 방식입니다.
APIView
는 렬화, 인증, 사용량 제한, 권한 등 여러가지 기본 설정을 제공합니다. 이러한 CBV 형태로 작성시, http 메소드에 해당하는 함수를 만들어줘야 합니다. 해당 함수 명은 지정되어 있으며, http의 메소드 명과 동일합니다. (함수명이 틀릴 경우 해당 메소드는 사용할수 없는 메소드로 간주 합니다. )
url에는 파라미터인자를 선언하므로 인자 pk를 받아야 하는 get/put/delete가 하나의 클래스, 파라미터가 필요 없는 gets/post가 하나의 클래스로 만든후 각각의 url로 선언 해야 합니다.