Rest는 REpresentational State Transfer 의 약자로 클라이언트와 서버가 데이터를 주고받는 방식에 관한 아키텍처 스타일이다.
REST 는 가상머신간의 호출에 있어서 Remote Procedure Call (RPC), Common Object Request Broker Architecture (CORBA), Simple Object Access Protocol (SOAP) 같은 복잡한 기술대신 간단한 HTTP 를 사용하고자 하는 아이디어에서 만들어졌다.
REST 는 자신만의 원칙과 제약조건들이 있는데 특정 서비스 인터페이스가 RESTful 하다고 말하기 위해선 이 원칙들이 지켜져야 한다.
REST 아키텍처 스타일을 따르는 Web API 를 REST API 라고 부른다.
RPC
: 프로그램이 원격 서버의 기능이나 프로시저를 마치 로컬인 것처럼 실행하여 분산 컴퓨팅을 용이하게 하는 통신 프로토콜
CORBA
: 다양한 프로그래밍 언어와 플랫폼에 걸쳐 분산된 개체 간의 상호 운용성을 가능하게 하는 미들웨어 기술
SOAP
: 웹 서비스 구현 시 구조화된 정보를 교환하기 위한 프로토콜로 메시지 형식으로 XML 을 활용하고 서로 다른 시스템 간의 통신을 허용한다.
REST 는 반드시 지켜야 하는게 아니다! 그보단 인터넷 기반 컴퓨터 시스템간의 상호운용성을 보장하기 위한 아키텍처 스타일이다.
일관된 규칙을 인터페이스에 적용하여 시스템 아키텍쳐 전반을 단순화하고 상호작용의 가시성을 향상시킬 수 있다.
제약조건
Identification of resources
: 각 리소스는 유일하게 식별 가능해야 한다.
=> 리소스가 URL 로 식별되어야 한다.
Manipulation of resources through representations
: 리소스는 서버 응답에서 균일하게 표현되어야 한다. API 소비자는 이 표현들을 사용해서 서버의 리소스 상태를 수정한다.
=> 리소스를 삭제, 수정, 입력시 HTTP 메시지에 표현을 담아 전송한다.
Self-descriptive messages
: 각 리소스 표현은 메시지 전달에 대한 충분한 정보와 이 리소스에 대해 할 수 있는 추가적인 작업에 대한 정보를 제공해야 한다.
=> 메시지만 봐도 무슨 리소스인지 해석할 수 있어야 한다.
Hypermedia as the engine of application state(HATEOAS)
: 하이퍼미디어를 애플리케이션의 상태를 관리하기 위한 메커니즘으로 사용한다. REST Api 를 사용하는 클라이언트가 전적으로 서버와 동적인 상호작용이 가능하도록 해야 한다.
=> 링크를 써서 페이지를 이동
Uniform Interface 는 중요하니 조금 더 자세히 알아봤다.
먼저 시중 사이트중에 http 를 아직도 사용중인 사이트를 찾아봤다.
요즘은 보안문제로 인해 대부분 https 를 사용하는 것 같은데 다행히 금방 찾을 수 있었다.
저 사이트에 들어가보고 개발자모드를 켜서 네트워크 - 헤더 - 요청헤더를 자세히 살펴볼 수 있다.
HTTP 헤더
: 클라이언트와 서버가 요청 / 응답으로 부가적인 정보를 전송하는 HTTP 메시지를 말하며 대소문자를 구분하지 않는 이름과 콜론, 값으로 구성된다. 쿠키, 세션방식의 인증을 사용시 토큰을 헤더에 담아 전달한다.
먼저 다음과 같은 메시지가 있을때 메시지만 보고 어떤 리소스를 전달하는지 해석할 수 있을까?
GET /yes24 HTTP/1.1
위와 같은 메시지만 있다면 무엇에 관한 것인지 알기 어렵다.
그래서 Host 를 추가해서 메시지가 gmarket 을 향한 것임을 알려준다.
GET /yes24 HTTP/1.1
Host: minishop.gmarket.co.kr
이런 식으로 HTTP 메시지만 봐도 어떤 내용인지, 어떤 리소스인지, 무엇을 담고 있는지 등에 대해 알 수 있어야 한다. 이러한 REST 제약 조건을 지킨 아키텍처 스타일을 REST 라고 하며 이러한 API 를 RESTful API 라고 한다.
클라이언트 서버 디자인 패턴은 사용자 인증, context (세션, 로그인 정보) 등을 관리하는 유저 인터페이스 client
와 데이터 저장소와 관련되어 있고 API 제공, 비즈니스 로직 처리 및 저장을 책임지는 server
를 분리시켜 서로간 의존성을 줄이고 독립적으로 발전하도록 한다.
HTTP 프로토콜은 stateless protocol 이라 REST 도 무상태성을 갖는다.
클라이언트에서 서버로의 각 요청은 반드시 요청을 완전히 완료하고 이해하기 위해 필요한 모든 정보를 포함해야 한다.
서버는 이전에 저장된 컨텍스트 정보의 이점을 취할 수 없다. 이런 이유로 클라이언트 앱은 반드시 세션 상태를 전적으로 유지해야 한다.
서버는 각각의 요청을 별개의 것으로 인식하고 처리한다.
응답은 반드시 암묵적이거나 명시적으로 캐시 처리 가능여부를 나타내야 한다. 캐시처리가 가능할 경우 클라이언트 앱은 응답 데이터를 이후 동일한 요청과 특정 기간동안 재사용할 권리를 갖게 된다.
구성 요소 동작을 제한하여 아키텍처가 계층적 구조로 구성되도록 한다.
REST 는 applet 이나 script 형태의 코드를 받아서 클라이언트에서 실행할 수 있다.
이름이 지정될 수 있는 모든 정보를 리소스라고 할 수 있다. 예를 들어 문서, 이미지, 일싲거 서비스 등이 될 수 있다.
자원은 데이터, 데이터를 설명하는 metadata, 클라이언트가 다음 상태로 전환되는데 도움이 될 hypermedia link 등을 포함한다.
예를 들어 users
는 복수형 리소스이고 user
는 단수형 리소스다.
만약 유저를 생성하거나 특정 유저를 조회하는 API 를 어떻게 구성해야 할까?
일반적으로 사용자는 다른 대상, 이 예시에선 다른 포스트가 존재하는지 여부를 알 수 없기에 https://mysite.com/post/1
보다는 https://mysite.com/posts/1
와 같이 복수 명사를 사용하는 것이 권장된다.
stackoverflow 에서도 코드에 대응하는 방식을 생각해 보라는 글이 있었다.
유저를 생성하는 것은 유저 배열에 하나의 유저를 추가하는 것이니 POST /users
가 적절해 보인다.
유저를 조회하는 것도 유저 배열중 하나의 유저를 조회하는 것이니 GET /users/:id
가 자연스럽다.
필수적으로 지켜야하는 것은 아니나 단수와 복수를 혼합해서 사용시 기준이 없어지거나 헷갈릴 수 있으니 한가지 방식을 사용하는게 더 적절하며 그렇다면 그중에서도 복수형 리소스를 사용하는 것이 더 바람직해 보인다.
복수 명사를 사용하자.
REST API 네이밍시 동사보다 명사를 사용하는 것이 권장된다. HTTP 에선 HTTP 메소드가 이미 GET
, PUT
, PATCH
, DELETE
라는 동작을 CRUD (Create
, Read
, Update
, Delete
) 동사의 형태로 나타낸다.
따라서 다음과 같은 형태로 사용하는 것이 적절해 보인다.
GET /getPosts --> GET /posts
POST /createPost --> POST /posts
GET /getPostById/1 --> GET /posts/1
/device-management/managed-devices
/device-management/managed-devices/{device-id}
/user-management/users
/user-management/users/{id}
HTTP 메소드로 엔드포인트가 무슨 일을 할지 나타내기에 동사 대신 명사를 사용하자
API 요청에 응답시 항상 상태 코드를 포함해야 사용자가 요청이 성공했는지, 실패했는지 알 수 있다.
정보 응답
ex) 102 는 리소스가 진행중임을 나타낸다.Redirect
ex) 301 은 리소스가 영구적으로 이동 페이지로 이동되었음을 의미한다.클라이언트 측 에러
ex) 400 은 요청이 잘못되었다는 것을 말하고 404 는 리소스를 찾을 수 없음을 나타낸다.서버 측 에러
ex) 500 은 내부 서버 에러를 말한다.예를 들어 다수의 사용자가 사용하는 블로그 플랫폼에서 여러 게시물은 각각 다른 사용자들에 의해 작성된다.
/posts/author
이와 같이 게시물들은 각각의 댓글들을 갖고 있다.
/posts/postId/comments
그러나 3단계 이상 중첩시 가독성이 떨어지므로 너무 많이 중첩하지 않는 것을 권장한다.
URL vs URI
URI, Uniform Resource Identifier
: 식별자, 자원 자체를 식별한다.지도
,naver.com
URL, Uniform Resource Locator
: 식별자 + 위치, 웹 사이트 주소뿐 아니라 위치를 동시에 보여준다.지도, 좌표
https://naver.com
막대한 양의 데이터를 가져오는 경우 느려질 수 있다. 그러니 REST API 는 미리 분류하여 일부 데이터만 가져오도록 할 수 있다.
/posts?tags=javascript
REST API 는 여러 버전을 지원하여 사용자들이 최신 버전이 아니더라도 사용할 수 있게 해야 한다. 가장 흔히 버전을 관리하는 방법은 Semantic Versioning 이다.
2.1.2
첫 번째 숫자 : 주 버전
두 번째 숫자 : 부 버전
세 번째 숫자 : 패치 버전
mysite.com/v1
/device-management
/device-management/managed-devices
/device-management/managed-devices/{id}
/device-management/managed-devices/{id}/scripts
/device-management/managed-devices/{id}/scripts/{id}
http://api.example.com/devicemanagement/manageddevices/
http://api.example.com/device-management/managed-devices /*This is much better version*/
폰트에 따라 밑줄은 보기 어려울 수 있다. 가독성을 위해 밑줄을 사용하지 말자
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //More readable
http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation //Less readable
편의를 위해 URI 경로에 소문자를 사용하자
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
/device-management/managed-devices.xml /*Do not use it*/
/device-management/managed-devices /*This is correct URI*/
URI 는 오직 유일하게 리소스를 식별하기 위해 사용하지 동작을 식별하기 위해 사용하는 것이 아니다.
HTTP GET /device-management/managed-devices //Get all devices
HTTP POST /device-management/managed-devices //Create new Device
HTTP GET /device-management/managed-devices/{id} //Get device for given Id
HTTP PUT /device-management/managed-devices/{id} //Update device for given Id
HTTP DELETE /device-management/managed-devices/{id} //Delete device for given Id
/device-management/managed-devices
/device-management/managed-devices?region=USA
/device-management/managed-devices?region=USA&brand=XYZ
/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date
document
이름으로 단수 명사를 사용한다.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
이름으로 복수 명사를 사용한다./device-management/managed-devices
/user-management/users
/user-management/users/{id}/accounts
store
이름으로 복수 명사를 사용한다./song-management/users/{id}/playlists
RESTful 은 이해하기 쉽고 사용하기 쉬운 REST API 를 만드는 것이 목적이다. 성능 향상보다는 일관적인 컨벤션으로 API 의 이해도, 호환성을 높이는 것을 목표로 한다.
blog
joomn11 - REST Api (Hateoas)
팀드모네 IT Blog - REST 제약조건
하나몬 - REST API란?
호박너구리 블로그 - REST API 컨벤션
docs
restfulapi.net - REST
restfulapi.net - resource naming
meta for developers - Graph API Reference
google cloud - 이름 지정 규칙
reference
gearheart - REST API
freecodecamp - REST Endpoint Design Examples
잘 참고하겠습니다 좋은 내용 감사합니다 😁