REST API는 아래 원칙을 따를 때 RESTful API라고 합니다.
원칙 | 설명 |
---|---|
1. 클라이언트-서버 구조 | 클라이언트는 요청을 보내고, 서버는 데이터를 제공 |
2. 무상태성(Stateless) | 요청 간 상태 정보를 저장하지 않음 (각 요청은 독립적) |
3. 캐시 가능(Cacheable) | 응답을 캐시하여 성능 최적화 가능 |
4. 계층화된 시스템(Layered System) | API 서버는 여러 계층으로 구성 가능 (보안, 로드 밸런싱) |
5. 일관된 인터페이스(Uniform Interface) | 표준 HTTP 메서드 사용 (GET , POST , PUT , DELETE ) |
6. 코드 온 디맨드 (선택적) | 필요하면 서버에서 실행할 수 있는 코드를 클라이언트에 제공 |
✅ 이 원칙을 따르면 RESTful API라고 부릅니다! 🚀
APIView
와 ViewSet
의 차이점Django REST Framework(DRF)에서는 API를 만들 때 APIView
와 ViewSet
을 사용할 수 있습니다.
둘 다 API 엔드포인트를 만들기 위한 방법이지만 구조와 사용법이 다릅니다.
APIView
(클래스 기반 뷰 - CBV)📌 APIView
는 HTTP 메서드(GET, POST, PUT, DELETE)를 직접 정의해야 하는 클래스 기반 뷰입니다.
View
클래스를 확장한 것으로, get()
, post()
, put()
, delete()
등의 HTTP 메서드를 직접 정의해야 합니다. urls.py
에서 수동으로 연결해야 합니다. APIView
예제from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Blog
from .serializers import BlogSerializer
class BlogListAPIView(APIView):
def get(self, request):
blogs = Blog.objects.all()
serializer = BlogSerializer(blogs, many=True)
return Response(serializer.data)
def post(self, request):
serializer = BlogSerializer(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
에서 수동으로 URL 등록from django.urls import path
from .views import BlogListAPIView
urlpatterns = [
path('blogs/', BlogListAPIView.as_view(), name='blog-list'),
]
ViewSet
(자동 라우팅 지원)📌 ViewSet
은 CRUD(Create, Read, Update, Delete)를 위한 API 엔드포인트를 자동으로 만들어주는 클래스입니다.
ModelViewSet
을 사용하면 리스트 조회, 개별 조회, 생성, 수정, 삭제 기능이 자동으로 생성됩니다. router.register()
를 사용하면 자동으로 URL 라우팅이 설정됩니다. list()
, create()
, retrieve()
, update()
, destroy()
등의 기본 CRUD 메서드를 제공하며, 필요하면 오버라이딩할 수 있습니다. ViewSet
예제from rest_framework import viewsets
from .models import Blog
from .serializers import BlogSerializer
class BlogViewSet(viewsets.ModelViewSet):
queryset = Blog.objects.all()
serializer_class = BlogSerializer
urls.py
에서 DefaultRouter
를 사용하여 자동 등록from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BlogViewSet
router = DefaultRouter()
router.register(r'blogs', BlogViewSet, basename='blog')
urlpatterns = [
path('', include(router.urls)), # ✅ 자동 라우팅
]
APIView
vs ViewSet
차이점 비교표APIView | ViewSet | |
---|---|---|
라우팅 방식 | urls.py 에서 path() 로 개별 연결 필요 | router.register() 로 자동 등록 가능 |
자동 CRUD 기능 | ❌ 직접 구현해야 함 | ✅ ModelViewSet 사용 시 자동 제공 |
사용 예제 | GET, POST 등 HTTP 메서드를 직접 정의 | list() , retrieve() , create() , update() , destroy() 제공 |
추천 사용 사례 | 특정 로직이 필요한 API | 단순한 CRUD API를 빠르게 만들 때 |
APIView
와 ViewSet
을 함께 사용하여 API 구현하기📌 기능:
GET /blogs/
→ 블로그 목록 조회 POST /blogs/
→ 새로운 블로그 생성 GET /blogs/popular/
→ 인기 블로그 조회 (ViewSet
으로는 자동 제공되지 않는 커스텀 API) ViewSet
을 사용하여 /api/blogs/
에서 CRUD 자동 제공 urls.py
코드 (APIView + ViewSet)from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BlogViewSet, BlogListAPIView, PopularBlogAPIView
router = DefaultRouter()
router.register(r'blogs', BlogViewSet, basename='blog')
urlpatterns = [
path('api/', include(router.urls)), # ✅ ViewSet 자동 라우팅
path('blogs/', BlogListAPIView.as_view(), name='blog-list'), # ✅ APIView 사용
path('blogs/popular/', PopularBlogAPIView.as_view(), name='popular-blogs'), # ✅ 커스텀 API
]
ViewSet
을 사용하여 /api/blogs/
에서 자동 생성 APIView
를 사용하여 /blogs/popular/
에서 직접 구현 ViewSet
과 APIView
을 적절히 섞어서 사용하면 효율적임. 🔥 즉, CRUD는 ViewSet
, 복잡한 로직은 APIView
를 사용하면 된다! 🚀
APIView
와 ViewSet
을 함께 사용하여 API 구현하기Django REST Framework에서 APIView
와 ViewSet
을 함께 사용하면 다양한 방식으로 API를 구성할 수 있습니다.
아래 예제에서는 Blog
모델을 사용하여 APIView
와 ViewSet
을 동시에 적용하는 방법을 보여줍니다.
APIView
를 사용한 개별 API 엔드포인트📌 기능:
GET /blogs/
→ 블로그 목록 조회 POST /blogs/
→ 새로운 블로그 생성 GET /blogs/popular/
→ 인기 블로그 조회 (ViewSet
으로는 자동 제공되지 않는 커스텀 API) views.py
에서 APIView
적용from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Blog
from .serializers import BlogSerializer
class BlogListAPIView(APIView):
def get(self, request):
blogs = Blog.objects.all()
serializer = BlogSerializer(blogs, many=True)
return Response(serializer.data)
def post(self, request):
serializer = BlogSerializer(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)
class PopularBlogAPIView(APIView):
def get(self, request):
popular_blogs = Blog.objects.filter(views__gte=100) # 조회수 100 이상
serializer = BlogSerializer(popular_blogs, many=True)
return Response(serializer.data)
urls.py
에서 APIView
등록from django.urls import path
from .views import BlogListAPIView, PopularBlogAPIView
urlpatterns = [
path('blogs/', BlogListAPIView.as_view(), name='blog-list'),
path('blogs/popular/', PopularBlogAPIView.as_view(), name='popular-blogs'),
]
ViewSet
을 사용한 자동 CRUD API📌 기능:
GET /api/blogs/
→ 블로그 목록 조회 POST /api/blogs/
→ 새로운 블로그 생성 GET /api/blogs/{id}/
→ 특정 블로그 조회 PUT /api/blogs/{id}/
→ 특정 블로그 수정 DELETE /api/blogs/{id}/
→ 특정 블로그 삭제 views.py
에서 ViewSet
적용from rest_framework import viewsets
from .models import Blog
from .serializers import BlogSerializer
class BlogViewSet(viewsets.ModelViewSet):
queryset = Blog.objects.all()
serializer_class = BlogSerializer
urls.py
에서 ViewSet
등록from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BlogViewSet
router = DefaultRouter()
router.register(r'blogs', BlogViewSet, basename='blog')
urlpatterns = [
path('api/', include(router.urls)), # ✅ ViewSet 자동 라우팅
]
APIView
와 ViewSet
을 같이 사용하는 urls.py
위에서 만든 APIView
와 ViewSet
을 하나의 urls.py
에서 함께 사용할 수 있습니다.
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BlogViewSet, BlogListAPIView, PopularBlogAPIView
router = DefaultRouter()
router.register(r'blogs', BlogViewSet, basename='blog')
urlpatterns = [
path('api/', include(router.urls)), # ✅ ViewSet 자동 라우팅
path('blogs/', BlogListAPIView.as_view(), name='blog-list'), # ✅ APIView 사용
path('blogs/popular/', PopularBlogAPIView.as_view(), name='popular-blogs'), # ✅ 커스텀 API
]
✔ CRUD API는 ViewSet
을 사용하여 /api/blogs/
에서 자동 처리
✔ 특수 API (인기 블로그 조회 등)는 APIView
를 사용하여 /blogs/popular/
에서 직접 처리
APIView | ViewSet | |
---|---|---|
라우팅 방식 | urls.py 에서 path() 로 개별 연결 필요 | router.register() 로 자동 등록 가능 |
자동 CRUD 기능 | ❌ 직접 구현해야 함 | ✅ ModelViewSet 사용 시 자동 제공 |
사용 예제 | 특정 기능 API (/blogs/popular/ ) | CRUD API (/api/blogs/ ) |
추천 사용 사례 | 비즈니스 로직이 복잡한 API | 단순한 CRUD API를 빠르게 만들 때 |
APIView
와 ViewSet
을 어떻게 함께 사용할 수 있는가?ViewSet
을 사용하여 /api/blogs/
에서 자동 생성 APIView
를 사용하여 /blogs/popular/
에서 직접 구현 APIView
와 ViewSet
을 적절히 섞어 사용하면 효율적인 REST API를 만들 수 있음🔥 즉, CRUD는 ViewSet
, 복잡한 로직은 APIView
를 사용하면 된다! 🚀