Maximize Your Potential

BackEnd

[DRF 설명서 개념따라잡기] FBV와 CBV 언제 어떤 것을 사용해야 할까?

maxworld 2024. 9. 16. 10:53
728x90
반응형

 

API 개발을 위한 View 구현체를 제공하는 대표적인 라이브러리는 Django REST Framework와 장고 닌자입니다. DRF는 클래스 기반 View(CBV) 구현체에 특화된 라이브러리이고, 장고 닌자는 함수 기반 View(CBV) 구현체에 특화된 라이브러리입니다. 비교적 오랜 기간 개발되어온 DRF는 함수 기반 View 기능이 상대적으로 빈약합니다. 클래스 기반 View를 사용할 때 DRF의 기능을 더 잘 활용할 수가 있습니다. 다시한 번 정리하면, DRF는 클래스 기반 View로 백엔드 서버를 개발할 때 유용하며, 장고 닌자는 함수 기반 View로 하는 백엔드 서버를 개발할 때 유용하다는 점을 인지해주시면 됩니다.

DRF 설명서 개념따라잡기 : FBV와 CBV: 언제 어떤 것을 사용해야 할까?

 

그러나, 개발을 진행함에 있어 좀 더 유용한 방법이 있을 뿐 DRF도 함수 기반 View를 지원하고, 장고 닌자 역시 클래스 기반 View를 지원하기는 함을 잊어선 안됩니다. 다시 말해서, DRF와 장고 닌자 모두 함수 기반 View와 클래스 기반 View 두 가지 모두를 지원한다는 것입니다. 하지만 각자 특화된 방식에 집중되어 있기 때문에 함수 기반 View로 개발을 원한다면 장고 닌자를, 클래스 기반 View로 개발하기를 원한다면 DRF를 사용하는 것이 적절하다는 것입니다. 두 가지 방법이 있다는 것 정도만 인지를 해두시고, 이 책에서는 DRF를 중심으로 다뤄왔기 때문에 DRF 내에서의 FBV와 CBV를 함께 배워보도록 하겠습니다.

Django에서 Function-Based Views(FBV)와 Class-Based Views(CBV)는 웹 애플리케이션의 View를 구현하는 두 가지 주요 방법입니다. 각 방법은 고유한 장단점을 가지며, 프로젝트의 요구 사항과 개발자의 선호에 따라 선택됩니다. 이 두 방법에 대한 주요 특징과 장단점, 그리고 Mixin의 활용에 대해 살펴보겠습니다.

FBV(Function-Based Views)

FBV는 Django의 기초입니다. 초기의 Django에서는 CBV 형태의 API가 없었고, 함수를 통해 API를 정의하는 형태를 사용했습니다. 이러한 기능을 템플릿화하는 방법으로 CBV를 도입하여 반복되는 코드(boilerplate code)를 줄일 수 있게 만들었습니다.

from django.http import HttpResponse
from rest_framework.decorators import api_view

@api_view(['GET', 'POST'])
def Animal(request):
    if request.method == 'POST':
        return HttpResponse("Post method")
    else:
        return HttpResponse("Get method")
  • 장점
    • 직관적
    • 데코레이터를 통해 어떤 HTTP 요청 메서드를 받는지 알 수 있으며, 코드가 간결하고 이해하기 쉽습니다.
    • 간단한 작성
    • 작성이 간단하여 Flask 형식의 API를 쉽게 만들 수 있으며, 단발성이나 재사용 가능성이 낮은 특별한 비즈니스 로직의 API를 작성할 때 유리합니다.
  • 단점
    • 재사용성과 확장성 부족
    • 1회성 성격으로 인해 재사용성이 낮고 확장하기 어렵습니다. CRUD를 만들 때 조건문 분기처리를 해서 각각 처리해야 하며, 같은 모델 대상으로 단순 CRUD만 하더라도 4개의 함수를 작성해야 합니다.

CBV(Class-Based Views)

# views.py
from django.http import HttpResponse
from django.views import View

class Animal(View):
    def get(self, request):
        return HttpResponse("Get method")

    def post(self, request):
        return HttpResponse("Post method")
  • 장점
    • 코드 중복 줄임
    • HTTP 메서드명을 메소드로 선언하여 요청을 처리할 수 있으며, 코드 중복을 줄일 수 있습니다.
    • 확장성과 재사용성
    • 해당 클래스를 다시 상속받아 확장하고 재사용할 수 있어, 확장성과 재사용성이 높습니다.
  • 단점
    • 복잡성
    • 단순한 요청이나 단발성, 특수한 비즈니스 로직 처리에 상속으로 인해 불필요한 코드가 발생할 수 있으며, 해석이 어렵고 처음 접하는 사람에게는 러닝커브가 있을 수 있습니다.

Mixin 활용

Django와 DRF는 다양한 형태의 Mixin을 제공하며, 이를 활용하면 DRF를 더 효과적으로 이해하고 사용할 수 있습니다. 특히, DRF의 generic을 활용하면 단순 CRUD CBV를 쉽게 생성할 수 있습니다.

CBV는 FBV를 '대체'하기 위해 등장한 것이 아니며, 확장성과 Django 철학에 맞는 'less code'에 초점을 맞춰 등장했습니다. 적절한 상황에서 CBV와 FBV를 적절하게 섞어 사용해야 하며, 특정 상황에서는 FBV가 더 편리할 수 있습니다. 프로젝트의 요구 사항과 개발자의 경험에 따라 두 방식 중 어떤 것을 선택할지 결정할 수 있으며, Mixin을 활용하여 더욱 효율적인 코드 구조를 구성할 수 있습니다.

이를 통해 Django REST Framework(DRF)와 장고 닌자는 각각 클래스 기반 View(CBV)와 함수 기반 View(FBV)를 지원하는데, 각각이 특화된 기능을 가지고 있다는 것을 알았습니다. DRF는 주로 CBV를 사용하여 백엔드 서버를 개발할 때 유용하며, 장고 닌자는 FBV를 사용할 때 유용하다는 것을 알았습니다.

 

FBV는 코드가 직관적이고 작성이 간단하여 단발성이나 재사용 가능성이 낮은 API를 작성할 때 좋습니다. CBV는 코드 중복을 줄이고 확장성과 재사용성을 높이는데 유용하며, 특히 DRF의 generic을 활용하면 단순 CRUD CBV를 쉽게 생성할 수 있습니다. 두 방식을 적절하게 혼용하여 사용하고, Mixin을 활용하여 코드를 효율적으로 구성하는 것이 중요합니다.

 

함수 기반 View(Function-Based Views, FBV)는 Django의 간단하고 직관적인 방법으로 View를 정의할 수 있게 해줍니다. Django Rest Framework(DRF)는 이를 확장하기 위해 @api_view 데코레이터를 제공하여, 개발자가 특정 HTTP 메서드에 대한 요청만 처리할 수 있게 하고, 더욱 강화된 요청 및 응답 객체를 제공합니다.

#views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status

@api_view(['GET', 'POST'])
def Animal(request):
    # GET 요청 처리
    if request.method == 'GET':
        data = {'message': 'GET 요청을 받았습니다.'}
        return Response(data, status=status.HTTP_200_OK)
    # POST 요청 처리
    elif request.method == 'POST':
        data = {'message': 'POST 요청을 받았습니다.'}
        return Response(data, status=status.HTTP_201_CREATED)

# urls.py
path('', views.Animal, name='Animal'),

 

@api_view 데코레이터의 사용

@api_view 데코레이터는 View 함수 위에 적용되며, 처리할 수 있는 HTTP 메서드를 인자로 받습니다. 즉 @api_view 데코레이터는 View가 응답해야 하는 HTTP 메서드의 목록을 받아들이며, 이를 사용하여 매우 간단한 View를 작성할 수 있습니다. 위 코드에서 @api_view(['GET', 'POST']) 데코레이터는 example_view 함수가 GET과 POST 메서드에 대한 요청만 처리하도록 제한합니다.

요청 처리

@api_view 데코레이터를 사용하면, Viewvvv 함수의 첫 번째 인자로 DRF의 Request 객체를 받습니다. 이 객체는 Django의 기본 HttpRequest 객체를 확장하며, 더욱 풍부한 기능을 제공합니다**.**

응답 반환

View 함수에서는 DRF의 Response 객체를 사용하여 응답을 반환할 수 있습니다. Response 객체는 HTTP 응답을 생성하며, 데이터를 JSON으로 렌더링합니다. status 인자는 HTTP 상태 코드를 지정합니다. status 모듈은 상태 코드를 명확하게 표현하기 위해 사용됩니다.

 

함수 기반 View(FBV)는 Django의 간편하고 직관적인 방법으로 View를 정의하는 데 도움이 되며, DRF의 @api_view 데코레이터를 통해 확장할 수 있다.

@api_view 데코레이터를 사용하면 함수가 처리할 수 있는 HTTP 메서드를 지정할 수 있어, 코드를 더욱 명확하게 작성할 수 있다.

DRF의 Request 객체는 Django의 HttpRequest 객체를 확장하여 더욱 풍부한 기능을 제공하며, Response 객체를 사용하여 간편하게 HTTP 응답을 반환할 수 있다.

status 모듈을 사용하여 HTTP 상태 코드를 명확하게 지정할 수 있으며, 이를 통해 클라이언트에게 적절한 응답을 제공할 수 있다.

함수 기반 View를 사용하면 간단한 API를 빠르게 구현할 수 있으며, DRF를 통해 더 많은 기능을 활용할 수 있다.

 
 

클래스 기반 Views (CBV)

클래스 기반 View(Class-Based Views, CBV)는 Django와 Django Rest Framework(DRF)에서 View를 정의하는 또 다른 방법입니다. CBV는 View를 클래스로 정의하며, View의 동작을 메서드로 구현합니다. 이 방식은 코드의 재사용성과 조직을 향상시키며, 복잡한 View 로직을 더 쉽게 관리할 수 있게 해줍니다.

APIView 클래스의 활용

APIView는 CBV의 확장이자 DRF의 기본 View 클래스로, HTTP 메서드를 클래스의 메서드로 매핑하고, 요청 객체와 응답 객체를 DRF의 버전으로 확장합니다. APIView 클래스는 일반 View 클래스와 다음과 같은 차이점을 가집니다.

특징 Class Based View (CBV) APIView

정의 Django에서 View를 클래스로  
정의하는 방식 Django Rest Framework에서 제공하는 CBV의  
확장, RESTful API 개발에 특화    
Request/Response Django의 기본 HttpRequest, HttpResponse 사용 DRF의 Request, Response 객체 사용
(JSON 등 API 처리에 최적화)    
예외 처리 표준 Django 예외 처리 방식을 따름 API 관련 예외(APIException) 자동으로 적절한
HTTP 응답으로 변환    
인증 및 권한 기본적인 Django 인증 사용 요청에 대한 자동 인증 및 권한 체크
(API 보안 강화)    
스로틀링 기본적으로 제공하지 않음 요청 빈도 제한 기능 제공 (서버 과부하 방지) CBV는 일반적인 웹 애플리케이션 개발에 적합하며, APIView는 API 개발에 특화된 기능을 제공합니다.

간략히 말하자면, CBV는 일반적인 웹 애플리케이션 개발에 적합하며, APIView는 API 개발에 특화된 기능을 제공합니다.

# models.py
from django.db import models

class Animal(models.Model):
    name = models.CharField(max_length=100)
    species = models.CharField(max_length=100)
    age = models.IntegerField()

    def __str__(self):
        return self.name

# serializers.py
from rest_framework import serializers
from .models import Animal

class AnimalSerializer(serializers.ModelSerializer):
    class Meta:
        model = Animal
        fields = ['id', 'name', 'species', 'age']

**# views.py**
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Animal
from .serializers import AnimalSerializer

class AnimalList(APIView):
    def get(self, request, format=None):
        animals = Animal.objects.all()
        serializer = AnimalSerializer(animals, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = AnimalSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# urls.py
from django.urls import path
from .views import AnimalList

urlpatterns = [
    path('animals/', AnimalList.as_view(), name='animal-list'),
]

위 코드에서 클래스는 APIView 클래스를 상속받아 GET 메서드와 POST 메서드를 정의합니다. 이 메서드들은 각각 GET과 POST HTTP 메서드에 대한 요청을 처리합니다.

 

Generic View로 CRUD 구현하기

DRF는 일반적인 CRUD(Create, Read, Update, Delete) 작업을 수행하기 위한 여러 가지 제네릭 View를 제공합니다. 이러한 제네릭 View를 사용하면, 모델 기반의 API를 빠르고 쉽게 구현할 수 있습니다.

**#views.py**
from rest_framework import generics
from .serializers import AnimalSerializer
from .models import Animal

class AnimalList(generics.ListCreateAPIView):
    queryset = Animal.objects.all()
    serializer_class = AnimalSerializer
    
class AnimalDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Animal.objects.all()
    serializer_class = AnimalSerializer

# urls.py
from django.urls import path
from .views import AnimalList, AnimalDetail

urlpatterns = [
    path('animals/', AnimalList.as_view(), name='animal-list'),
    path('animals/<int:pk>/', AnimalDetail.as_view(), name='animal-detail'),
]
  • ListCreateAPIView

이 View는 객체의 목록을 검색하고 새 객체를 생성하는 데 사용됩니다.

  • RetrieveUpdateDestroyAPIView

이 View는 단일 객체를 검색, 업데이트, 삭제하는 데 사용됩니다.

 

Queryset 속성 및 Serializer_class 속성

Queryset 속성은 View가 작업할 대상 객체의 집합을 지정하며, Serializer_class 속성은 객체를 JSON으로 직렬화하고 역직렬화하는 데 사용되는 시리얼라이저 클래스를 지정합니다. 이러한 제네릭 View를 사용하면, 간단한 코드로 풍부한 기능을 제공하는 API를 빠르게 구현할 수 있습니다. 또한, 제네릭 View는 확장 및 커스터마이징이 가능하여, 복잡한 요구 사항에도 유연하게 대응할 수 있습니다. 이렇게 CBV와 제네릭 View를 활용하면, DRF를 사용하여 효율적이고 유지 관리가 쉬운 API를 구현할 수 있습니다. 

 

https://ridibooks.com/books/2773000084

 

DRF 설명서 : 개념때려잡기

DRF 설명서 : 개념때려잡기 작품소개: 간단한 DRF 프로젝트를 해봤는데 레벨 업이 필요하신가요?그런 분들에게 DRF 설명서 : 개념때려잡기를 추천해 드립니다.이 책은 6명의 오르미가 함께 DRF를 공

ridibooks.com