DRF(Django Rest Framework)와 RESTful API

Hansu Kim·2021년 10월 15일
0

Django

목록 보기
8/10

Django의 구조와 단점

Django는 Frontend와 Backend가 합쳐져있는 구조이며, 이 구조는.
아래 2가지 단점을 가지고 있다.

  1. Backend에서의 Response가 HTML 페이지 형식이므로, 매 응답마다 페이지를 새로 그리게(Refresh) 된다.
  2. Backend와 Frontend의 코드를 분리할 수 없다.

그에 따라 최근에는 아래와 같이 FE와 BE를 아예 분리하고 있다.

Backend와 Frontend가 분리된 구조

위와 같은 형태에서 BE의 Response는 Json 형태의 데이터로 전달이 되며, 이러한 구조는 아래 2가지 장점을 갖게 된다.

  1. BE는 Business Logic에만 집중
  2. FE에서 가능한 동작들이 많아진다. (리액트, 뷰, 앵귤러 같은 프레임워크 활용 가능(?))

Django에서는 DRF를 통해 위와 같은 구조를 제공하고 있다.
DRF에서는 RESTful API를 사용하고 있는데, RESTful API란 리소스를 기반으로 디자인된 인터페이스이다.

API
BE와 FE가 분리된 구조에서, FE가 BE에 데이터를 요청하는 인터페이스를 뜻한다.

REST API란

REST는 하이퍼미디어 기반 분산 시스템을 구축하기 위한 아키텍처 스타일이다. REST는 어떤 기본 프로토콜과도 독립적이며 HTTP에 연결될 필요가 없지만, 가장 일반적인 REST API 구현은 응용 프로그램 프로토콜로 HTTP를 사용하며 HTTP용 REST API의 가이드를 따르는 것이다.
REST의 목적이 엔티티와, 애플리케이션이 해당 엔티티에서 수행할 수 있는 작업을, 모델링하는 것이기 때문이다.

HTTP를 사용하는 RESTful API의 기본 디자인 원칙

  • 리소스를 중심으로 디자인한다. (리소스: 클라이언트에서 액세스 가능한 모든 개체/데이터/서비스)
  • 리소스마다 해당 리소스를 식별가능한 URI인 식별자가 있다.
    ex) https://adventure-works.com/orders/1
  • 클라이언트는 JSON형식의 리소스를 교환하며 서비스와 상호작용한다.
  • Stateless 요청 모델을 사용해야 한다.

HTTP와 상태 비저장 요청 모델(Stateless Request Model)
HTTP는 대표적인 상태 비저장 프로토콜이다. 클라이언트는 동일한 HTTP 연결을 통해 여러 요청을 보낼 수 있지만 서버는 각 요청에 대한 연결을 다시 설정하는 데 소비되는 시간,대역폭을 최소화하기 위해서 동일한 소켓을 통해 도착하는 Request들의 순서에 특별한 의미를 부여하지 않는다.
그러므로, HTTP 요청은 서로 독립적이어야 하고, 임의 순서로 발생할 수 있으므로 각 요청이 해당 사항을 이행하기에 충분한 정보를 자체적으로 포함하고 있어야 한다. 이를 상태 비저장(Stateless) 요청 모델이라고 한다.
HTTP는 Stateless 특성으로 인해 웹 서비스 확장성이 뛰어나나, 웹서비스의 데이터가 백엔드 데이터 저장소에 기록되기에, 백엔드 데이터 저장소는 확장이 어렵다는 단점이 있다.

URI
Uniform Resource Identifier. 인터넷에 있는 자원을 나타내는 유일한 주소

리소스를 중심으로 API 디자인 구성

  • 리소스 URI는 동사(리소스에 대한 작업)가 아닌 명사(리소스)를 기반으로 해야 한다.
  • 리소스는 single physical data item을 기반으로 할 필요가 없다. 예를 들어 인터넷 쇼핑몰의 "order" 리소스는 백엔드 내부적으로 여러 Relational Database Table로 구현할 수 있지만 클라이언트에서는 단일 엔티티로 표현된다. 단순히 DB의 내부 구조를 반영하는 API는 지양해야 한다. REST의 목적이 엔티티와 애플리케이션이 해당 엔티티에서 수행할 수 있는 작업을 모델링하는 것이기 때문이다.
  • URI에 일관적인 명명 규칙을 적용하고, 이를 통해 URI에 대해 복수 명사를 사용하여 컬렉션 및 항목에 대한 URI의 계층 구조를 구성한다.
  • 리소스 URI를 컬렉션/항목/컬렉션 보다 더 복잡하게 요구하지 않는 것이 좋다.
  • 웹 서버의 부하 경감을 위해 작은 리소스를 표시하는 번잡한 Web API를 피해야 한다. 즉, 데이터를 비정규화하고 단일 요청을 통해 관련 정보를 검색할 수 있는 더 큰 리소스로 결합하는 것이 바람직하다. 다만 이 방식에서도 클라이언트에 필요없는 정보를 가져오는 오버헤드의 균형을 잘 조정해야 한다.
/customers : 고객 컬렉션의 경로
/customers/5 : ID가 5인 고객의 경로
/customers/5/orders : 고객 5에 대한 모든 주문
/orders/99/customer : 윗 항목의 반대방향으로, 주문에서 고객으로의 연결 표시
	-> 이런 방식은 지양해야 한다. 해당 방식으로 모델이 너무 많이 확장되면 구현이 어려워지기 때문. 이 매커니즘은 HATEOAS를 사용하여 HTTP Response의 본문에 연결된 리소스에 탐색 가능한 링크를 제공하는 방식으로 구현하는 것이 더 좋다.

HTTP 메서드를 기준으로 API 작업 정의

The HTTP protocol defines a number of methods that assign semantic meaning to a request. The common HTTP methods used by most RESTful web APIs are:

  • GET 은 지정된 URI에서 리소스의 표현을 검색합니다. 응답 메시지의 본문은 요청된 리소스의 세부 정보를 포함하고 있습니다.
  • POST 는 지정된 URI에 새 리소스를 만듭니다. 요청 메시지의 본문은 새 리소스의 세부 정보를 제공합니다. 참고로 POST를 사용하여 실제로 리소스를 만들지 않는 작업을 트리거할 수도 있습니다.
  • PUT 은 지정된 URI에 리소스를 만들거나 대체합니다. 요청 메시지의 본문은 만들 또는 업데이트할 리소스를 지정합니다.
  • PATCH 는 리소스의 부분 업데이트를 수행합니다. 요청 본문은 리소스에 적용할 변경 내용을 지정합니다.
  • DELETE 는 지정된 URI의 리소스를 제거합니다.

The effect of a specific request should depend on whether the resource is a collection or an individual item. The following table summarizes the common conventions adopted by most RESTful implementations using the e-commerce example.

HTTP 메서드를 기준으로 API 작업 정의 예시
리소스 POST GET PUT DELETE
/customers 새 고객 만들기 모든 고객 검색 고객 대량 업데이트 모든 고객 제거
/customers/1 Error 고객 1에 대한 세부 정보 검색 고객 1이 있는 경우 고객 1의 세부 정보 업데이트 고객 1 제거
/customers/1/orders 고객 1에 대한 새 주문 만들기 고객 1에 대한 모든 주문 검색 고객 1의 주문 대량 업데이트 고객 1의 모든 주문 제거

POST, PUT, PATCH의 차이점

POST, PUT 및 PATCH의 차이점을 구분하기 어려울 수 있습니다.

  • POST 요청은 리소스를 만듭니다. 서버는 새 리소스에 대한 URI를 할당하고 클라이언트에 해당 URI를 반환합니다. REST 모델에서는 컬렉션에 POST 요청을 자주 적용합니다. 새 리소스가 컬렉션에 추가됩니다. POST 요청은 새 리소스를 만들지 않고 기존 리소스에 처리할 데이터를 보내는데 사용할 수도 있습니다.

  • PUT 요청은 리소스를 만들거나 또는 기존 리소스를 업데이트합니다. 클라이언트는 리소스의 URI를 지정합니다. 요청 본문에는 리소스의 완전한 표현이 포함됩니다. 이 URI를 사용하는 리소스가 이미 있으면 리소스가 대체됩니다. 아직 없고 서버에서 리소스 만들기를 지원하는 경우 새 리소스가 생성됩니다. PUT 요청은 컬렉션보다는 특정 고객 같은 개별 항목인 리소스에 가장 자주 적용됩니다. 서버에서 PUT을 통한 업데이트를 지원하지만 만들기는 지원하지 않을 수 있습니다. PUT을 통한 만들기 지원 여부는 리소스가 존재하기 전에 클라이언트가 의미 있는 방법으로 리소스에 URI를 할당할 수 있는지 여부에 따라 결정됩니다. 할당할 수 없는 경우 POST를 사용하여 리소스를 만들고 PUT 또는 PATCH를 사용하여 업데이트합니다.

  • PATCH 요청은 기존 리소스에 부분 업데이트 를 수행합니다. 클라이언트는 리소스의 URI를 지정합니다. 요청 본문은 리소스에 적용할 변경 내용 을 지정합니다. 클라이언트가 리소스의 전체 표현이 아닌 변경 내용만 보내기 때문에 PUT을 사용하는 것보다 이 방법이 더 효율적일 수 있습니다. 또한 서버에서 리소스 만들기를 지원하는 경우 기술적으로 PATCH는 새 리소스를 만들 수 있습니다("null" 리소스에 대한 업데이트를 지정하여).

  • PUT 요청은 idempotent여야 합니다. 클라이언트가 동일한 PUT 요청을 여러 번 제출하는 경우 그 결과가 항상 같아야 합니다(같은 값을 사용하여 같은 리소스가 수정되므로). POST 및 PATCH 요청이 반드시 idempotent가 된다는 보장은 없습니다.

참고 URL Microsoft Azure Document 중 API-Design에 관해..
https://docs.microsoft.com/ko-kr/azure/architecture/best-practices/api-design
https://www.django-rest-framework.org/

0개의 댓글