Restful API

짱쫑·2021년 12월 22일
0
post-thumbnail

🚶🏻‍♀️ Restful API란?

HTTP 통신에서 어떤 자원에 대한 CRUD 요청을 Resource와 Method로 표현하여 특정한 형태로 전달하는 방식

RESTful API 라는 단어에서 사용되는 REST(REpresentational State Transfer)의 개념을 한줄로 정의하자면 아래와 같이 정의할 수 있다.

즉, REST란 어떤 자원에 대해 CRUD(Create, Read, Update, Delete) 연산을 수행하기 위해 URI(Resource)로 요청을 보내는 것으로, Get, Post 등의 방식(Method)을 사용하여 요청을 보내며, 요청을 위한 자원은 특정한 형태(Representation of Resource)으로 표현된다.

그리고 이러한 REST 기반의 API를 웹으로 구현한 것이 RESTful API인데 예를 들어, 우리는 게시글을 작성하기 위해 http://localhost:8080/board 라는 URI에 POST방식을 사용하여 JSON형태의 데이터를 전달할 수 있다.

위와 같이 CRUD 연산에 대한 요청을 할 때, 요청을 위한 Resource(자원, URI)와 이에 대한 Method(행위, POST) 그리고 Representation of Resource(자원의 형태, JSON)을 사용하면 표현이 명확해지므로 이를 REST라 하며, 이러한 규칙을 지켜서 설계된 API를 Rest API 또는 Restful한 API라고 한다. 그리고 위에서 살짝 언급하였듯이, 이러한 Rest API는 Resource(자원), Method(행위), Representation of Resource(자원의 형태)로 구성된다.

❗️ RESTful API의 구성요소

Resource

서버는 Unique한 ID를 가지는 Resource를 가지고 있으며, 클라이언트는 이러한 Resource에 요청을 보낸다. 이러한 Resource는 URI에 해당한다.

Method

서버에 요청을 보내기 위한 방식으로 GET, POST, PUT, PATCH, DELETE가 있다. CRUD 연산 중에서 처리를 위한 연산에 맞는 Method를 사용하여 서버에 요청을 보내야 한다.

Representation of Resource

클라이언트와 서버가 데이터를 주고받는 형태로 json, xml, text, rss 등이 있다. 최근에는 Key, Value를 활용하는 json을 주로 사용한다.

🚶🏾‍♀️ Rest 디자인 원칙

가장 기본적인 레벨에서 API는 하나의 애플리케이션이나 서비스가 다른 애플리케이션이나 서비스 내의 리소스에 액세스할 수 있도록 해주는 메커니즘이다. 액세스를 수행하는 애플리케이션이나 서비스를 클라이언트라하고, 리소스가 포함된 애플리케이션이나 서비스를 서버라고 한다.

SOAP또는 XML-RPC 등의 일부 API는 개발자에 대한 엄격한 프레임워크를 부과한다. 그러나 REST API는 거의 모든 프로그래밍 언어를 사용하여 개발이 가능하다. 다양한 데이터 포맷을 지원할 수 있고, 유일한 요구사항이 있다면 아키텍처 제한사항으로 알려진 6가지의 REST 디자인 원칙에 맞아야 한다.

:: 균일한 인터페이스 (Uniform Interface)
요청이 어디에서 오는지와 무관하게 동일한 리소스에 대한 모든 API 요청은 동일하게 보여야 한다. REST API는 사용자의 이름이나 이메일 주소 등의 동일한 데이터 조각이 오직 하나의 URI(Uniform Resource Identifier)에 속함을 보장해야 한다. 리소스가 너무 클 필요는 없지만, 클라이언트가 필요로 하는 모든 정보를 포함해야 한다.

:: 클라이언트-서버 디커플링 (Client - Server Decoupling)
Rest API 디자인에서, 클라이언트와 서버 애플리케이션은 서로 간에 완전히 독립적이어야 한다. 클라이언트 애플리케이션이 알아야 하는 유일한 정보는 요청된 리소스의 URI이며 다른 방법으로 서버 애플리케이션과 상호작용할 수 없다. 이와 유사하게 서버 애플리케이션은 HTTP를 통해 요청된 데이터에 전달하는 것 말고는 클라이언트 애플리케이션을 수정하면 안된다.

:: 무상태성 (Stateless)
Rest API는 stateless이다. 각 요청에서 이 처리에 필요한 모든 정보를 포함해야 한다는 말이다. 즉, Rest API는 서버측 세션을 필요로 하지 않는다. 서버 애플리케이션은 클라이언트 요청과 관련된 데이터를 저장할 수 없다.

:: 캐싱 가능성 (Cacheable)
되도록 리소스를 클라이언트 또는 서버측에서 캐싱할 수 있어야한다. 또한 서버 응답에 전달된 리소스에 대해 캐싱이 허용되는지 여부에 대한 정보도 포함되어야 한다. 이 목적은 서버측의 확장성 증가와 함께 클라이언트측의 성능 향상을 동시에 얻는 것이다.

:: 계층 구조 아키텍쳐 (Layered System)
Rest API에서는 호출과 응답이 서로 다른 계층을 통과한다. 일반적인경우 클라이언트와 서버 애플리케이션이 서로 간에 직접 연결된다고 가정하지 말고 통신 루프에는 다수의 서로 다른 중개자가 있을 수 있다. Rest API는 앤드 애플리케이션 또는 중개자와 통신하는지 여부를 클라이언트나 서버가 알 수 없도록 설계돼야 한다.

:: 코드 온 디멘드 (Code on demand - Option)
Rest API는 일반적으로 정적 리소스를 전송하지만 특정한 경우에는 응답에 실행 코드를 포함할 수도 있다. 이러한 경우에 코드는 요청 시에만 실행되어야 한다.

🚶🏻 Rest API 작동 방식

Rest API는 HTTP 요청을 통해 통신함으로써 리소스 내에서 레코드(CRUD)의 작성, 읽기, 업데이트 및 삭제 등의 표준 데이터베이스 기능을 수행한다. 예를 들어, Rest API는 GET 요청을 사용하여 레코드를 검색하고, POST요청을 사용하여 레코드를 작성하며, PUT요청을 사용하여 레코드를 업데이트하고, DELETE요청을 사용하여 레코드를 삭제한다. 모든 HTTP메소드는 API호출에서 사용될 수 있다. 잘 디자인된 Rest API는 HTTP기능이 내장된 웹 브라우저에서 실행되는 웹 사이트와 유사하다.

시간소인 또는 특정 인스턴트의 리소스 상태를 리소스 표현이라한다. 이러한 정보는 JSON(JavaScript Object Notation), HTML, XLT, Python, PHP 또는 일반 텍스트를 포함하여 실제로 거의 모든 형식으로 클라이언트에 전달될 수 있다. JSON은 사람과 기계가 모두 읽을 수 있으므로 인기를 얻었으며, 이는 프로그래밍 언어와 무관한 언어이다.

메타데이터, 권한 부여, URI, 캐싱, 쿠키 등의 중요한 식별자 정보를 포함하므로, 요청 헤더와 매개변수 역시 Rest API 호출에서 중요하다. 요청 헤더와 응답 헤더는 일반적인 HTTP 상태 코드와 함께 잘 디자인 된 Rest API 내에서 사용된다.

🚶🏾‍♀️ Restful API Naming

URI(Uniform Resource Identifier)

  • Uniform: 리소스 식별하는 통일된 방식
  • Resource: 자원, URI로 식별할 수 있는 모든 것(제한 없음)
  • Identifier: 다른 항목과 구분하는데 필요한 정보

URI는 Resource(or Representation)만 식별함
ex) 미네랄을 캐라 -> 미네랄이 리소스, 회원을 등록하고 수정하는 기능 -> 회원이라는 개념 자체가 리소스
최근에는 Resource 대신 Representation 라는 표현을 사용하기 시작했지만 아직 Resource라는 표현을 쓰는 비중이 많으니 이 글에서는 Resource와 Representation를 함께 표기하겠다.

1. 리소스를 표현하기 위해 명사를 사용

Restful URI가 가리키는 resource(or representation)는 수행되는 행위가 아니라 객체다.
이 resource를 네 가지 범주로 나눌 수 있다.
항상 리소스가 어느 범주에 해당하는 지 확인하고, 그 범주에 맞는 네이밍 컨벤션을 일관되게 사용해야 한다.

:: 문서(Document)

  • 단일 개념(파일 하나, 객체 인스턴스, 데이터베이스 row)
  • 단수 사용 (/device-management, /user-management)
http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/{id}
http://api.example.com/user-management/users/admin

:: 컬렉션(Collection)

  • 서버가 관리하는 리소스 디렉터리
  • 서버가 리소스의 URI를 생성하고 관리
  • 복수를 사용하라
  • POST 기반 등록
  • 예) 회원 관리 API
  • 복수 사용 (/users)
http://api.example.com/user-management/users
http://api.example.com/user-management/users/{id}

:: 스토어(Store)

  • 클라이언트가 관리하는 자원 저장소
  • 클라이언트가 리소스의 URI를 알고 관리
  • PUT 기반 등록
  • 예) 정적 컨텐츠 관리, 원격 파일 관리
  • 복수 사용 (/files)
http://api.example.com/files
http://api.example.com/files/new_file.txt

:: 컨트롤 URI 혹은 컨트롤러(Controller)

  • 문서, 컬렉션, 스토어로 해결하기 어려운 추가 프로세스 실행
  • 동사를 직접 사용
  • 예) GET, POST만 사용할 수 있는 HTTP FORM의 경우 컨트롤 URI(동사로 된 리소스 경로)를 사용 ex) /members/delete, /members/new 등
  • 동사 사용 (/checkout, /play 등)
http://api.example.com/cart-management/users/{id}/cart/checkout
http://api.example.com/song-management/users/{id}/playlist/play

2. 핵심은 일관성

일관된 resource (or representation) naming conventions과 URI 형식을 사용하면 모호함이 최소화되고 가독성과 지속성이 극대화된다. 일관성을 위해 다음과 같은 디자인 힌트를 구현할 수 있다.

- 계층 관계 표현을 위해 '/'을 사용

http://api.example.com/device-management
http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices/{id}
http://api.example.com/device-management/managed-devices/{id}/scripts
http://api.example.com/device-management/managed-devices/{id}/scripts/{id}

- 마지막 문자로 '/' 사용 금지

http://api.example.com/device-management/managed-devices/ /* X */
http://api.example.com/device-management/managed-devices /* O */

- 가독성을 위해 '-'를 사용

//More readable
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location
//Less readable
http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation

- '_'(언더스코어) 사용 자제
일부 브라우저나 화면에서는 '_'는 가려질 수 있기 때문에 혼란을 피하기 위해 '-'를 사용

//More readable
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location
//More error prone
http://api.example.com/inventory_management/managed_entities/{id}/install_script_location

- 소문자를 사용
Schem과 HOST에만 대소문자 구별이 없고, 그 외에는 대소문자가 구별된다.
예시의 URL은 대소문자 구별이 없다면 모두 동일한 URL이지만, 1번과 2번은 동일하고 3번은 다르다.

http://api.example.org/my-folder/my-doc //1
HTTP://API.EXAMPLE.ORG/my-folder/my-doc //2
http://api.example.org/My-Folder/my-doc //3

- 파일확장자 사용자제

// X
http://api.example.com/device-management/managed-devices.xml
// O
http://api.example.com/device-management/managed-devices

3. CRUD 함수명 사용 자제

URI는 어떤 동작이 수행되는 지 가리키는 것이 아니라, 리소스를 가리킨다. 리소에 대한 작업은 HTTP Method를 이용하도록 한다.

HTTP GET http://api.example.com/device-management/managed-devices //Get all devices
HTTP POST http://api.example.com/device-management/managed-devices //Create new Device
HTTP GET http://api.example.com/device-management/managed-devices/{id} //Get device for given Id
HTTP PUT http://api.example.com/device-management/managed-devices/{id} //Update device for given Id
HTTP DELETE http://api.example.com/device-management/managed-devices/{id} //Delete device for given Id

4. 필터를 위해 쿼리 파라미터를 사용

Resource에 대한 정렬, 필터링, 페이징은 신규 API를 생성하지 않고 쿼리 파라미터를 활용하라.

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices?region=USA
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date
profile
不怕慢, 只怕站

0개의 댓글