티스토리 뷰

일상코딩/노트

Django : REST API 2

코딩애벌레 2024. 4. 12. 10:59

지난 시간에 이어서 API 서버를 구축하기 위한 초석을 쌓아보자


Django-rest-framework

Django를 기반으로 하는 파이썬 라이브러리

: rest_framework에서 제공하는 serializer(직렬화)을 사용하기 위함

설치 명령어
설치 명령어에 쓰인 단어와 많이 다르니 유의하자

 

Serialization (직렬화)

: 여러 시스템에서 활용하기 위해 데이터 구조나 객체 상태를 나중에 재구성 할 수 있는 포맷으로 변환하는 과정

어떠한 언어나 환경에서도 나중에 다시 쉽게 사용할 수 있는 포맷으로 변환하는 과정

직전 시간에 배웠던 requests의 라이브러리 역할을 반대로 해주고 있는 과정


Postman

html이 사라짐으로써 CRUD를 확인하기 어려워 졌기 때문에 프로그램을 이용하여 데이터 조작을 할 수 있다

: API를 구축하고 사용하기 위한 플랫폼

: API를 빠르게 만들 수 있는 여러 도구 및 기능을 제공한다

Postman 프로그램 실행 화면

 

Postman에서 실행 가능한 method와 url 예시는 아래와 같다. 이외 view 함수 정의를 해준다면 다른 기능도 사용 가능하다.

  GET POST PUT PATCH DELETE
articles/ 전체 글 조회 글 작성      
articles/1/ 특정 글 조회   특정 글 수정 특정 글 일부 수정 특정 글 삭제

 

이제 method의 요청이 들어오면 해당하는 결과를 반환해주는 함수를 만들어 보자.



GET (List 조회)
게시글 데이터 목록을 제공하는 ArticleListSerializer 정의

 

article의 모델은 title, content를 필수로 받고 있다. (created_at과 updated_at은 자동)

 

 

Serializer

Serialization을 진행하여 Serialized data를 반환해주는 클래스

 

ModelSerializer

Django 모델과 연결된 Serializer 클래스

일반 Serializer와 달리 사용자 입력 데이터를 받아 '자동'으로 모델 필드에 맞추어 Serialization을 진행

: 필요없는 데이터, 요청하지 않는 데이터는 저장되지 않는다.

 

더이상 name을 정의할 필요가 없어졌다
갑자기 새로운 부분이 많아져서 어지러워진다

 

빨간 네모

rest_framework의 decorators에 속하며 요청된 method에 대해서만 정의, 처리하겠다는 것을 명시하는 부분이다. 이전에는 html의 method의 값을 전달해줄 수 있었으나 사라지게되면서 method를 명시해주기 위해 필수 값이다. 기본 값은 'GET'이다. 다른 method 요청에 대해서는 405 Method Not Allowed 에러를 응답한다.

 

파란 네모

rest_framework 라이브러리의 일부이며 url 요청이 들어오게 되면 해당 url에 django rest_framework의 결과를 띄우게 된다. serializer.data에서 .data가 붙는 이유는 Serializer를 사용하여 모델 인스턴스를 json 형식으로 변환 했는데, 이 과정에서 결과 데이터를 가리키기 위함이다.

 

초록 네모

작성했던 ArticleSerializer를 가져오며, Article 객체를 모두 호출한 articles를 넣음으로써 데이터 포장을 해준다. many의 속성은 개수가 2개 이상일 경우 넣어준다. 단일 데이터의 경우 해당 속성은 작성하지 않아도 된다.

다만, 데이터의 개수가 확실치 않다면 조건문을 통해 나누어 주어야하는 번거로움이 있다.

 

Postman에서는 해당 url로 요청을 보내면 저장되어있던 데이터베이스의 내부 데이터를 조회할 수 있다
html 작성 없이 해당 페이지를 볼 수 있는 이유는 djangorestframework에서 제공해주기 때문이다

 


GET (단일 데이터 조회)

 

위의 과정과 동일하다. 다만, 게시글의 pk값을 받아서 url과 함수에 전달해서 단일 데이터 조회할 때 사용해주기만 하면 된다.

url에 게시글의 번호를 전달해주어야 한다
article_pk를 통해 게시글(단일 데이터) 조회한 후 serializer로 감싸주면 된다. 이외 동일
명시적으로 단일 데이터 조회와 리스트 조회를 나누어준다. (물론 같은 형태면 사용해도 무관하긴 하다)
문제없이 단일 데이터 조회 확인

 


POST (게시글 데이터 생성)

 

게시글 데이터를 생성하는 과정의 view함수를 따로 def article_create로 나눠야할까? 물론 나누어도 문제는 없다. 하지만, 웹의 흐름상 게시글 목록에서 게시글 생성 버튼이 있는 것을 고려, 요청 method가 POST인 점을 이용해 article_list의 view 함수 구조 변경(분기처리)를 한다면 웹의 흐름과 가독성을 모두 잡을 수 있다. 이렇게 함으로써 url을 추가할 필요도 없어진다.

 

  • 분기 처리시 if, else를 사용하지 않고 elif로 method를 명시해준다
  • request.data는 django 내부의 python 데이터이므로 serializer로 변형해준 다음 유효성 검사를 해준다
  • 유효성 검사를 통과했다면 저장, 통과하지 못한다면 자동으로 serializer 내부에 errors 데이터가 저장된다
  • 따라서 통과했을 때는 serializer.data를 Response를 통해 return 해주면 되고 오류시에는 serializer.errors를 return해주면 된다

해당 함수를 테스트해보려면 어떻게 해야할까? 우리에게 주어진 html이 없어서 데이터 생성을 하는 것은 할 수 없는 것일까? 바로 이때 등장하는 것이 Postman이다. 

다양한 method가 채워져 있는 모습

 

번호 순서대로 클릭해주면 직접 채워넣을 수 있는 Key : Value 표가 있다

 

POST 요청을 보낼 수 있는 url로 수정해주고 model를 확인하여 알맞은 데이터를 채워준다

 

Postman에서 제대로 완료 되었다는 확인을 해준다

 

database와 조회에서도 문제없이 확인 가능

 

틀리게 작성하면 당연히 문제를 반환해준다. 일부러 필드명을 틀린다면 serializer에서 errors를 반환한 메세지를 띄워준다

 

근데 왜 이럴까?

 

문제는 데이터 생성에 오류가 발생했는데 Postman에서는 문제 없다는 듯이 OK를 띄고 있다. 이는 따로 설정을 해주지않는다면 요청 자체는 오류가 없기 때문에 200 OK를 반환해준다 (없는 method로 요청한다면 405 method 에러를 띈다)

이를 해결하기 위해서 DRF에서 제공하는 status를 사용할 수 있다.

Response를 타고 들어가면 기본 status_code가 200으로 전달되는 모습을 볼 수 있다

 

: 데이터 생성 성공했을 경우 201 Created 응답

: 데이터 생성이 실패 했을 경우 400 Bad request 응답

DRF에 있는 stauts를 import 해준 뒤, Response에서 status를 할당해주면 된다
생성과 오류 모두 제대로된 status를 출력하고 있다

 


DELETE (게시글 데이터 삭제)

 

게시글 데이터를 삭제하는 클라이언트를 떠올려보면 주로 detail 페이지에서 버튼을 누름으로써 삭제를 요청하는 것이 자연스럽다. 그러면 view 함수 중 detail에 넣어주면 되겠다.

 

: 요청에 대한 데이터 삭제가 성공했을 경우에는 204 No content 응답

삭제 요청의 Response에서 넘겨줄 데이터가 따로 필요 없으므로 status만 정의해준다.

 

문제없이 삭제가 되었지만, 아쉬운점은 body 부분에 아무런 메세지가 뜨지 않는다. 이유는 넘겨준 데이터가 없기 때문인데..

 

위에서는 계속 데이터를 넘겨주어 출력하고 있었지만, 굳이 데이터 값이 아니라 직접 정의한 데이터 혹은 문자열 등을 모두 넘겨줄 수 있다. 첫번째 인자로 위치하고 있으니 Response의 첫번째 인자로 넘겨주기만 하면 된다.

context로 넘겨도 되고, 직접 문자열을 적어주어도 문제없다
명확히 삭제됨을 확인할 수 있다.

 


PUT (게시글 데이터 수정)

 

수정의 경우도 당연히 detail 페이지에서 진행할 것이다! 빠르게 작성해보자. 여러번 겪었지만 주의해야할 점은 수정의 경우 수정 전 데이터가 같이 넣어주지 않는다면 수정되는 것이 아닌 새로운 데이터가 생성될 것이다. 즉, Serializer 넘겨줄때 instance를 같이 넘겨주자. (첫번째 매개변수가 instance, 두번째가 data 이기 때문에 직접 선언은 안해주어도 되긴 한다)

Ctrl + 좌클릭으로 탐색하는 것이 습관화 되어있으면 좋다
제목만 바꾸고 싶어서 수정 요청을 보냈는데 왜 content도 필요로 할까?

 

오류가 발생한 이유는 유효성 검사를 통과하지 못했다는 것인데, PUT은 전체 게시글 수정을 의미한다. 글 초반에 사용 가능한 method를 보여주면서 PUT 과 PATCH가 굉장히 유사했다. 즉, PUT은 모든 데이터를 수정해야만 할 경우, PATCH는 일부분 수정도 가능한 것이다. 

방법은 2가지다. PUT을 사용하면서 일부분 수정을 허용해주는 것 혹은 PATCH method를 사용하는 것이다. 

PUT을 배웠는데 일부분 수정 허용도 배워야 하지 않겠는가? 어렵지 않다 Serializer 을 통할 때, partial 값을 True로 수정해주기만 하면 된다.

partial 속성이 기본 값 False이며 False일 경우 empty. 값을 비워버린다는 것이다.
일부분 수정을 허락

 

그럼 PATCH를 사용하면 되지 않을까? 물론 올바른 사용은 PATCH를 이용하는 것이다. RESTful 한 조건에 맞추기 위해서는 일부분 수정은 PATCH, 전체 수정은 PUT을 사용하는 것이 원칙이다.

 

+ 부록

raise_exception

  • is_valid()의 선택 인자
  • 유효성 검사를 통과하지 못할 경우 ValidationError 예외를 발생 시키는데, DRF에서 제공하는 기본 예외 처리기에 의해 자동 처리되며 기본적으로 HTTP 400 응답을 반환할 수 있다

다음 시간에는 조금 더 심화된 N:1을 DRF에서 다뤄볼 예정이다!

'일상코딩 > 노트' 카테고리의 다른 글

JavaScript : DOM  (1) 2024.04.16
Django : REST API 3  (0) 2024.04.15
Django : REST API 1  (0) 2024.04.11
Django : Many to one relationship  (0) 2024.04.05
DB : SQLite JOIN  (0) 2024.04.04
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함