RESTful API를 설계해보자

라모스·2023년 6월 7일
0
post-thumbnail

RESTful API이란 무엇인지, 좋은 설계 원칙에 대해 알아보자.

들어가기에 앞서, 소프트웨어 인터페이스의 디자인 방법과 API의 목표 식별 과정을 간략하게 짚고 넘어가자.

소프트웨어 인터페이스 디자인 방법

사용하기 쉽고, 이해하기도 쉬운 API를 만드는 건 올바른 관점에 집중하고 있어야 가능하다. 소프트웨어가 어떻게 동작하는지에 집중하기 시작하면 재앙이 벌어진다. 사용자가 무엇을 하는지에 대해 중점을 두면 현실 세계 사물의 사례처럼 모든 좋은 인터페이스를 디자인할 수 있다.

정리하자면, API는 프로바이더의 관점이 아니라 반드시 컨슈머의 관점에서 디자인되어야 한다.

위 그림은 오직 프로바이더만 이해할 수 있게 설계 된 전자레인지의 예시이다. 이는 사용자가 원하는 바를 쉽게 이룰 수 없는 디자인이다. 컨슈머 관점에 집중한 API는 자연스럽게 목표가 명확해지고, 사용하기도 쉬워진다.

API의 목표 식별 과정

  • 누가 API를 사용하는가?
  • 무엇을 할 수 있는가?
  • 어떻게 하는가?
  • 하기 위해서 무엇이 필요한가?
  • 끝나면 무엇을 반환하는가?
  • 입력은 어디를 통해 들어오는가?
  • 출력은 어디에서 어떻게 쓰이는가?

이 정보들은 우리가 만들 API의 기초가 되며, 동시에 정확한 API 인터페이스를 디자인하기 위해 꼭 알아야 한다.

REST API?

REST는 Representational State Transfer라는 용어의 약자로 2000년 로이 필딩(Roy Fielding)의 박사학위 논문에서 최초로 소개되었다. 로이 필딩은 HTTP의 주요 저자 중 한 사람으로 그 당시 HTTP 웹 설계의 우수성에 비해 제대로 사용되어지지 못하는 모습에 안타까워하며 웹의 장점을 최대한 활용할 수 있는 아키텍처로써 REST를 발표했다고 한다.

REST의 구성

REST API는 다음과 같은 구성을 가진다.

  • 자원(Resource): URI
  • 행위(Verb): HTTP Method
  • 표현(Representations)

상품 가져오기라는 간단한 예시를 들어보자.

# Request
GET /products/P123

# Response
200 OK
{
  "reference": "P123",
  "name": "Macbook Pro M2 Max 14 inch".
  "price": 3099.00
}

Request는 HTTP 메서드와 /products/P123이라는 경로의 조합으로 구성된다.

  • 경로: 서버상의 리소스를 식별할 수 있는 주소를 의미
  • HTTP 메서드: 이 리소스를 가지고 무슨 행위를 하고 싶은지 표시해주는 역할

Response의 첫 부분은 HTTP 상태코드 200과 원인을 알려주는 문장 OK로 구성되어 있다.

  • HTTP 상태 코드: 접수된 Request의 처리가 어떻게 되어가는지를 의미
  • Response Body: Request의 경로로 식별된 리소스의 콘텐츠를 포함하고 있다. 위 예시의 경우 JSON 데이터로 표현된 상품 정보가 반환되었다.

REST의 특징

REST API가 충족해야 할 제약 사항은 다음과 같다. 이는 REST의 특징이라 할 수 있겠다.

  • Uniform Interface: 모든 상호작용은 식별된 리소스의 개념에 따라 이루어져야 한다. 이는 식별된 리소스의 조작은 리소스의 상태 표현들과 표준 메서드들을 통해서만 이뤄짐을 의미한다. 또한, 상호작용은 리소스의 표현이 무엇을 의미하는지와 이 리소스들로 무엇을 할 수 있는지 알려줄 수 있는 모든 메타데이터를 제공해야 한다.
  • Stateless: 요청을 처리하는데 필요한 모든 정보는 해당 요청에 포함되어 있어야 한다. 서버는 요청을 처리하는데 필요한 클라이언트의 그 어떤 컨텍스트도 서버의 세션에 담지 않는다.
  • Cacheable: 요청에 대한 응답은 저장 가능 여부(클라이언트가 동일한 요청을 다시 하지 않고 재사용할 수 있도록) 및 기간을 표시해야 한다.
  • Self-descriptiveness: REST API 메시지만 보고도 이를 쉽게 이해할 수 있는 자체 표현 구조로 되어있다.
  • Client-Server 구조: 서로 커뮤니케이션하는 클라이언트와 서버. 가령 모바일 애플리케이션의 동작 방식과 API를 제공하는 서버의 동작 방식에 대해 분리해서 생각해야 한다.
  • 계층형 구조: 다충 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고 proxy, gateway 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다. 단, 클라이언트는 오직 시스템에서 하나의 레이어만 볼 수 있어야 한다.
  • Code on demand: 서버는 필요하다면 클라이언트에 실행 가능한 코드를 전송할 수 있어야 한다. (ex. JavaScript) 이 제약사항은 선택적이다.

REST API 디자인 가이드

REST API 설계 시 가장 중요한 항목은 다음 두 가지로 요약할 수 있다.

  • URI는 정보의 자원을 표현해야 한다.
  • 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현한다.

HTTP Method

HTTP Method를 가지고 CRUD를 매핑할 수 있다.

Method역할
GETGET을 통해 해당 리소스를 조회한다. 리소스를 조회하고 해당 도큐먼트에 대한 자세한 정보를 가져온다.
POSTPOST를 통해 해당 URI를 요청하면 리소스를 생성한다.
PUTPUT를 통해 해당 리소스를 수정한다.
DELETEDELETE를 통해 해당 리소스를 삭제한다.

URI는 자원을 표현하는 데 집중하고 행위에 대한 정의는 HTTP Method를 통해 하는 것이 RESTful한 API를 설계하는 중심 규칙이다.

URI 설계 시 주의할 점

  • 슬래시 구분자(/)는 계층 관계를 나타내는 데 사용
  • URI 마지막 문자로 슬래시(/)를 포함하지 않는다.
  • 하이픈(-)은 URI 가독성을 높이는데 사용
  • 밑줄(_)은 URI에 사용하지 않는다.
  • URI 경로에는 소문자가 적합: URI 경로에 대문자 사용은 피하도록 해야 한다. 대소문자에 따라 다른 리소스로 인식하게 되기 때문이다. RFC 3986(URI 문법 형식)은 URI 스키마와 호스트를 제외하고는 대소문자를 구별하도록 규정하기 때문이다.
  • 파일 확장자는 URI에 포함시키지 않는다. Accept Header를 사용하도록 하자.

좀 더 자세한 규칙은 다음과 같다.

  • 도큐먼트 이름으로는 단수 명사를 사용해야 한다.
  • 컬렉션 이름으로는 복수 명사를 사용해야 한다.
  • 스토어 이름으로는 복수 명사를 사용해야 한다.
  • 컨트롤러 이름으로는 동사나 동사구를 사용해야 한다.
  • 경로 부분 중 변하는 부분은 유일한 값으로 대체한다.
  • CRUD 기능을 나타내는 것은 URI에 사용하지 않는다.

리소스 간의 관계 표현

리로스들은 다른 리소스들과 관계가 있을 수도, 없을 쑤도 있다. 리소스 간의 관계를 표현하는 방법은 다음과 같다.

/리소스명/리소스 ID/관계가 있는 다른 리소스명

ex) GET : /users/{userId}/devices (has의 관계를 표현할 때)

ex) GET : /users/{userid}/likes/devices (관계명이 애매하거나 구체적 표현이 필요할 때)

Collection과 Document

일정한 타입의 리소스 여러 개를 포함하는 리소스를 Collection 이라 한다. Document는 단순히 문서로 이해해도 좋고, 객체라 이해해도 좋다. Collection은 이 객체들의 집합이라 생각하면 된다.

중요한 점은 Collection은 복수로 사용한다.

http:// www.example.com/teams/realmadrid/players/10

REST API의 자세한 디자인 규칙은 REST API 디자인 규칙을 참고해보면 좋을 것 같다.

References

profile
Step by step goes a long way.

0개의 댓글