RESTful API 정리하기 [TIL / 네트워크]

알락·2022년 12월 18일
1

네트워크

목록 보기
1/3

network banner

취업 공고 중 요건을 확인하다보면, RESTfull API 개발 경험을 요구하는 것을 몇 번 본 적이 있다. 그리고 개발하는 중에도, 서버 요청에 대한 라우팅을 만들어주면 뭔가 체계적인 정리가 필요하다는 생각이 들 때도 있다. REST 개념이 이와 관련되어 있는 것 같아서 한 번 정리해본다.


REST

REST는 하이퍼미디어 기반 분산 시스템을 구축하기 위한 아키텍처 스타일입니다.
-마이크로소프트: RESTful 웹 API 디자인 중

REpresentational State Transfer 을 축약하면 REST가 된다. REST는 어떻게 서버에 요청되는 URI path를 라우팅할지에 대해서만 가이드라인을 제시하는 것이 아니다. REST는 웹 생태계에서 구현되는 서비스에 적용 가능한 하나의 아키텍쳐다.

⌞ State Transfer

월드 와이드 웹(World Wide Web 🌎, 이하 웹)을 이용하여 통신을 하게되면 보통 클라이언트와 서버의 구조로 상호작용하게 된다. 클라이언트는 요청하고, 서버는 응답을 하는 것이다.

그리고 이런 웹의 특징은 Stateless하다는 것이다. 이는 서버가 클라이언트의 상태 정보를 보관하고 있지 않다는 것이다. 이를 해결하기 위해 보통은 클라이언트에서 쿠키나 세션을 이용하기도 한다.

State Transfer의 뜻을 직역해보자면 "상태 전송"이 되겠다. 클라이언트가 요청을 했을 때, 서버는 해당 요청이 필요로 하는 자원의 현 상태를 전송한다.

그럼 미리 살펴본 StatelessState Transfer가 충돌되는 것처럼 느껴진다. 클라이언트나 서버는 상태를 간직하지 않다고 했는데, 서버에서 전송한 자원의 현 상태는 상태가 아닌걸까? 사실 Stateless의 상태와 State Transfer의 상태는 서로 다른 것을 의미한다. 전자의 상태는 클라이언트가 현재 어떤 상태인지에 대한 정보이고, 후자의 상태는 클라이언트가 요청한 자원의 상태 정보이다.

⌞ REpresentational

State Transfer를 더 세밀하게 설명해주는 문구다. 직역해보자면 "표현적인" 내지 "표현하는"이 될 것이다.

"Representational"을 설명하려면 먼저 로이 필딩 논문의 REST에 대한 설명 중, Data Element들을 살펴보는 게 좋다. 특히 그 중 resourcerepresentation 개념을 이해해보면 이해하기 쉽다.

resource에 대해서는 Any information that can be named can be a resource라고 설명한다. 대표적인 예시로도 the intended conceptual target of a hyptertext reference라고 소개한다.
그래서 나는 먼저 웹 초창기 1.0 시절 때, URL을 통해서 정적인 문서를 요청해 오는 것을 떠올려봤다. 이 상황에서 나는 해당 문서를 resource라고 얘기할 것이다.
하지만 라우팅을 하고, 해당 문서의 위치가 아닌, 별도의 URI로 해당 문서를 요청한다면 이번에도 해당 문서를 나는 resource라고 얘기할 것이다. 이 정도로 이해했다.

representation에 대해서는 이렇게 설명한다.

REST components perform actions on a resource by using a representation to capture the current or intended state of that resource and transferring that representation between components.
-Architectural Styles and the Design of Network-based Software Architectures 중

핵심만 이해해 봤을 때 요청된 resource의 현 상태나 서비스가 의도한 상태로 전해지는 데이터를 의미한다고 생각한다. 논문의 예시로 이해를 돕자면, HTML document,JPEG image가 이에 해당한다.

철학적으로 이해해보자면, resource가 이데아💡, 그리고 representation이 형상🖼이라고 이해해 볼 수 있겠다.


REST 특징

다른 곳에서는 REST constraints를 REST 제약이라고 하는데, 여기서는 특징이라 해석하려고 한다. REST가 되기 위한 특징은 다음과 같다.

1. Client-Server

Client는 유저 인터페이스, Server는 데이터 스토리지에만 각자의 관심사를 분리시키기 위한 조건이다. 이를 통해 다양한 플랫폼에서 유저 인터페이스의 이식성이 좋아지고, 서버 구현을 간단하게 만들어 확장성을 높일 수 있다는 장점이 있다.

2. Stateless

Client와 Server 양 측의 통신 중에는 서로의 상태에 대한 정보를 보관하고 있지 않다는 특징이다. 논문에서는 이 특징이 가시성과, 신뢰성, 그리고 확장성을 높일 수 있다고 전한다.

우선, 상대방의 한 요청에 대해서 전후로 있을 전체적인 요청의 맥락을 따져볼 필요가 없다는 점에서 가시성 증진의 효과를 설명한다.
그리고 신뢰성에 대해서는, 상태 정보를 보관하고 있지 않음으로써 보관하고 있을 때 생기는 복잡한 문제들에서 벗어날 수 있다는 점을 든다.
확장성에서는, 서버가 클라이언트의 상태 정보를 저장하지 않음으로써 사용 가능한 자원이 생긴다는 것을 얘기한다.

3. Cache

Stateless를 채택하다보니 그로 인해서 생기는 단점들이 있다. 사용 빈도가 많은 요청이나 응답이 매번 새롭게 행해진다는 것이다. 어떤 요청에 대해서 응답에 cacheable 하다는 신호를 포함시킨다면 이후 똑같은 요청이 일어났을 때는 응답이 Cache에 저장되어서 클라이언트의 입장에서는 요청에 대한 응답 지연시간이 줄어들게 된다. 서버 입장에서는 매번 새로운 응답을 할 필요 없기 때문에 서버의 자원을 효율적으로 사용할 수 있게 된다.

4. Uniform Interface

이에 대해서는 API 구현 가이드라인과 맥락이 비슷하기 때문에, 아래에서 더 자세히 다룰 예정이 참고하기 바란다. Uniform Interface은 특히 다른 네트워크 아키텍쳐하고 REST를 구분할 수 있는 특징이라고 논문에서 소개한다. 이는 REST를 사용하는 네트워크의 구조를 간단하고 파악하기 쉽게 만든다. 하지만 이는 효율적인 인터페이스와는 다소 멀어질 수 있다.

[Uniform Interface 조건]

  • Identification of resource
  • Manipulation of resources through representations
  • Self-descriptive messages
  • Hypermedia as the engine of application state

5. Layered System

Layered System example

위의 그림을 보면 이해하기 쉽다. Layered System은 REST 네트워크를 구성하는 요소들이 계층적으로 연결되어질 수 있다는 것이다. 이 방식을 채택하면, 레거시 서비스를 은닉할 수 있고 레거시 클라이언트에 제공되기 어려운 서비스의 제공을 막기 수월하다. 클라이언트와 서버 사이에 로드 밸런싱과 같은 역할을 맡는 중재자가 개입되어 서비스의 가용성을 높일 수 있다. 대신 클라이언트의 입장에서는 데이터가 여러 단계를 통해 전해지기 때문에 지연시간이 길어질 수 있다는 단점이 있다.

6. Code-On-Demand(Optional)

클라이언트 요청에 대해서 서버가 클라이언트에서 사용 가능한 코드를 전송할 수 있다는 부분인데, 사실 이 부분은 이해가 덜 되어서 추후에 필요하면 수정하도록 하겠다.


RESTful API

이 부분은 위에서 REST의 특징으로 소개했던 Uniform Interface의 일환이다. "RESTful" 하다는 것은 REST를 따르는 서비스라는 뜻이고, "RESTful API"는 REST를 따르는 서비스가 구현하는 Uniform Interface 라고 이해했다.

⌞ 성숙도 모델

Web API에 대해서 얼마나 따르고 있는지에 대해서 Leonard Richardson가 제안한 모델이다.

  • 수준 0: 한 URI를 정의한다. 모든 작업은 이 URI에 대한 POST 요청이다.
  • 수준 1: 개별 리소스에 대한 별도의 URI를 만든다.
  • 수준 2: HTTP 메서드를 사용하여 리소스에 대한 작업을 정의한다.
  • 수준 3: 하이퍼미디어(HATEOAS, 아래에 설명)를 사용한다.

마이크로소프트에서 제공하는 RESTful API 문서에서는 많은 서비스들이 수준 2에 해당하는 API를 제공하고 있다고 얘기한다.

⌞ API 설계 규칙

- 리소스 중심 URI 작성

  • 리소스 URI는 동사가 아니라 명사의 사용을 권장한다.
    ex) example.com/request -> example.com/customer
  • 데이터 집합을 표현할 때는 복수 명사를 이용한다.
    ex) example.com/customers
  • 한 레코드에 대한 데이터를 표현할 때는 단수 명사를 이용하며, 특정 지을 수 있는 식별자로 구분한다.
    ex) example.com/customer/1

- HTTP 메소드 활용

  • URI에 직접적으로 메소드를 넣지 않는다.
    ex) example.com/get/customers (X)

  • 메소드 헤더를 통해서 리소스에 행하는 작업을 지시한다.
    [메소드 활용 정리 표]

    메소드설명적용사례
    GET리소스 집합이나 단일 데이터를 요청할 때 쓴다.GET example.com/customers
    POST리소스를 추가 생성할 때 사용한다.POST example.com/customers
    PUT리소스를 일체로 수정할 때 사용한다.PUT example.com/customer/:id
    PATCH리소스의 특정 부분을 수정할 때 사용한다.PATCH example.com/customer:id
    DELETE리소스를 삭제할 때 사용한다.DELETE example.com/customer/:id

    [메소드 별 status code 정리 ]

    메소드성공실패
    GET- 200 반환
    - 204(컨텐츠 없음) 반환
    - 404(찾을 수 없음) 반환
    POST- 201(만들어짐) 반환
    - 204(컨텐츠 없음) 반환
    - 400(잘못된 요청) 반환
    PUT- 200 or 204 반환
    - 201(컨텐츠 생성) 반환
    - 기존 리소스를 업데이트할 수 없는 경우 409(충돌) 반환
    PATCH-200 or 204 반환- 415(지원하지 않는 미디어 형식) 반환
    - 400(형식 오류) 반환
    - 409(유효한 입력, 리로스 적용 불가) 반환
    DELETE-204 반환- 404(찾을 수 없음) 반환

- 데이터 필터링 및 페이징

  • URI 쿼리를 이용한다.
    ex) example.com/customers?age=20&limit=0&offset=20

참고

profile
블록체인 개발 공부 중입니다, 프로그래밍 공부합시다!

0개의 댓글