API란?
API란 "Application Programming Interface"의 약자로, 프로그램들이 상호작용할 수 있는 인터페이스를 제공하는 것을 의미한다. Django의 API는 주로 HTTP 프로토콜을 통해 데이터를 주고받는 RESTful API 형식이며, 구축하기 위해서는 다음과 같은 주요 구성 요소가 필요하다
- 모델(Model): Django의 모델은 데이터베이스의 테이블과 매핑된다. 데이터베이스에서 데이터를 읽고 쓰는 데 사용되는 ORM(Object-Relational Mapping)을 통해 모델을 정의한다. 각 모델은 데이터베이스의 테이블과 필드에 해당하며, 이를 통해 데이터의 구조를 정의하고 조작할 수 있다.
- 시리얼라이저(Serializer): 시리얼라이저는 Django의 모델 데이터를 JSON 또는 XML과 같은 직렬화된 형식으로 변환해주는 역할을 한다.
- 뷰(View): Django의 뷰는 HTTP 요청을 받아 처리하는 로직을 담당한다. API의 뷰는 요청을 받아 데이터를 읽고 쓰는 등의 작업을 수행하고, 그 결과를 응답으로 반환한다.
- URL 패턴(URL Patterns): URL 패턴은 클라이언트가 API에 접근할 수 있는 엔드포인트를 정의한다. 각 엔드포인트는 특정한 HTTP 요청(Method)과 URL에 매핑되며, 해당 요청을 처리할 뷰를 지정한다.
GET
질문 목록을 가져와 API를 통해 제공하는 코드이다.
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.response import Response
from rest_framework.decorators import api_view
@api_view()
def question_list(request):
questions = Question.objects.all()
serializer = QuestionSerializer(questions, many = True)
return Response(serializer.data)
- @api_view(): question_list 함수를 API 뷰로 변환하는 장식자. 아무값도 넣지 않을경우에는 GET 메서드가 기본으로 호출된다.
- questions = Question.objects.all(): 데이터베이스에서 모든 질문을 가져온다. Question 모델의 모든 인스턴스를 쿼리셋으로 가져오는것이다.
- serializer = QuestionSerializer(questions, many=True): 질문 쿼리셋을 시리얼라이저에 전달하여 질문 데이터를 JSON 형식으로 직렬화. many=True는 다수의 객체를 직렬화할 때 사용.
- return Response(serializer.data): 시리얼라이저에서 얻은 데이터를 포함하는 Response 객체를 반환.
POST
질문 목록 조회 및 새로운 질문 등록을 위한 코드이다.
from rest_framework.decorators import api_view
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.response import Response
from rest_framework import status
@api_view(['GET','POST'])
def question_list(request):
if request.method == 'GET':
questions = Question.objects.all()
serializer = QuestionSerializer(questions, many = True)
return Response(serializer.data)
if request.method == 'POST':
serializer = QuestionSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
- @api_view(['GET', 'POST']): question_list 함수를 GET 및 POST 요청을 처리할 수 있는 API 뷰로 정의.
- GET 요청 처리:
- if request.method == 'GET':: 요청이 GET 메서드인 경우 위의 코드와 동일하게 진행
- POST 요청 처리:
- if request.method == 'POST': : 요청이 POST 메서드인 경우,
- serializer = QuestionSerializer(data=request.data): 요청으로부터 데이터를 받아 새로운 질문 객체 생성.
- if serializer.is_valid(): : 시리얼라이저가 유효한 경우,
- serializer.save(): 시리얼라이저에서 질문을 생성하고 저장.
- return Response(serializer.data, status=status.HTTP_201_CREATED): 상태 코드와 함께 생성된 질문을 포함하는 응답 객체를 반환
- else: : 유효하지 않은 경우,
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST): 에러 메시지를 포함하는 응답 객체를 반환
- if request.method == 'POST': : 요청이 POST 메서드인 경우,
Status codes - Django REST framework
www.django-rest-framework.org
PUT (==UPDATE)
특정 질문의 세부 정보를 반환하고, 질문 내용을 업데이트하는 코드
@api_view(['GET', 'PUT'])
def question_detail(request, id):
question = get_object_or_404(Question, pk=id)
if request.method == 'GET':
serializer = QuestionSerializer(question)
return Response(serializer.data)
if request.method == 'PUT':
serializer = QuestionSerializer(question, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
- question = get_object_or_404(Question, pk=id): 데이터베이스에서 주어진 ID에 해당하는 질문을 가져오며, 만약 해당 ID에 해당하는 질문이 없다면 404 에러를 발생
- GET 요청 처리:
- if request.method == 'GET':: 요청이 GET 메서드인 경우,
- serializer = QuestionSerializer(question): 질문 객체를 시리얼라이저에 전달하여 JSON 형식으로 직렬화.
- return Response(serializer.data): 시리얼라이저에서 얻은 데이터를 포함하는 Response 객체를 반환.
- if request.method == 'GET':: 요청이 GET 메서드인 경우,
- PUT 요청 처리:
- if request.method == 'PUT':: 요청이 PUT 메서드인 경우,
- serializer = QuestionSerializer(question, data=request.data): 요청으로부터 데이터를 받아 질문 객체를 업데이트
- if serializer.is_valid():: 시리얼라이저가 유효한 경우,
- serializer.save(): 시리얼라이저에서 질문을 업데이트하고 저장.
- return Response(serializer.data, status=status.HTTP_200_OK): 업데이트된 질문을 포함하는 응답 객체를 반환.
- else:: 유효하지 않은 경우,
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST): 에러 메시지를 포함하는 응답 객체를 반환
- if request.method == 'PUT':: 요청이 PUT 메서드인 경우,
DELETE
질문을 삭제하는 코드
from django.shortcuts import get_object_or_404
@api_view(['GET', 'PUT', 'DELETE'])
def question_detail(request, id):
question = get_object_or_404(Question, pk=id)
...
if request.method == 'DELETE':
question.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Class based view
데코레이터를 사용하지 않고 클래스로 나누어서 API를 작성하는것도 가능하다. 두가지 방법 모두 동일한 기능을 제공하지만 클래스를 사용하여 작성할 경우 코드가 더 깔끔해진다. 또한 상속 역시 가능해서 코드의 재사용성이 증가한다.
from rest_framework.views import APIView
from rest_framework.decorators import api_view
from polls.models import Question
from polls_api.serializer import QuestionSerializer
from rest_framework.response import Response
from rest_framework import status
from django.shortcuts import get_object_or_404
class QuestionList(APIView):
def get(self, request):
questions = Question.objects.all()
serializer = QuestionSerializer(questions, many=True)
return Response(serializer.data)
def post(self, request):
serializer = QuestionSerializer(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 QuestionDetail(APIView):
def get(self, request, id):
question = get_object_or_404(Question, pk=id)
serializer = QuestionSerializer(question)
return Response(serializer.data)
def put(self, request, id):
question = get_object_or_404(Question, pk=id)
serializer = QuestionSerializer(question, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, id):
question = get_object_or_404(Question, pk=id)
question.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Generic based view
Django에서 제공하는 Generic View는 일반적인 웹 개발 작업에서 반복되는 패턴을 미리 구현해 놓은 재사용 가능한 뷰 클래스들을 말한다. 이러한 Generic Views를 사용하면 개발자가 뷰를 작성할 때 일정한 패턴을 따라야 하는 번거로움을 줄일 수 있고, 코드의 재사용성과 유지보수성을 높일 수 있다.
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework import generics
class QuestionList(generics.ListCreateAPIView):
queryset = Question.objects.all()
serializer_class = QuestionSerializer
class QuestionDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Question.objects.all()
serializer_class = QuestionSerializer
제네릭뷰에 대한 더 자세한 내용을 알고싶다면 다음 사이트를 참고하면 좋을듯하다. https://kimcoder.tistory.com/581
[Django] 클래스형 뷰와 제네릭 뷰 소개
장고에서는 뷰를 클래스로도 작성할 수 있으며, 함수형 뷰보다는 클래스형 뷰가 더 이점이 많다. 이번 포스팅에서는 클래스형 뷰와 제네릭 뷰에 대한 감을 잡아보자. 1. 클래스형 뷰의 장점 - 다
kimcoder.tistory.com
'Dev Tool > Django' 카테고리의 다른 글
[Django] Serilalizer 알아보기 (1) | 2024.04.10 |
---|---|
[Django] 뷰(Views)와 템플릿(Templates) (0) | 2024.04.10 |
[Django] Shell 사용하기 (0) | 2024.04.09 |
[Django] model 만들고 활용하기 (0) | 2024.04.08 |
[Django] Django App 생성하기 (0) | 2024.04.08 |