[KT Aivle AI] 14주차 장고 RESTful API

hyowon·2024년 5월 28일
0

KtAivle

목록 보기
37/39

개요

  • Unit 1. RESTful API 개요
  • Unit 2. Django REST Framework
  • Unit 3. RESTful API 구현

1) RESTful API 개요

REST 정의

  • Representational State Transfer (REST):
    • 자원(Resource)의 표현(Representation)에 의한 요청정보 전달
    • 주로 JSON 또는 XML 데이터를 통해 응답
    • 웹의 기존 기술과 HTTP 프로토콜을 활용하는 통신 방식

REST 개념

  • HTTP URI:
    • URI를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD 기능을 적용하는 것을 의미한다

REST API

  • API(Application Programming Interface):
    • 데이터와 기능의 집합을 제공하여 컴퓨터 프로그램간 상호작용을 촉진하며, 서로 정보를 교환가능 하도록 하는 것
  • REST API:
    • REST 기반으로 서비스 API를 구현한 것
    • OpenAPI: 누구나 사용할 수 있도록 공개된 API (구글 맵, 공공 데이터 등)
    • 마이크로 서비스: 하나의 큰 애플리케이션을 여러 개의 작은 애플리케이션으로 쪼개어 변경과 조합이 가능하도록 만든 아키텍처

REST API 설계 규칙

  1. URI:
    • URI는 정보의 자원을 표현해야 한다
  2. 자원에 대한 행위:
    • HTTP Method(GET, PUT, POST, DELETE)로 표현한다
  3. 슬래시 구분자:
    • 계층 관계를 나타낸다
  4. URI 마지막 문자:
    • 슬래시를 포함하지 않는다 (Django는 /를 붙이는 것을 권장함)
  5. 하이픈:
    • URI 가독성을 높이는데 사용한다
  6. 밑줄:
    • URI에 사용하지 않는다
  7. URI 경로:
    • 소문자가 적합하다
  8. 파일확장자:
    • URI에 포함하지 않는다

RESTful

  • RESTful:
    • REST라는 아키텍처를 구현하는 웹 서비스를 나타내기 위해 사용되는 용어이다. 'REST를 제공하는 웹 서비스를 'RESTful하다'고 할 수 있다
  • RESTful의 목적:
    • 이해하기 쉽고 사용하기 쉬운 REST API를 만드는 것
    • RESTful한 API 구현 목적은 성능 향상이 아니라 일관적인 컨벤션을 통한 API의 이해도 및 호환성을 높이는 것
    • 성능이 중요한 상황에서는 굳이 RESTful한 API를 구현할 필요는 없다

정리

  • RESTful API 는 자원을 명시하는 URIHTTP Method 를 사용하여 웹 서비스 간의 상호작용을 촉진하고, 일관적인 API 설계를 통해 사용성과 호환성을 높이기 위한 아키텍처 스타일입니다.
  • 이를 통해 사용자는 이해하기 쉽고, 유지보수가 용이한 API를 설계할 수 있습니다. RESTfulAPI 의 목표는 성능보다는 일관성과 가독성을 중시하는 것입니다.

2) Django REST Framework

1. Django REST Framework 설치

  • 커맨드창
pip install djangorestframework

2. 앱 등록

mysite2/settings.py:

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "rest_framework",
]

3) RESTful API 구현

1) 새로운 앱 생성

mysite2/urls.py:

from django.urls import path, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from mysite2.views import HomeView

urlpatterns = [
    path('', HomeView.as_view(), name='home'),
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),
    path('api/', include('api.urls')),
    path('api2/', include('api2.urls')),
]

2) 뷰 구현

api2/serializers.py:

from django.contrib.auth.models import User
from rest_framework import serializers

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'is_staff']

api2/views.py:

from django.contrib.auth.models import User
from rest_framework import viewsets
from .serializers import UserSerializer, PostSerializer
from blog.models import Post

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

3) 새로운 앱 생성

api2/urls.py:

from django.urls import path, include
from rest_framework import routers
from .views import UserViewSet, PostViewSet

router = routers.DefaultRouter()
router.register('users', UserViewSet)
router.register('posts', PostViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

4) Post REST API 구현 (Post 관련 추가)

api2/serializers.py:

from django.contrib.auth.models import User
from rest_framework import serializers
from blog.models import Post, Comment

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'is_staff']

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'image', 'like', 'category']

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = '__all__'

api2/views.py:

from django.contrib.auth.models import User
from rest_framework import viewsets
from .serializers import UserSerializer, PostSerializer, CommentSerializer
from blog.models import Post, Comment

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer

api2/urls.py:

from django.urls import path, include
from rest_framework import routers
from .views import UserViewSet, PostViewSet, CommentViewSet

router = routers.DefaultRouter()
router.register('users', UserViewSet)
router.register('posts', PostViewSet)
router.register('comments', CommentViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

정리

  • 1. 새로운 앱 생성
    • 이 부분은 새로운 앱을 생성하고 해당 앱의 URL을 프로젝트의 루트 URL에 연결하는 부분입니다.
  • 2. 뷰 구현
    • 뷰는 요청을 받아서 처리하는 부분을 담당합니다. Serializer 는 모델 데이터를 JSON 포맷으로 변환하거나 반대로 JSON 데이터를 모델 객체로 변환하는 역할을 합니다. ViewSet은 일반적인 CRUD(Create, Retrieve, Update, Delete) 기능을 제공합니다.
  • 3. Post REST API 구현
    • 이 부분은 게시물( Post )에 대한 REST API 를 구현하는 부분입니다. 게시물과 관련된 모델( Post )과 Comment 를 위한 SerializerViewSet 을 구현합니다.
    • 또한, URLs 에 대한 설정도 하여 각각의 엔드포인트가 어떤 ViewSet 과 연결되는지 설정합니다.

이러한 구조를 통해 Django 를 사용하여 강력하고 유연한 RESTful API를 구축할 수 있습니다.

4) Router 대신 URL Path 직접 정의하기

serializers.py

from rest_framework import serializers
from blog.models import Post, Comment

# 게시물 목록을 위한 Serializer
class PostListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'image', 'like']

# 게시물 상세 정보를 위한 Serializer
class PostRetrieveSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        exclude = ['create_at']
  • Serializer 는 데이터를 JSON 형식으로 변환하거나 JSON 데이터를 모델 객체로 변환하는 역할을 합니다.
  • 위 코드에서는 게시물 목록을 위한 PostListSerializer와 게시물 상세 정보를 위한 PostRetrieveSerializer를 정의합니다.

views.py

from rest_framework.generics import ListAPIView, RetrieveAPIView, CreateAPIView
from .serializers import PostListSerializer, PostRetrieveSerializer, CommentSerializer
from blog.models import Post, Comment

# 게시물 목록을 보여주는 API 뷰
class PostListAPIView(ListAPIView):
    queryset = Post.objects.all()
    serializer_class = PostListSerializer

# 특정 게시물을 보여주는 API 뷰
class PostRetrieveAPIView(RetrieveAPIView):
    queryset = Post.objects.all()
    serializer_class = PostRetrieveSerializer

# 댓글을 생성하는 API 뷰
class CommentCreateAPIView(CreateAPIView):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
  • 여기서는 Django REST Framework 의 제네릭 뷰인 ListAPIView, RetrieveAPIView, CreateAPIView를 사용하여 게시물 목록을 보여주는 PostListAPIView , 특정 게시물을 보여주는 PostRetrieveAPIView, 그리고 댓글을 생성하는 CommentCreateAPIView를 정의합니다.

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('post/', views.PostListAPIView.as_view(), name="post-list"),          # 게시물 목록
    path('post/<int:pk>/', views.PostRetrieveAPIView.as_view(), name="post-detail"),  # 특정 게시물
    path('comment/', views.CommentCreateAPIView.as_view(), name="comment-list"),     # 댓글 생성
]
  • URL 패턴을 정의하여 각 API 뷰에 대한 엔드포인트를 지정합니다. 이렇게 하면 /post/, /post/<id>/, /comment/와 같은 경로로 API를 호출할 수 있습니다.

좋아요 기능 구현

views.py

from rest_framework.generics import UpdateAPIView
from rest_framework.response import Response
from .serializers import PostListSerializer
from blog.models import Post

# 게시물에 좋아요를 추가하는 API 뷰
class PostLikeAPIView(UpdateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostListSerializer

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        data = {'like': instance.like + 1}  # 좋아요 수 증가
        serializer = self.get_serializer(instance, data=data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return Response(serializer.data)
  • UpdateAPIView를 상속받아 게시물에 좋아요를 추가하는 PostLikeAPIView를 정의합니다. 이 API는 요청이 들어올 때마다 해당 게시물의 좋아요 수를 증가시킵니다.

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('post/', views.PostListAPIView.as_view(), name="post-list"),               # 게시물 목록
    path('post/<int:pk>/', views.PostRetrieveAPIView.as_view(), name="post-detail"),   # 특정 게시물
    path('comment/', views.CommentCreateAPIView.as_view(), name="comment-list"),      # 댓글 생성
    path('post/<int:pk>/like/', views.PostLikeAPIView.as_view(), name="post-like"),   # 게시물에 좋아요
]
  • URL 패턴을 정의하여 게시물에 좋아요를 추가하는 엔드포인트를 만들었습니다. 이렇게 하면 /post/<id>/like/와 같은 경로로 게시물에 좋아요를 추가할 수 있습니다.
profile
안녕하세요. 꾸준히 기록하는 hyowon입니다.

0개의 댓글