REST API에 대한 오해
@eungjun-yi님의 그런 REST API로 괜찮은가 컨퍼런스 영상과 Roy Thomas Fielding의 논문 Architectural Styles and the Design of Network-based Software Architectures을 참고해 작성했다.
도대체 REST API란 무엇일까?
REST API의 정의
사실 Roy Thomas Fielding의 논문에서는 "REST API"라는 단어가 직접 언급 돼 있지는 않다. (RESTful 이라는 단어도 논문에는 나오지 않았지만, Roy가 사용하기는 하는데, 이게 REST의 형용사적인 표현인 건지, REST 스타일의 일부가 적용된 Web 서비스인 것인지는 의견이 분분하다. 참고로 AWS에서는 후자로 표현한다.)
그래서 REST API를 말하기 전, REST에 대해 먼저 말하자면, REpresentational State Transfer의 약어이다. 이때, REST는 분산 하이퍼미디어 시스템(ex. 웹)의 추상화 된 아키텍처 스타일이다. 주의해야 할 점은, 분산 애플리케이션을 위한 구조적인 모델이 아니라는 점이다. 또한, REST는 구조적인 제약(혹은 스타일)이지, 프로토콜이 아니다.
따라서 REST API란, REST 아키텍처 스타일을 따르는 API라고 할 수 있다.
REST style을 구성하는 Constraints
- Starting with Null Style: 1. 아무 것도 없는 상태에서 시스템에 맞춰 익숙한 요소들을 조합해 시스템에 맞는 아키텍처를 만들어내거나, 2. 어떠한 제약도 없는 상태에서, 시스템이 전반적으로 필요로 하는 요구사항부터 시작해 점점 제약 조건을 붙여가며 적용하는 것을 말한다. 1번은 창의력과 이상을 강조하는 데에 반해, 2번은 제약과 시스템 컨텍스트에 대한 이해를 강조한다. REST는 2번의 과정을 통해 개발되었다. 따라서 REST style은 특정 제약 조건들을 조합한 구조적인 스타일이라는 것이다.
- Client-Server: 사용자 인터페이스를 데이터 저장과 관련된 문제로부터 분리한다. 그로 인해, 사용자 인터페이스의 여러 플랫폼에 대한 이식성을 향상시킬 수 있고, 서버 컴포넌트를 단순화 시킴으로써 확장성을 향상 시킬 수 있다. 즉, 클라이언트와 서버는 분리돼 있기 때문에, 클라이언트는 resource에 해당하는 URI외에 알 수 없으며, server application과 상호작용할 수 없다.
- Stateless: 클라이언트와 서버는 상태를 가지지 않으며 상호작용해야 한다는 제약을 추가했다. 따라서 클라이언트로부터의 모든 요청은 서버가 어떠한 컨텍스트 없이 이해할 수 있도록 자세해야 한다. 또한, 세션의 상태는 클라이언트에서 유지되어야 한다. 이러한 제약을 통해 가시성, 신뢰성, 확장성을 야기할 수 있다.
- Cache: 클라이언트와 서버 간 무상태를 유지하며 네트워크를 효율적으로 구성하기 위해서 캐시라는 제약을 추가했다. 요청에 따른 응답에는 cacheable한 지, not cacheable한 지 명백하게 표시되어야 한다. 이는 클라이언트 및 서버 모두에서 적용 가능하다.
- Uniform Interface: 리소스에 대한 모든 요청은 동일한 구조와 표준을 사용해야 한다. HTTP Method와 URI를 통해 클라이언트가 서버의 리소스에 액세스하고 조작할 수 있어야 한다. 또한, 리소스에 대한 메타데이터(자원의 상태 및 버전 등)를 반환해야 한다.
- Layered System: 클라이언트는 서버와 직접적으로 통신하지만, 서버는 다른 시스템(캐시, 로드밸런서, 게이트웨이 등)과 통신할 수 있다. 이를 통해 시스템을 더욱 유연하고 확장 가능하게 만들 수 있다.
잘못 알고 있는 REST API
REST API의 정의
보통 REST API를 정의한다 그러면, "URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(ex. POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것" 등으로 많이 소개한다. 하지만 이는 완전히 잘못됐다고 생각한다. (특히 CRUD Operation을 적용하는 것...이라니...!?)
"REST(REpresentational State Transfer)에서 URI를 통해 자원을 명시하는 것"?은 오히려 RFC 2396에서 소개하는 URI라는 개념에 대한 내용에 가깝다고 생각한다. 물론 Roy Fielding 또한 논문의 6.2 REST Applied to URI에서 URI에 REST 스타일을 적용했다고 하는데(이는 Roy 본인이 RFC 2396의 저자이기도 하기 때문에 작성된 것으로 보인다.), REST 스타일을 '적용'했다고 했지, REST 스타일의 정의를 표현한 것은 아니라고 생각한다.
즉, 앞에서도 언급했지만 REST는 수많은 구조적인 스타일 중 하나일 뿐이며, 따라서 REST API라고 누군가 묻는다면, "REST 스타일을 따르는 API"라고 하는 것이 가장 정확해 보인다. 그리고 이후로 추가 질문으로 그렇다면 REST가 무엇인지에 대해 묻는다면, 그제서야 REST 아키텍처 스타일의 조건에 대해 말하는 것이 옳다고 생각한다.