흔히 잘못 이해되는 로이 필딩의 REST 논문
이 글은 Two-Bit History의 "Roy Fielding's Misappropriated REST Dissertation"을 원작자의 허락 하에 번역한 것입니다. 원문은 여기에서 읽을 수 있습니다.
Roy Fielding's Misappropriated REST Dissertation
RESTful API는 어디에서나 쓰이고 있다. 그런데 얼마나 많은 사람들이 "RESTful"이 무엇을 의미하는지 제대로 알고 있을지를 생각해 보면 이는 재미있는 일이다.
아마도 대부분의 사람들이 이 해커뉴스 글쓴이에게 공감할 것이라고 생각한다.
REST에 대한 여러 글을 읽었고 REST에 대한 원본 논문의 일부도 살펴봤다. 하지만 여전히 REST가 정확히 무엇인지는 희미하다. 나는 이제 아무도 그걸 정확히 모르는 게 아닐까, REST가 단순히 형편없이 정의된 개념이 아닐까 생각하기 시작했다.
나는 원래 REST가 인터넷상의 통신 방식에서 어떻게 이렇게 지배적인 패러다임이 되었는지를 탐구하는 글을 쓰려고 했다. 그래서 REST를 세상에 처음 소개했던 로이 필딩(Roy Fielding)의 2000년 논문을 읽는 것으로 연구를 시작했다. 그런데 논문을 읽고 나서는 필딩이 제시한 개념에 대한 오해가 어떻게 이렇게 널리 퍼져있는지에 대한 것이 훨씬 더 흥미로운 이야기라는 것을 깨달았다.
필딩의 논문에서 REST의 개념이 나왔다는 사실은 많은 사람들이 알고 있다. 하지만 그에 비해 실제로 그 논문을 읽어 본 사람은 매우 적다(이해할 만한 일이다). 그 결과, 논문이 실제로 어떤 내용을 담고 있는지에 대한 오해가 만연하다.
이런 오해 중 가장 큰 것은 필딩의 논문이 API 구축에 대한 문제를 직접적으로 다룬다는 것이다. 나는 REST가 처음부터 HTTP 위에 구축되는 웹 API의 아키텍처 모델로서 의도되었을 거라고 생각하고 있었다. 내 생각에는 많은 사람들이 그럴 것이다. 나는 원래 다음과 같이 상황이 전개되었을 거라고 생각했다. 사람들이 HTTP 위에 엉망진창으로 API를 구축하던 혼란스럽고 실험적인 시기가 있었고 필딩이 나타나 REST라는 합리적인 해결책을 제시한 거라고 말이다. 하지만 이런 타임라인은 말이 되지 않는다. 우리가 오늘날 알고 있는 형태의 웹 서비스 API는 필딩이 논문을 발표한 후 몇 년이 지나서야 등장했기 때문이다.
필딩의 논문은 "네트워크 기반 소프트웨어 아키텍처의 아키텍처 스타일과 설계(Architectural Styles and the Design of Network-based Software Architectures)"라는 제목인데, HTTP 기반으로 API를 구축하는 방법에 대한 것이라기보다는 HTTP 그 자체에 대한 것이다. 필딩은 HTTP 1.0 명세에 기여했고, 1999년에 발표된 HTTP/1.1 명세의 공동 저자였다. 필딩은 HTTP 프로토콜의 설계에서 얻을 수 있는 아키텍처에 대한 교훈에 관심을 갖고 있었다. 그리고 그의 논문은 HTTP/1.1의 표준화 과정을 주도했던 아키텍처 설계 원칙을 정리한 개념으로 REST를 제시했다. 필딩은 어떤 제안을 HTTP/1.1에 포함할지에 대한 결정을 내릴 때 이 원칙을 사용했다. 예를 들어 필딩은 새로운 MGET
, MHEAD
메서드를 도입하여 요청을 일괄 처리할 수 있게 하자는 제안을 거부했다. REST에 규정된 제약 조건 중 REST 시스템 내의 메시지가 프록시 및 캐싱하기 쉬워야 한다는 조건1을 위반한다고 판단했기 때문이다. 그 대신 HTTP/1.1은 지속적으로 유지되는 연결을 기반으로 여러 HTTP 요청을 보낼 수 있도록 설계되었다. (또한 필딩은 쿠키가 stateless해야 할 시스템에 상태를 추가하기 때문에 RESTful하지 않다고 생각했다. 하지만 이미 쿠키는 널리 사용되고 있었다2.) 필딩에게 REST는 HTTP 기반의 시스템을 구축하기 위한 가이드가 아니라 HTTP를 확장하는 방법에 대한 가이드였다.
필딩이 REST를 다른 시스템 구축에 적용할 수 없다고 생각했다는 이야기는 아니다. 다만 그는 REST를 적용할 다른 시스템 역시 "분산 하이퍼미디어 시스템(distributed hypermedia systems)"이라고 생각했다. 바로 이게 사람들이 REST에 대해 가지고 있는 또 다른 오해다. REST가 어떤 네트워크 애플리케이션에도 적용할 수 있는 범용 아키텍처라는 것이다. 하지만 필딩이 논문에서 REST를 소개하는 부분을 요약하자면 근본적으로 이렇게 말하는 것과 같다. "이봐, 우리가 방금 HTTP를 설계했어. 만약 너도 분산 하이퍼미디어 시스템을 설계하고 있다면, 우리가 만든 이 REST라는 멋진 아키텍처를 사용하면 훨씬 더 쉬울 거야." 웹이 이미 존재하는 상황에서 누군가가 이런 시스템을 구축하려는 시도를 할 거라고 필딩이 생각한 이유는 분명하지 않다. 어쩌면 2000년 당시에는 하나 이상의 분산 하이퍼미디어 시스템이 세상에 존재할 여지가 있는 것처럼 보였을지도 모른다. 어쨌든 필딩은 REST가 인터넷 상의 하이퍼미디어를 연결할 때 발생하는 확장성과 일관성의 문제를 해결하기 위한 개념이며, 분산 애플리케이션 전반을 위한 아키텍처 모델은 아니라는 점을 분명히 한다.
우리는 필딩의 논문을 REST를 처음 소개한 논문으로 기억한다. 하지만 사실 그 논문은 모든 상황에 적용되도록 만든(one-size-fits-all) 소프트웨어 아키텍처가 얼마나 형편없으며 어떻게 하면 필요에 맞는 소프트웨어 아키텍처를 더 잘 선택할 수 있는지에 대한 논문이다. REST 자체를 다루는 내용은 논문의 챕터 하나에 불과하다. 논문의 대부분은 네트워크 애플리케이션에서 사용할 수 있는 다양한 아키텍처 스타일3을 분류하는 데에 쓰인다. 이중에는 유닉스 파이프에서 영감을 받은 Pipe-and-Filter(PF)도 있고 Client-Server(CS) 스타일의 여러 변형도 있다. 예를 들어 Layered-Client-Server (LCS), Client-Cache-Stateless-Server (C$SS), 그리고 Layered-Client-Cache-Stateless-Server (LC$SS) 같은 것들 말이다. 이런 구조들은 점점 난해하고 다루기 힘들어진다. 하지만 필딩이 강조하고자 했던 핵심은 기존의 스타일들이 부과하는 제약들을 조합해서 새로운 스타일을 만들 수 있다는 것이다. REST 역시 이런 방식으로 도출되었으며 사실 REST 대신 Uniform-Layered-Code-on-Demand-Client-Cache-Stateless-Server (ULCODC$SS)라고 불릴 수도 있었다. 물론 명백한 이유로 그렇게 되지는 않았다.(역자: 당연하지만 REST에 비해 너무 길고 어색한 이름이니까) 필딩은 각각의 제약이 특정 애플리케이션에 적합할 수도 있고 그렇지 않을 수도 있으며, HTTP에는 이러한 제약 조건의 조합(REST)이 가장 적합하다고 판단했다는 점을 강조하기 위해 이러한 아키텍처 분류 체계를 제시했다.
REST가 이렇게 어디서나 쓰이고 있는 건 참으로 깊은 아이러니다. REST는 오늘날 모든 종류의 네트워크 애플리케이션에서 맹목적으로 사용되고 있지만, 필딩은 원래 개별 애플리케이션의 특정한 요구사항에 맞는 소프트웨어 아키텍처를 도출해 내는 방법의 예시로 REST를 제시했다.
나는 어떻게 이런 일이 벌어졌는지 이해하기 어렵다. 필딩은 형식이 기능을 따른다는 원칙(form follow function)을 어기는 것의 위험성을 매우 명확하게 이야기했기 때문이다. 필딩은 논문의 거의 첫 부분에서 이렇게 경고한다. "유행에 따라 설계하는 것(design-by-buzzword)은 흔한 일"이며 이는 소프트웨어 아키텍처를 제대로 이해하지 못한 결과라고 말이다4. 그는 몇 페이지 뒤에서도 이 문제를 다시 지적한다.
어떤 아키텍처 스타일은 흔히 모든 형태의 소프트웨어에 대한 "은탄환(silver bullet, 역자: 만능 해결책을 뜻한다)"으로 묘사된다. 그러나 훌륭한 설계자라면 해결하려는 문제에 맞는 스타일을 선택해야 한다.5
REST 자체가 특히 형편없는 "은탄환"이다. 왜냐 하면, 필딩이 이후 지적한 바에 따르면 REST는 분산 하이퍼미디어 애플리케이션을 구축하고 있는 게 아니라면 적합하지 않을 수 있는 트레이드오프를 포함하고 있기 때문이다.
REST는 대용량 하이퍼미디어 데이터 전송을 효율적으로 처리하도록 설계되었으며, 웹의 일반적인 사용 사례를 최적화한다. 그러나 이로 인해 REST 인터페이스는 다른 형태의 아키텍처적인 상호작용에는 최적이 아닐 수 있다.6
필딩은 웹이라는 환경에서 발생한 "무질서한 확장성(anarchic scalability)"이라는 곤란한 문제 때문에 REST를 만들었다. 이 문제는 서로 다른 조직과 국가에 걸쳐서 성능 저하 없이 문서들을 연결해야 하는 문제였다. REST가 부과하는 제약들은 이러한 무질서한 확장성 문제를 해결하기 위해 신중하게 선택된 것들이다. 공개된(public-facing) 웹 서비스 API의 경우에 이와 비슷한 문제를 다루어야 하고 이러한 경우 REST가 적절한 선택일 수 있다. 하지만 오늘날 우리는 REST가 남용되는 것을 흔히 볼 수 있다. 가령 엔지니어링 팀이 자신들이 완전히 제어할 수 있는 클라이언트하고만 통신하는 백엔드를 설계하면서도 REST를 사용하는 경우를 흔히 볼 수 있다. 이건 마치 몬티 파이썬 스케치(역자: 영국의 전설적인 코미디 그룹 몬티 파이썬의 짧은 코미디. 프로그래밍 언어 Python의 유래가 된 그 사람들 맞다)에 나오는 건축가 같은 상황이다. 건축가가 아파트를 설계하는데, 그는 도살장을 건축해본 경험밖에 없어서 아파트를 도살장처럼 설계해 버리는 것이다. (필딩 또한 이 스케치의 대사를 논문 서문에 사용했다. "실례지만...방금 '칼'이라고 하셨나요?(Excuse me… did you say 'knives'?)")
그래. 필딩의 논문이 은탄환 같은 소프트웨어 아키텍처를 피하는 것에 대한 내용이었다는 건 알겠다. 그러면 어떻게 REST는 모든 종류의 웹 서비스에서 사실상의 표준(de facto standard)이 되었을까?
내 이론은 이렇다. 2000년대 중반 SOAP에 질려버려서 뭔가 다른 걸 시도해 보려는 사람들이 있었고, 적당한 네 글자 약어를 필요로 했다는 것이다.
물론 농담 반 진담 반이었다. SOAP(Simple Object Access Protocol)는 장황하고 복잡한 프로토콜이어서 관련된 여러 XML 명세를 이해하지 않고는 사용할 수 없다. 초창기의 웹 서비스들은 SOAP 기반의 API를 제공했지만, 2000년대 중반부터 API가 폭발적으로 늘어나면서 SOAP의 복잡성에 질린 개발자들이 대거 이탈했다.
이렇게 이탈한 개발자들 사이에서 SOAP는 경멸의 대상이었다. Ruby on Rails는 2007년 SOAP 지원을 중단했는데, 그때 Rails의 창시자인 데이비드 하이네마이어 한손(David Heinemeier Hansson)이 남긴 유명한 코멘트가 이를 단적으로 보여준다. "SOAP는 지나치게 복잡하다. 기업의(enterprise) 사람들이 SOAP를 장악했고 이런 경우 보통 좋은 결과가 나오지 않는다"7. "기업의 사람들"은 모든 걸 공식적으로 명세하려 했지만 "돌아가는 구현이 급한 사람들(get-shit-done)"에게 그건 시간 낭비처럼 보였다.
돌아가는 게 급한 사람들은 SOAP를 쓰지 않기로 했다고 해도 여전히 뭔가 표준적인 방식이 필요했다. 모두가 HTTP를 사용하고 있었고 최소한 전송 계층(transport layer)으로는 모두가 계속 HTTP를 사용할 거였다. 전송 계층에서 필요한 프록시와 캐시 지원을 위해 가장 간단한 방법은 HTTP의 기존 의미론을 그대로 사용하는 거였기 때문이다. 그래서 그들은 그렇게 했다. 그들은 이런 접근을 대충 HTTP로 다 해버리자(Fuck It, Overload HTTP, FIOH)라고 부를 수도 있었다. 그리고 그건 적절한 이름이었을 것이다. 비즈니스 로직 오류에 적절한 HTTP 상태 코드를 뭘로 할지 고민해 본 사람이라면 무슨 뜻인지 알 것이다. 하지만 SOAP의 공식적인 명세 작업과 비교하면 이런 이름은 지나치게 가벼워 보였을 것이다.
운 좋게도 HTTP/1.1 명세의 공동 저자가 쓴 논문이 있었다. 이 논문은 HTTP의 확장과 약간 관련이 있었다. 그리고 "대충 HTTP로 다 해버리자"에 적당한 학술적 권위를 줄 수 있었다. 즉 REST는 사실 "대충 HTTP로 다 해버리자"에 불과한 것에 적당한 가림막이 될 수 있었던 것이다.
나는 이게 정확한 상황 전개였다고 말하는 게 아니다. 또한 불손한 스타트업 개발자들이 REST를 남용하려는 음모를 꾸몄다고 하는 것도 아니다. 하지만 이 이야기는 REST를 처음 제시한 필딩의 논문이 웹 서비스 API에 관한 것이 전혀 아님에도 불구하고 어떻게 REST가 웹 서비스 API의 모델이 되었는지 이해하는 데 도움을 준다. REST의 제약을 도입하는 게 좋을 때도 있다. 특히 조직 간의 경계를 가로지르는 공개 API의 경우 REST의 인터페이스 일관성(uniform interface)이 유용할 수 있다. 이게 웹에 API를 구축하는 방식과 관련해서 REST가 나온 핵심적인 이유일 것이다. 하지만 "대충 HTTP로 다 해버리기"라는 별개의 접근이 존재했고 해당 진영에서 단순히 마케팅 목적으로 REST라는 이름을 빌려왔다고 상상해 보면, 오늘날 우리가 알고 있는 RESTful API와 필딩이 처음 설명한 REST 아키텍처 스타일 사이의 수많은 괴리를 이해하기가 훨씬 쉬워진다.
예를 들어 REST 순수주의자(purist)들은 요즘 REST API라고 불리는 것들은 진짜 REST API가 아니라고 종종 불평한다. 그 이유는 대부분의 REST API가 애플리케이션 상태 엔진으로서의 하이퍼미디어(Hypermedia as The Engine of Application State, HATEOAS)를 사용하지 않기 때문이다. 필딩 본인도 이러한 비판을 한 적이 있다. 필딩에 따르면 진정한 REST API라면 기본 엔드포인트(base endpoint)에서 링크를 따라가는 것을 통해 모든 엔드포인트를 탐색할 수 있어야 한다. 만약 사람들이 정말로 REST API를 만들려고 한다면 HATEOAS가 빠진 것은 확실한 문제다. HATEOAS는 필딩의 원래 REST 구상에서 정말 핵심적인 부분이기 때문이다. REST의 원래 내용인 "Representational State Transfer"에서 state transfer란 많은 사람들이 생각하는 것처럼 네트워크를 통해 리소스를 전송하는 것이 아니라 리소스 간의 하이퍼링크들을 이용해서 상태 기계(state machine)를 탐색하는 것을 의미하기 때문이다.8 하지만 만약 대부분의 사람들이 그냥 "대충 HTTP로 다 하는 API"를 만들고 이를 슬쩍 REST API라고 부르거나, 조금 더 솔직하게 "RESTful" API라고 부르고 있다면? 그렇다면야 HATEOAS가 있든 없든 중요하지 않다.
마찬가지로 필딩의 논문에는 어떤 HTTP 메서드가 어떤 CRUD 작업에 매핑되어야 하는지에 대한 내용이 전혀 없다. 소프트웨어 개발자들이 리소스를 업데이트할 때 PUT과 PATCH 중 어느 것을 사용하는 것이 더 RESTful한지 끝없이 논쟁하는 것을 생각해 보면 놀라운 일이다. HTTP 메서드를 CRUD 작업에 표준적으로 매핑하는 방법이 있다는 건 유용한 일이지만 이러한 표준적인 매핑은 HTTP의 일부일 뿐 REST의 일부는 아니다.
이러한 이유로, 아무도 REST를 이해하지 못한다고 말하기보다는 "REST"라는 용어가 잘못 사용되고 이해되고 있다고 생각하는 게 더 적절하다. 현대적인 REST API의 개념은 필딩의 REST 아키텍처와 역사적으로 연관되어 있기는 하지만 두 가지 개념은 실제로는 별개이다. 이런 역사적 연관성을 염두에 두는 건 언제 RESTful API를 구축할지 결정할 때 참고가 될 수 있다. 당신의 API는 HTTP처럼 조직이나 국가의 경계를 넘어야 하는가? 그렇다면 예측 가능하고 인터페이스 일관성을 갖는 RESTful API를 구축하는 것이 맞는 접근일 수 있다. 하지만 그렇지 않다면 필딩이 "형태가 기능을 따르는 것(form follow function)을 선호했다는 걸 기억하는 게 좋다. 당신이 달성하려고 하는 목표에 따라서 GraphQL이나 어쩌면 JSON-RPC가 더 적합한 해결책일 수 있다.
만약 이 글이 재미있었다면, 비슷한 글이 4주마다 올라옵니다! 트위터에서 @TwoBitHistory를 팔로우하거나, RSS 피드를 구독하여 새로운 글이 올라올 때 놓치지 않도록 하세요.
Footnotes
-
Roy Fielding. "Architectural Styles and the Design of Network-based Software Architectures", 128. 2000. University of California, Irvine, PhD Dissertation, accessed June 28, 2020, https://www.ics.uci.edu/~fielding/pubs/dissertation/fielding_dissertation_2up.pdf ↩
-
Fielding, 130. ↩
-
필딩은 소프트웨어 아키텍처와 소프트웨어 아키텍처 "스타일"을 구분한다. REST는 아키텍처 스타일이며 HTTP 아키텍처에서 구현되어 있다. ↩
-
Fielding, 2. ↩
-
Fielding, 15. ↩
-
Fielding, 82 ↩
-
Paul Krill. "Ruby on Rails 2.0 released for Web Apps", InfoWorld. Dec 7, 2007, accessed June 28, 2020, https://www.infoworld.com/article/2330967/ruby-on-rails-2-0-released-for-web-apps-2.html ↩
-
Fielding, 109. ↩