티스토리 뷰
2019/07/22 - [Django] - REST API 이용하기
HTTP Method
요청 목적 |
HTTP Method |
SQL |
새로운 리소스 생성 |
POSTa |
INSERT |
리소스 읽기 |
GET |
SELECT |
리소스의 메타데이터 요청 |
HEAD |
|
리소스 데이터 업데이트 |
PUT |
UPDATE |
리소스의 부분 변경 |
PATCH |
UPDATE |
리소스 삭제 |
DELETE |
DELETE |
특정 URL에 대해 지원되는 HTTP 메서드 출력 |
OPTIONS |
|
요청(requests)에 대한 반환 에코 |
TRACE |
|
TCP/IP 터널링(일반적으로 구현되어 있지는 않음) |
CONNECT |
-
read-only API만 구현하다면 GET method만 구현
-
read-write API를 구현한다면 최소한 POST 메서드는 구현해야 하며 PUT과 DELETE 또한 고려
-
단순화하기 위해 때때로 REST API는 GET과 POST만으로 구현되도록 설계
-
GET, PUT, DELETE는 여러 번 실행해도 그 결과과 변하지 않는 멱등(idempotent)관계이며 POST와 PATCH는 그렇지 않다.
-
PATCH가 구현되어 있지 않은 경우도 있다. 하지만 API가 PUT 요청을 지원 한다면 PATCH 또한 구현하는 것이 좋다
-
django-rest-frameworks와 django-tastypie는 앞의 모든 경우를 처리한다.
HTTP 상태 코드
HTTP 상태 코드 |
성공/실패 |
의미 |
200 OK |
Success |
GET - 리소스 반환 PUT - 상태 메시지 제공 또는 리소스 반환 |
201 Created |
Success |
POST - 상태 메지시 반환 또는 새로 생성된 리소스 반환 |
204 No Content |
Success |
DELETE - 성공적으로 삭제된 요청의 응답 |
304 Unchanged |
Redirect |
ALL - 이전 요청으로부터 아무런 변화가 없음을 나타낸다. 성능 개선을 위해 마지막으로 수정된 리소스나 Etag 헤더를 확인하기 위해 이용한다. |
400 Bad Request |
Failure |
ALL - 폼 검증 에러를 포함한 에러 메시지 반환 |
401 Unauthorized |
Failure |
ALL - 인증 요청을 했으나 사용자가 인증 요건을 제공하지 않음 |
403 Forbidden |
Failure |
ALL - 사용자가 허용되지 않은 콘텐트로 접근을 시도함 |
404 Not Found |
Failure |
ALL - 리소스 없음 |
405 Method Not Allowed |
Failure |
ALL - 허가되지 않은 HTTP 메서드로 시도됨 |
410 Gone |
Failure |
ALL - 더는 제공되지 않는 메서드로 호출. 새 버전의 API를 제공하기 위해 기존 API 서비스를 중지할 때 이용된다. 모바일 애플리케이션의 경우 해당 결과에 대대 사용자에게 애플리케이션 업그레이드를 요청하는 방법을 쓰기도 한다. |
429 Too Many Requests |
Failure |
ALL - 제한 시간 내에 너무 많은 요청을 보냄. 접속 제한(rate limit)을 이용할 때 쓰인다. |
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
List of HTTP status codes - Wikipedia
This is a list of Hypertext Transfer Protocol (HTTP) response status codes. Status codes are issued by a server in response to a client's request made to the server. It includes codes from IETF Request for Comments (RFCs), other specifications, and some ad
en.wikipedia.org
REST API 아키텍처
-
프로젝트 코드들은 간결하게 정리되어 있어야 한다.
-
앱의 코드는 앱 안에 두자
-
비즈니스 로직을 API 뷰에서 분리하기
- API URL을 모아 두기
- API 테스트하기
- API 버저닝하기
외부 API 중단하기
- 사용자들에게 서비스 중지 예고하기
- 410 에러 뷰로 API 교체하기
API에 접속 제한하기
- 제한 없는 API 접속은 위험하다
- REST 프레임워크는 반드시 접속 제한을 해야만 한다
- 비즈니스 계획으로서의 접속 제한
http://www.django-rest-framework.org/
www.django-rest-framework.org
https://django-tastypie.readthedocs.io/en/latest/
django-tastypie.readthedocs.io
https://django-braces.readthedocs.io/en/latest/index.html
django-braces.readthedocs.io
https://github.com/jsocol/django-jsonview
jsocol/django-jsonview
Return Python objects, always get JSON. Contribute to jsocol/django-jsonview development by creating an account on GitHub.
github.com
테스트 하기
import json
from django.urls import reverse
from django.test import TestCase
from flavors.models import Flavor
class FlavorAPITests(TestCase):
def setUp(self):
Flavor.objects.get_or_create(title="A Title", slug='a-slug')
def test_list(self):
url = reverse("flavor_object_api")
response = self.client.get(url)
self.assertEquals(response.status_codde, 200)
data = json.loads(response.content)
self.assertEquals(len(data), 1)
import json
from django.urls import reverse
from django.test import TestCase
from flavors.models import Flavor
class DjangoRestFrameworkTests(TestCase):
def setUp(self):
Flavor.objects.get_or_create(title="title1", slug="slug1")
Flavro.objects.get_or_create(title="title2", slug="slug2")
self.create_read_url = reverse("flavor_rest_api")
self.read_update_delete_url = reverse("flavor_rest_api", kwargs={"slug": "slug1"})
def test_list(self):
response = self.client.get(self.create_read_url)
self.assertContains(response, "title1")
self.assertContains(response, "title2")
def test_detail(self):
response = self.client.get(self.read_update_delete_url)
data = json.loads(response.content)
content = {"id": 1, "title": "title1", "slug": "slug1", "scoops_remaining": 0}
def test_create(self):
post = {"title": "title3", "slug": "slug3"}
response = self.client.post(self.create_read_url, post)
data = json.loads(response.content)
self.assertEquals(response.status_code, 201)
content = {"id": 3, "title": "title3", "slug": "slug3", "scoops_remaining": 0}
self.assertEquals(data, content)
self.assertEquals(Flavor.objects.count(), 3)
def test_delete(self):
response = self.client.delete(self.read_update_delete_url)
self.assertEquals(response.status_code, 204)
self.assertEquals(Flavor.objects.count(), 1)
Django REST Framework 3.9 -- Classy DRF
What is this? Django REST framework is a powerful and flexible toolkit that makes it easy to build Web APIs. It provides class based generic API views and serializers. We've taken all the attributes and methods that every view/serializer defines or inherit
www.cdrf.co
https://martinfowler.com/articles/microservices.html
Microservices
An in-depth description of the microservice style of architecture. Applications designed as suites of independently deployable services, governed in a decentralized manner.
martinfowler.com
https://en.wikipedia.org/wiki/Representational_state_transfer
Representational state transfer - Wikipedia
From Wikipedia, the free encyclopedia Jump to navigation Jump to search Software architectural style that defines a set of constraints to be used for creating Web services Representational State Transfer (REST) is a software architectural style that define
en.wikipedia.org
https://jacobian.org/2008/nov/14/rest-worst-practices/
REST worst practices | Jacob Kaplan-Moss
REST worst practices A few weeks ago, I sent the following in a email to a co-worker asking for input on designing REST APIs in Django. Since then, I’ve quoted myself a few times; I thought these thoughts would be worth a (slightly edited) public home. I t
jacobian.org
싱글 페이지 애플리케이션 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 싱글 페이지 애플리케이션(single-page application, SPA, 스파)은 서버로부터 완전한 새로운 페이지를 불러오지 않고 현재의 페이지를 동적으로 다시 작성함으로써 사용자와 소통하는 웹 애플리케이션이나 웹사이트를 말한다. 이러한 접근은 연속되는 페이지들 간의 사용자 경험의 간섭을 막아주고 애플리케이션이 더 데스크톱 애플리케이션처럼 동작하도록 만들어준다. SPA에서 HTML, 자바스크립트, CSS 등 필요한
ko.wikipedia.org
'Django' 카테고리의 다른 글
Django Utils (0) | 2019.08.23 |
---|---|
REST API 이용하기 (0) | 2019.07.22 |
queryset (0) | 2019.07.15 |
Angular4 (0) | 2019.07.14 |
Class ListView() (0) | 2019.07.13 |