API
API(Application Programming Interface)는 애플리케이션 시스템을 통합하기 위한 정의 및 프로토콜 세트로, 당사자들 간 계약을 나타내는 documentation으로 비유를 합니다. 웹 API는 일반적으로 Request Message에 HTTP를 사용해 Respose Message의 구조를 정의합니다. 이러한 응답 메시지는 XML 또는 JSON(JavaScript Object Notation)의 형태로 제공됩니다. 해당 방식을 통해서 다른 애플리케이션이 쉽게 조작이 가능합니다. JSON은 이름에도 불구하고 사용 언어와 상관이 없을 뿐 아니라 인간과 기계 모두 read-able 하기 때문에 가장 널리 사용하고 있습니다.
REST(ful)
REST(REpresentational State Transfer)는 웹의 장점을 최대한 활용할 수 있는 네트워크 기반의 아키텍처 중 하나입니다.
API를 개발할 때 REST로 간주되기위해서는 다음과 같은 기준을 만족해야 합니다.
- client-server의 구조를 가짐과 동시에 리소스로 구성을 하며, 요청은 HTTP로 관리되어야 합니다.
- stateless client-server 커뮤니케이션을 지원해야 합니다. (stateless : 요청을 하는 도중 클라이언트 정보가 저장되지 않으며 각 요청이 분리되어 있는 것을 의미합니다. 각 요청이 분리되어있고 서로 연결되어 있지 않음으로써 독립성을 가집니다) HTTP 세션과 같은 콘텍스트 저장소에 저장하지 않는 형태를 의미합니다. 해당 방식을 통해서 API server는 상태 정보 상관없이 들어오는 요청만 처리하면 되기 때문에 구현을 단순하며 명확하게 할 수 있습니다. 클라이언트의 경우 사용자 인증과 콘텍스트 (세션, 로그인 정보)를 관리하는 역할을 가지는 것으로 정립됨에 따라서 클라이언트 / 서버에 있어서 각각의 개발 범위가 명확해졌습니다.
- client-server 상호 작용을 간소화하는 cache-able 데이터가 존재합니다. (HTTP GET method의 경우 가능합니다) HTTP 프로토콜 기반의 LB, SSL뿐 아니라 강력한 기능인 캐싱은 대부분의 서비스에서 60% 이상을 차지하는 Select와 같은 조회성 트렌젝션 (GET)에 대해서 성능 향상을 기대할 수 있게 도와줍니다. REST 컴포넌트가 위치한 서버에 트렌젝션을 발생시키지 않기 때문에 전체 응답 시간과 성능, 서버 자원 사용률을 향상합니다.
- 정보가 표준 형식으로 전송되도록 구성 요소들을 통합하는 인터페이스를 제공해야 합니다.
- 요청한 정보를 검색하는데 관련된 서버(보안, L4 | L7 스위치, 로드 벨런싱 등)의 각 유형을 클라이언트가 볼 수 없도록 계층을 나누는 시스템을 제공해야 합니다.
- code-ondemands(optional) - 요청을 받으면 서버에서 클라이언트로 실행 가능한 코드를 전송해 클라이언트 기능을 확장시킬 수 있습니다.
통합 인터페이스의 경우 4가지 측면을 포함합니다.
- 요청에서 리소스 식별 : 리소스가 요청에서 식별되며 클라이언트로 반환된 표현으로부터 분리됩니다.
- 표현을 통한 리소스 조작 : 클라이언트가 리소스를 나타내는 파일을 수신합니다. 이 표현에는 조작 또는 삭제를 허용할 수 있도록 충반한 양의 정보가 포함되어야 합니다.
- 자기 기술적(Self-descriptive) 메시지 : 클라이언트에 반환되는 각 메시지에 클라이언트가 정보를 처리할 수 있도록 설명해주는 정보가 충분히 포함되어야 합니다. API 메시지 자체만 보더라도 어떤 기능을 할 것이라는 예측을 할 수 있게 도와줍니다. Open API의 경우 대부분 API document를 제공하지만, 해당 제공이 없더라도 직관적인 이해를 할 수 있도록 돕습니다.
- 애플리케이션 상태 엔진으로의 하이퍼미디어 : 리소스를 할당한 이후 REST client가 하이퍼링크를 통해 현재 사용 가능한 기타 모든 작업을 찾을 수 있어야 합니다.
REST의 구성요소
크게 메서드, 리소스, 메시지 3가지 요소로 구성됩니다.
각각의 요소를 통해서 문장을 표현하는 것을 대신할 수 있습니다. "장바구니에 물건을 생성한다."라는 문장은 생성한다(Method: POST) + 장바구니 (Resource: /carts) + 물건 (Message: body: {"id": "33521", "name": "nike free run 4"})로 대체할 수 있습니다. 각 구성요소에 대해서 알아보겠습니다.
(1) 메서드
HTTP POST /categories/:sport
POST라는 '생성한다'라는 의미를 가지는 메서드를 통해서 행위를 설명합니다. REST에서 사용하는 CRUD(Create Read Update Delete)에 해당하는 4가지의 메서드가 존재합니다.
* GET
GET은 Read에 해당하며, 리소스에 대한 정보를 조회하는 것을 의미합니다. 다른 메서드와 다르게, HTTP GET 메서드를 사용할 경우 웹 캐시를 사용해서 성능의 이점을 취할 수 있습니다. 웹 캐시가 자신의 저장소 내에 요청된 리소스를 가지고 있다면, 요청을 가로채서 원래 서버로부터 리소스를 다시 다운로드하는 대신 리소스의 복사본을 반환합니다. 해당 방식을 통해서 서버의 부하를 완화하고, 리소스를 회신하는데 더 적은 시간이 들도록 돕습니다. 모든 리소스가 영원히 변하지 않고 같게 유지되는 것이 아니기 때문에 리소스가 변하기 전까지만 캐싱을 하고 변한 이후 더 이상 캐싱하지 않는 것을 처리해야 합니다.
* POST
POST는 Create에 해당하며, 리소스에 대한 정보를 생성하는 것을 의미합니다. POST 메서드는 멱등성(Idempotency)에 대한 보장이 불가능합니다. 멱등성이란 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미합니다. POST 메서드는 리소스를 추가하는 연산이기 때문에 연산의 적용 결과에 따라서 언제나 다르게 적용됩니다. Idempotency를 보장하지 않는 경우는 트렌젝션 처리에 있어서 신중을 기해야 합니다. 한 트렌젝션에 포함되어 있는 API들 중 일부가 실패한 경우 원복을 하기 위한 작업을 수행할 때 Idempotency를 보장하는 REST API는 다시 실행시키는 것으로 간단하게 처리가 가능하지만, 그렇지 않은 경우는 기존 상태를 저장한 이후 원복을 해 주어야 하기 때문입니다. (POST는 기본적으로 Idempotency를 보장하지 않는 것이지, GET / PUT... 이 언제나 보장을 한다는 것을 의미하는 것은 아닙니다. 특정 글을 읽을 때마다 조회수가 증가하는 로직, 혹은 특정 정보를 변경할 때마다 변경 이력을 남기는 로직이 있다면 해당 API들은 멱등성을 보장할 수 없습니다)
* PUT
PUT는 Update에 해당하며, 리소스에 대한 정보를 변경하는 것을 의미합니다. PUT 메서드와 비슷한 동작을 하는 것으로 PATCH 메서드가 존재합니다. PUT이 해당 자원의 전체를 교체하는 의미를 지니는 대신, PATCH는 일부를 변경하는 의미를 가집니다.
HTTP PUT /categories/:sport/players/:id
상기 API에서 농구(baseball) 선수 중 (23) 번에 해당하는 인원의 이름과 포지션을 바꾸고자 하는 상황이 있을 수 있습니다. 저는 마이클 조던의 팬인데요, 영구 결번임에도 저를 한번 넣어보도록 하겠습니다. 해당 방식을 하기 위해서는 body parameter에 다음과 같은 정보가 들어갑니다.
body:
{
"name": "moonkey",
"position": "forward-center"
}
메서드가 PUT인 경우 이렇게 되면 id 23에 저가 포워드센터로 변경이 됩니다. 그러나 position에 대한 값을 따로 명시하지 않았을 때를 가정했을 때, 마이클 조던의 포지션인 슈팅가드(shooting guard)로 적용되는 것이 아닌, 아예 값이 사라지게 됩니다.
이에 반해서 PATCH 메서드를 사용해서, 이름만 변경하고 싶을 경우, body의 name field만 값을 변경하게 되면 원래 있던 값이 사라지는 것이 아닌 기존의 값으로 유지됩니다. Update라는 행위에 대해서 PATCH가 더 적합한 의미라고 평가받는 경우도 있고 해당 부분을 반영한 것인지 Rails 4부터는 PATCH가 update이벤트의 기본 메서드로 사용할 것이라고 소개하고 있습니다.
* DELETE
DELETE는 Delete에 해당하며, 리소스에 대한 삭제를 하는 기능입니다. GET과 DELETE는 body parameter가 존재하지 않을 수 있습니다. 또한 구형 브라우저가 PUT, DELETE를 제대로 지원하지 못하는 부분이 있기 때문에 해당 부분 확인 이후 사용하는 것이 좋습니다.
※ 잘못된 부분이나 궁금한 점 댓글로 작성해 주시면 최대한 답변하겠습니다. 읽어주셔서 감사합니다.
※ REST API #2 - 개념 정리 (2)에서 리소스와 메시지에 대한 설명으로 이어집니다.
'React > Rest API' 카테고리의 다른 글
REST API #5 - Axios vs Fetch ? (0) | 2021.02.27 |
---|---|
REST API #4 - Axios (2) | 2021.02.08 |
REST API #3 - Fetch (1) | 2021.02.07 |
REST API #2 - 개념 정리 (2) (0) | 2021.01.12 |