티스토리 뷰

728x90

이번 포스팅에서는 지난 포스팅까지 구축된 API 서버와 간단한 가상 데이터를 이용하여 Client가 CRUD 작업을 요청하면 API서버에서 어떤 방식으로 동작하는지 알아보겠습니다.

 

API 서버 구축은 이전 포스팅을 참고하세요. 

 

 

Django로 RESTful API 서버 구축해보기 (1) - API서버 구축과 API Test tool

벌써 두 번째 포스팅입니다. 지난 포스팅에서 Django를 설치하고 기본적인 가상환경 셋팅을 마쳤습니다. Django로 RESTful API 서버 구축해보기 (0) - Django 설치와 가상환경설정 작년 졸업프로젝트를 할

recordofwonseok.tistory.com

 

 

데이터를 관리할 App 생성

 

 가장 먼저 할 일은 데이터를 생성하고 관리해줄 App을 하나 생성하는 것입니다.

 

django-admin startapp dataTest

 

터미널에 다음 명령어를 입력하여 dataTest라는 앱을 하나 생성하겠습니다. 여기서 앱이란 DJango의 프로젝트를 구성하고 있는 기능요소들을 의미합니다. 각각의 앱은 자신만의 Models, Views, Urls를 갖고 있으며 독자적인 기능을 수행할 수 있습니다.

 

정상적으로 앱이 생성된 것을 확인할 수 있습니다. 

 

앱을 생성하고 가장 먼저 할 일은 앱을 프로젝트에 연동하여 사용할 준비를 하는 것입니다.

 

메인 프로젝트(저의 경우 RESTfulAPI) 의 settings.py에 들어가서 INSTALLED_APPS에 방금 생성한 app을 추가해주어야 합니다. 

그러지 않으면 프로젝트에서 앱을 실행할 때 에러가 발생하게 됩니다.

 

Model 구축

 

앱을 프로젝트에 연동하였으니 이제 데이터를 관리할 모델을 구축해야 합니다.

 

Django의 MTV 구조에 대해 잘 모르시는 분은 먼저 MTV 구조에 대해 공부하신 후 따라하는 것을 추천드립니다.

 

MTV 구조는 간단히 말하면 데이터 모델의 역할을 하는 models, 데이터 가공과 처리, 라우팅 역할을 수행하는 views, 화면에 보여주는 역할을 수행하는 template를 지칭하는 말입니다.  순서대로 Spring의 M, V, C에 매칭되는 개념입니다.

(스프링의 Views는 화면에 띄워주는 역할을 수행하지만 Django의 View는 요청의 처리, 데이터의 가공 등 controller의 역할을 수행합니다. )

 

models를 만들고 적용하기 위해서는 먼저 migrtion을 생성해야 합니다.

python manage.py makemigrations

위 명령어로 migrations를 생성해주면 됩니다.

 

이제 dataTest 앱의 models.py로 이동하여 모델을 구축하겠습니다.

 

예전에 프로젝트를 위해 Django를 사용할 땐 mySQL workbench에 연동하여 사용했었는데 그 방법은 메인 앱의 settings.py로 가서 DATABASES에 mysql 연동을 위한 정보를 입력하고 migrate를 실행하면 mysql에 생성된 스키마에 맞게 자동으로 models.py에 데이터 모델이 생성되는 구조였습니다.

 

이번에는 간단한 데이터를 사용할 것이므로 django기본 데이터베이스인 sqlite3을 사용하겠습니다. 

models.py에 users라는 모델을 몇개의 컬럼들과 함꼐 구축했습니다.

 

 

models.py

from django.db import models

# Create your models here.

class Users(models.Model):
    name = models.CharField(max_length=10) # 이름
    address = models.TextField() # 주소
    phone_number = models.CharField(max_length=15) # 번호
    job_position = models.CharField(max_length=10) # 직위
    age = models.IntegerField(max_length=5) # 나이
    dateTimeOfPosting = models.DateTimeField(auto_now_add=True)
    class Meta:
        ordering = ["dateTimeOfPosting"]

 

여기서 Meta 클래스는 테이블에 대한 추가 요소들을 정의하기 위해 사용합니다. ordering은 테이블 내 객체의 순서를 정의할 때 사용하며 dataTimeOfPosting 값의 오름차순으로 정렬됩니다.

 

모델을 생성했으니 migrate를 실행하여 프로젝트에 적용시켜 주겠습니다.

 

python manage.py migrate

 

migration이 잘 적용된 것을 볼 수 있습니다.

 

 

 

Serializer 생성

 

모델이 잘 구축되었으니 이제 view에서 데이터에 CRUD 작업을 수행하야 하는데 그 전에 할 일이 있습니다.

바로 Serializer을 추가하는 작업입니다.

 

Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

 

Serializer는 공식문서에 다음과 같이 설명되어 있습니다. 번역하자면 쿼리셋이나 모델 인스턴스같은 복잡한 데이터를 

JSON이나 XML같은 사용하기 쉬운 데이터셋으로 변환해주는 모듈이라는 것입니다. 

 

RESTful API는 JSON 타입의 데이터로 통신이 이루어지기 때문에 ORM구조인 models의 데이터를 Serializer를 통해 JSON 타입으로 변환해주어야 합니다.

 

Serializer작업을 수행하기 위해 Serializer.py를 dataTest앱에 생성하겠습니다.

 

 

Serializer까지 생성했다면 이제 정말 준비가 끝났습니다!

 

view 생성

 

CRUD Operation 중 가장 기본적인 Read와 Create 작업을 먼저 구현하겠습니다.

 

from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from .models import Users
from .serializer import userSerializer

@csrf_exempt
def user_list(request):
    if request.method == 'GET': # GET 방식일 때
        query_set = Users.objects.all() # ORM으로 Users의 모든 객체 받아옴
        serializer = userSerializer(query_set, many=True) # JSON으로 변환
        return JsonResponse(serializer.data, safe=False) # JSON타입의 데이터로 응답

    elif request.method == 'POST': # POST방식일 때
        data = JSONParser().parse(request) # 요청들어온 데이터를 JSON 타입으로 파싱
        serializer = userSerializer(data=data) # Serializer를 사용해 전송받은 데이터를 변환하기 위함
        if serializer.is_valid(): # 생성한 모델과 일치하면
            serializer.save() # 데이터 저장
            return JsonResponse(serializer.data, status=201) # 정상 응답 201
        return JsonResponse(serializer.errors, status=400) # 모델에 일치하지 않는 데이터일 경우

 

views.py에 위 코드를 붙여넣기하고 서버를 실행하면 됩니다. 각 코드에 설명은 주석으로 달아 놓았으니 참고하시면 될 것 같습니다.

 

urls 설정

 

위 설정이 모두 완료되었다면 요청을 받기 위한 urls를 설정해주어야 합니다. 각 app에도 router의 기능을 하는urls를 사용할 수 있지만 간단하게 진행하기 위해 메인 폴더의 urls.py에서 경로를 지정하겠습니다.

 

urls.py

from django.urls import path, include
from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
from dataTest import views
# Serializers define the API representation.

urlpatterns = [
    path('users/', views.user_list),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

 

user/ 로 요청이 들어올 경우 user_list를 실행하도록 하였습니다.

 

여기서 from dataTest import views에 에러가 발생하시는 분들은 settings.py의 BASE_DIR 경로를 확인하신 후 

BASE_DIR = Path(__file__).resolve().parent.parent

 

아래와 같다면 정상적으로 작동하니 무시하셔도 됩니다.

 

 

API 서버 테스트

 

이제 insomnia를 사용하여 api 서버가 정상적으로 작동하는지, 데이터는 잘 전송되는지 확인해보겠습니다.

http://127.0.0.1:8000/users/ 경로로 GET 요청을 보낼 경우 아래와 같은 응답이 돌아옵니다.

 

 

200 OK 응답과 함께 빈 배열이 전송되는데 아직 데이터베이스에 아무런 데이터도 존재하지 않으므로 이는 정상적인 응답입니다.

 

이제 POST 방식으로 데이터베이스에 데이터를 생성해보겠습니다.

 

보내는 데이터의 형태를 JSON으로 선택하고 제가 만든 모델의 양식에 맞게 json 문법으로 데이터를 작성하면 됩니다.

 

우선 테스트로 아무 데이터나 보내보겠습니다.

CREATE 요청은 POST 방식으로 동작하므로 요청방식을 POST로 바꾼 후 Send를 누르면 아래와 같은 응답이 돌아옵니다.

이와 같은 결과는 dataTest 앱의 views.py 에서 생성한 모델과 일치하지 않는 경우 status 400과 함께 serializer.errors를 응답으로 전송하라고 구현했기 때문에 나타납니다.

elif request.method == 'POST': # POST방식일 때
    data = JSONParser().parse(request) # 요청들어온 데이터를 JSON 타입으로 파싱
    serializer = userSerializer(data=data) # Serializer를 사용해 전송받은 데이터를 변환하기 위함
    if serializer.is_valid(): # 생성한 모델과 일치하면
        serializer.save() # 데이터 저장
        return JsonResponse(serializer.data, status=201) # 정상 응답 201
    return JsonResponse(serializer.errors, status=400) # 모델에 일치하지 않는 데이터일 경우

 

 

이번에는 정상적인 데이터 양식으로 전송해보겠습니다.

 

{
	"name": "한원석",
	"phone_number": "010-0000-0000",
	"address": "서울특별시 마포구 상수동 ",
	"job_position": "인턴",
	"age": 26
}

 

위 양식으로 정상적인 데이터를 전송하니 201 Created status와 함께 생성된 데이터가 응답으로 돌아왔습니다.

 

 

이제 다시 GET 요청으로 데이터베이스를 조회하면

 

 

데이터 생성이 정상적으로 동작한 것을 확인할 수 있습니다!

 

 


Create와 Read가 정상적으로 잘 동작하는 것을 확인했습니다. 이론으로만 알다가 실제로 구현해보니 훨씬 쉽게 이해되고 머릿속에 남는 것 같습니다. 

 

중간에 models.py에 오타가 나서 migrate가 제대로 안 된 버그때문에 시간을 많이 잡아먹어서 DELETE와 UPDATE 작업은 다음 포스팅에서 진행하도록 하겠습니다. 

 

 

 

 

320x100
댓글
© 2022 WonSeok, All rights reserved