11P by GN⁺ 7시간전 | ★ favorite | 댓글 1개
  • Roy Fielding의 REST 원조 논문에서는 HTTP 메서드나 CRUD 중심의 API 사용을 명확히 규정하지 않으며, REST는 원래 하이퍼미디어 기반(HATEOAS) 시스템 설계를 강조함
  • 많은 이들이 RESTful API라 부르는 것들은 중요한 REST 제약조건(특히 하이퍼미디어 사용)을 구현하지 않음
  • 리소스는 단순 데이터 구조나 엔티티에 국한되지 않고, URI로 식별 가능한 모든 개념을 포함함
  • Fielding의 6가지 규칙에 따르면, 하이퍼미디어 중심 탐색, 프로토콜 독립성, 미디어 타입 중시 등이 핵심임
  • 현실적으로는 OpenAPI 등 문서화 도구 편의성 때문에 대부분의 API가 진정한 RESTful보다는 RPC 스타일에 가깝게 설계되는 경향이 많음

대부분의 RESTful API가 진정한 RESTful이 아닌 이유

  • Roy Fielding의 대표 논문(2000) 은 REST(Representational State Transfer)를 네트워크 기반 소프트웨어 설계의 이상적 스타일로 제시하며, 웹의 성공을 뒷받침하는 원리로 설명함
  • 논문에서는 HTTP 메서드 사용, CRUD 중심 설계를 필수로 규정하지 않으며, REST를 지향할 때 하이퍼미디어(HATEOAS) 기반 상태 전이, 보편적 인터페이스, 자원 중심의 상호작용이 핵심임을 강조함

하이퍼미디어(HATEOAS)와 REST의 오해

  • Fielding은 하이퍼미디어 없는 API는 RESTful이 아니라고 명확히 지적
    • "엔진이 하이퍼텍스트에 의해 구동되지 않으면 RESTful이 아님"
  • HATEOAS란 클라이언트가 서버 응답에 내장된 링크를 따라 동적으로 행동을 탐색하는 방식임
  • 단순히 HTTP/CRUD 인터페이스만 사용하는 것은 REST의 본질과 다름

REST의 흔한 오해

  • REST는 CRUD라는 인식(실제로는 더 넓은 개념)
  • 리소스는 엔티티(서버의 데이터 구조)라는 오해
  • RESTful API에는 동사(Verb)를 쓰면 안된다는 주장
  • 이런 것들은 설계 결정일 뿐 REST의 본질과는 직접 관련 없음

하이퍼미디어 구동(HATEOAS)의 실제 의미

  • HATEOAS의 목적은 클라이언트-서버 결합도 최소화에 있음
  • 서버의 URI 구조 변경 시, 클라이언트 재배포의 고통을 줄여 확장성과 진화 가능성을 높임
  • 클라이언트는 문서나 사전 지식 없이 응답 내 하이퍼링크를 따라 동작을 탐색함
    {  
      "orderId": 123,  
      "\_links": {  
        "self": { "href": "/orders/123" },  
        "cancel": { "href": "/orders/123/cancel", "method": "POST" }  
      }  
    }  
    
  • 위와 같이 응답에 동작(링크)가 포함되어야 진정한 RESTful에 가까워짐

REST에서 리소스란?

  • 리소스는 URI로 식별 가능한 모든 것
    • 문서, 이미지, 물리적 객체, 서비스, 추상 개념 등 포함
  • 서버에는 실제 "리소스"가 존재하는 것이 아니라, URI로 접근 가능한 추상적 매핑 구조가 있을 뿐임
  • RFC 3986에서도 리소스의 범위를 한정하지 않음
    • 전자 문서, 이미지, 정보원, 서비스, 심지어 사람·법인·도서 등도 포함 가능

Fielding이 정의한 RESTful API의 6가지 규칙

  • 1. 단일 프로토콜에 종속되지 말 것
    • URI 기반 식별을 모든 프로토콜에서 활용 가능해야 함
  • 2. 프로토콜(예: HTTP) 표준을 임의로 변경하지 말 것
    • 표준의 미비점 보완은 가능하나, 임의의 규칙 추가/변경 금지
  • 3. URI 구조 대신 미디어 타입(포맷) 정의에 집중할 것
    • 데이터 형식 및 링크 정의에 집중, 경로 명세/문서화에 에너지 낭비 금지
  • 4. 고정된 URI 네이밍/계층구조 하드코딩 금지
    • 클라이언트가 서버의 네임스페이스 구조를 추측·고정하지 않도록, 링크 기반 탐색 유도
  • 5. 리소스 타입(내부 분류) 노출 금지
    • 내부 객체 타입은 클라이언트에 무의미, 표준 미디어 타입·링크만 노출
  • 6. 북마크(초기 URI)만 필요, 나머지는 응답의 링크로 탐색
    • 클라이언트는 표준 미디어 타입만 알고, 상태 전이는 항상 서버 응답 내 하이퍼링크 기반으로 이뤄져야 함

규칙의 해석과 실제 적용

  • 프로토콜, URI, 타입에 대한 결합을 최소화해야 진정한 RESTful에 가까워짐
  • API는 데이터와 링크의 형식(미디어 타입)에 집중해야 하며, URI 구조나 명명 규칙 등은 클라이언트가 미리 알 필요 없음
  • 예시처럼 /users/123/activate 같은 경로를 명세하지 않고, 응답 내 "activate" 링크로 동작을 안내해야 함

실제 RESTful API가 드문 이유

  • OpenAPI, Swagger 등 도구의 편의성이 개발 현장에서 우선시됨
    • 자동 문서화, 코드 생성, 유효성 검사 등 실질적 이점 제공
  • 클라이언트-서버를 같은 팀이 개발하는 SPA 환경에서는 URI 결합 문제의 필요성이 크지 않아, HATEOAS의 장점이 부각되지 않음
  • REST 원칙의 초기 학습 부담, 동적 링크 파싱의 복잡성 등 실용적 장벽이 큼

결론

  • Fielding의 규칙에 따르면 진정한 RESTful API는 하이퍼미디어(HATEOAS) 기반 동적 탐색이 필수임
  • REST는 단순히 HTTP 위에서 CRUD를 구현하는 것이 아니며, 웹의 원리와 같이 느슨한 결합·진화 가능성·동적 상태 전이에 초점을 둔 아키텍처임
  • 현실에서는 실용성과 팀의 상황에 맞는 설계가 더 중요할 수 있음
    • 외부 개발자를 위한 퍼블릭 API라면 HATEOAS 채택이 권장되지만, 내부 전용 API라면 단순한 RPC 스타일도 실용적임
  • API는 배우기 쉽고 오용하기 어렵게 설계하는 것이 핵심이며, 반드시 RESTful일 필요는 없음
Hacker News 의견
  • 나는 여기서 나타나는 지나친 원리주의에 공감하며 Fielding의 논문도 흥미롭게 읽었음, 하지만 이건 이미 끝난 전쟁임을 느꼈음 REST API라는 말을 듣는 순간 다음을 거의 확신할 수 있음

    • API는 JSON을 반환함
    • CRUD 작업이 POST/GET/PUT/DELETE에 매핑됨
    • 팀은 적합한 HTTP 상태 코드에 대해 끝없이 논쟁하며, 일부 코드는 스펙과 다르게 쓰임
    • 복잡한 필터 지원을 위해 listing endpoint가 POST로 변경될 가능성도 있음 Agile, CI, DevOps처럼 처음의 정의를 고집하거나, 아니면 이미 사회적 의미가 바뀌었으니 그냥 통용되는 뜻대로 용어를 쓰게 됨
    • Fielding이 이겼던 이유는 바로 그의 논리가 모순되고 대부분 틀렸기 때문라고 생각함 21세기의 "worse is better" 패러다임임 RPC 시스템은 사용성이 떨어지고 성공하지 못했고, 예로 Sun RPC, RMI, DCOM, CORBA, XML-RPC, SOAP, Protocol Buffers 등이 있음 사람들은 REST가 RPC가 아니라고 하지만 실제로는 Javascript에서
    const getItem = async (itemId) => { ... }
    

    같은 함수를 만들고, 이 함수는

    GET /item/{item_id}
    

    를 호출함 백엔드에는

    Item getItem(String itemId) { ... }
    

    같은 함수가 있고 어노테이션으로 URL 매핑을 설명함. 결국 이건 RPC임. 다만 복잡하고 비직관적인 시스템 대신 좀 더 수작업스럽고 개발자가 통제할 수 있는 형태로 남아 있음 대다수 문제의 80%는 사람들이 ISO 8601 날짜 포맷을 안 쓰는 것이 원인임

    • 왜 누가 이걸 "전투"라고 여기고 신경 쓰는지 이해가 잘 안 됨 REST 개념은 유용하지만, HATEOAS 부분은 실용성이 거의 없고 문제만 만듦 Richardson maturity model을 보면 REST의 최정점은 HATEOAS 같은 요소가 포함되어 있음 REST에서 HATEOAS가 빠지면 REST라고 할 수 없다는 논리도 이해 안 됨, 별로 큰 차별점이 안됨 HATEOAS가 실질적으로 거의 무의미하면 이 원리주의적 분류에 집착하는 게 의미가 없는 것 같음 Richardson maturity model

    • "팀이 상태 코드에 대해 과도하게 논쟁하고 HTTP spec과 다르게 쓰는 경우가 많다"는 부분에서는 401 Unauthorized는 인증이 안 된 경우, 403 Forbidden은 권한이 없는 경우에 써야 함을 강조함

    • 나는 사람들에게 Paper에서 정의한 REST의 의미를 진짜로 쓸 건지 물어보는 편임 보통 의미 없는 용어를 남용하는 현실을 용납하지 않는 쪽임 결국 "그냥 웹 API라는 얘기구나"라고 한 뒤 넘어감. 중요한 건 이런 API마다 엉뚱한 점을 파악해야 한다는 차이임

    • 나에게 진짜 중요한 뉘앙스는, "하이퍼미디어 링크"가 다양한 link type(HTTP 헤더나 반환 결과에 포함됨)으로 "일반적"인 것처럼 보이지만, 실질적으로 오늘날의 REST도 동일하게 동작한다는 점임 예를 들어, 만약 잘못 설계해서 "activate"가 아니라 "enable"이어야 했다면, 결국 /api/v1/account/ID/activate에서 /api/v2/account/ID/enable로 바꿔야 함 즉, API에서 모든 액션의 의미를 어디선가 하드코딩해야 함(그리고 아이콘, 액션 설명 번역 등 부가 메타데이터도 부족함) 이 방식의 "범용성"은 사실 착각임

  • 13년 전 처음으로 HTTP API를 개발하게 되었을 때, 진짜 REST가 뭔지 파악하기 위해 Fielding의 논문을 처음부터 끝까지 읽고, RESTful Web Services Cookbook도 읽음 그리고 Django의 관례를 피해가며 REST API를 만들었음 이건 일종의 ‘카고 컬트’적 접근으로, 진짜 REST가 우리 서비스에 어떤 이점을 주는지 잘 몰랐음 그로부터 몇 년을 더 다양한 HTTP API를 만들면서야 결국 실무 상황에선 REST 원론이 줄 수 있는 이점이 없다는 걸 느꼈음 "셀프 디스커버리"와 "제너릭 클라이언트와 호환" 비전은 거의 실현 불가능하고, 구체적으로 Fielding 논문은 이런 부분을 아예 완벽하게 안내하지도 않음 진짜 셀프 디스커버러블 API 만들려면 "엔드포인트 디스커버리 프로토콜", "오퍼레이션 설명", "헬프 메세지" 등 구체적인 룰이 필요함 그리고 결국 그 룰을 이해하는 전용 클라이언트를 만들어야 하고, 그럼 일반화된 클라이언트의 이점은 사라짐 즉, 현실에서 서비스 전용 API/JS 코드/CLI 등 결국 서버별 맞춤 코드를 만드는 수밖에 없었음 그리고 좋은 UX는 REST의 이상과 충돌하는데, 프론트에 앱 특화 코드를 만들어야 진짜 좋은 UX가 나옴 UI 요소도 표준화할 수는 있긴 하지만 실제로는 JavaScript 같은 언어를 통해 유연하게 UI를 만드느 게 더 쓸모 있음

    • 셀프 디스커버러블 API라는 개념의 한계에 공감함 진짜 REST 클라이언트는 실질적으로 구현 불가능함 모든 URL의 동작을 알고 있어야 하고, 새로 추가되는 행동이 있다면(예: /cansofspam/123/frobnicate) 클라이언트가 명확히 처리하지 못함 결국 클라이언트 업데이트가 필요하거나 무시하거나 아주 단순한 버튼(예: Frobnicate)만 추가 가능함 그래서 실제로 완전한 의미의 REST 서버나 클라이언트는 존재하지 않음 현실적으로 클라이언트가 디스커버리 없이 기대하는 API만 지원하는 게 운영이 됨

    • API에는 다양한 측면이 있어서 설명하는 일이 어려움 API 사용자들은 평균 응답 지연, 재시도 가능한 에러코드, 액션의 원자성/멱등성 등도 알아야 함 HATEOAS만으론 이런 것들을 알 수 없음 완벽한 REST를 구현할 필요가 없고, 기본적으로 REST가 주는 이점은 단순히 명사/동사를 HTTP 메서드와 URL로 매핑하는 통일된 언어가 있다는 점임 그런데도 세세한 설계와 고민이 엄청 많음 예를 들어 HTTP 스펙상 허용되는 걸 실제 LB에선 쓸 수 없다거나, 500 에러를 리트라이하는 기준/백오프 로직 등을 신경 써야 하는 점이 있음

    • 브라우저가야말로 "제너릭 코드"로, 우리가 매일 쓰는 최고의 UX를 제공함 REST 개념엔 서버가 클라이언트에 코드를 넘길 수도 포함됨(보안상의 이슈는 있지만, 브라우저와 표준이 이런 부분도 많이 해결함) Fielding 논문 내 관련 부분 링크

    • 사실 REST 정의도 약해진 버전에선 별로 이득이 없음 "리소스 삭제에 DELETE를 꼭 써야 한다"는 건 그다지 중요하지 않음 그냥 POST 쓰면 누가 어려워 하나요?

    • 나는 '셀프 디스커버러블'이란 게 목표라고 생각해본 적도 없고, 달성 가능한 일이라고도 안 봄 간단한 클라이언트 설계에서는 애초에 기대가 너무 과함 특히, TFA에서도 ‘discoverable’이란 단어 자체가 안 나옴

  • 이런 API 디자인 방식이 진짜 쓸모 있는 곳은, 사용자와 이를 대신 탐색하는 agent(예: 브라우저)가 API를 탐색하면서 각 응답 내 미디어 타입, 링크 정보에 따라 상호작용할 수 있을 때임 대부분 웹 API들은 이런 use-case가 아니라, 특정 UI/UX를 추구하는 웹앱용으로 설계되어 있음 이는 의도적으로 선택된 방향임 앱 제작자는 앱 목표를 위해 데이터의 표현, UI 흐름 등을 완전히 통제하길 원함 REST API 설계는 사용자가 API의 리소스 사용 방식을 더 주도적으로 통제해야 할 때 필요함 예시로

    • 누구나 접근 가능한 정부 정보 포털(법령, 날씨, 부동산 기록 등)
    • 각종 서식 제출이 필요한 정부 포털
    • 위키피디아나 OpenStreetMap 같은 open data 프로젝트 이런 쪽이 REST API 디자인을 도입해야 할 영역임 결국 REST 정의를 엄격히 따지는 사람들은 학구적인 배경이 많고, 반면 넓게 쓰는 사람들은 앱 경험을 중요시하는 개발자인 셈임 해답은 단순함, 진짜 REST가 아닐 때는 REST라고 부르지 않으면 됨
    • 사실 HTML 문서가 정확히 그 사례임 문서 안에 다른 문서로 가는 링크들이 있고, 사용자는 링크에 써있는 텍스트대로 어디로든 탐색할 수 있음 만약 사용자를 위한 거면 UI라고 부르고, 애플리케이션용이면 API라고 부름 HATEOAS가 엉뚱하게 느껴지는 이유는, API를 직접 사용자에 맞추자는 것처럼 보임 하지만 우리는 이미 UI라는 형태로 그걸 누리고 있음

    • 순수 REST 개념은 매우 학구적임 오픈/빅데이터 프로젝트에서 실질적인 성능이나 아키텍처를 구현하려면 REST 달성유무보다 현실적인 접근이 더 중요함 심지어 학자들도 결국 결과물을 만들어야 하기 때문에 완벽한 REST만 고집하지 않음

    • 이런 종류의 API 설계는 웹 페이지뿐 아니라 다른 클라이언트를 만들 때도 유용함 GET으로 리소스를 받아서 필드/경로로 값 추출하고, 새 URI를 만들어 조작하는 등 비슷한 패턴으로 여러 가지 앱/CLI/UI 구축이 가능함 non-SPA라면 HTML로 바로 구현하는 것도 가능하고, 결국 사용자(혹은 user-agent)가 반환 표현 내부의 정보를 dereference 하는 것임

    • AI가 API를 소비하는 시대가 오면 이 use-case가 더 중요해질지 궁금함 API의 discoverability는 웹앱 개발자보다 AI에 훨씬 더 유리함 MCP(몰입형 제어 프로토콜)를 보면 tool discoverability가 얼마나 강력한지 알 수 있음 HATEOAS가 이런 bare API 소비에도 큰 잠재적 이점을 줄 수 있음

    • 미국 기상청의 RESTful 서비스 API 문서 링크처럼 공개정보 API가 잘 설계되어 있으면 정말 쾌적함

  • "진짜 하이퍼미디어 기반 클라이언트를 만드는 초기 인지부하가 거대하게 느껴졌고, 그냥 URI 템플릿(/users/{id}/orders 등)을 하드코딩하는 편이 편하게 느껴졌다"는 내용과 관련해, 실제로 그게 더 쉬운 일임을 경험적으로 체감함 순정 REST 원칙은 대다수 상황에서 비용 대비 효용이 떨어짐 마치 전자레인지에 하나의 버튼으로 메뉴/작동방식/시간을 다 조작하는 방식이, 그냥 표준 버튼에 기능을 익숙하게 쓰는 것보다 훨씬 번거로움 내가 실제로 쓰는 2버튼 엔진 코드 리더기도 어이없이 조작이 불편함 아직도 Fielding 논문을 반드시 읽으라 하는 문화는 좀 심각한 논란거리임 좋은 아이디어라면 다양한 방식, 대중적 시각으로 쉽게 설명되어야 함 예를 들어, 물리를 이해하려면 Newton의 Principia를 반드시 읽으라는 사람은 없음

  • RESTful/HATEOAS 패턴을 도입할 때 진짜 가치가 있으려면, 이를 이해하는 클라이언트가 필요함 htmx: hypermedia clients intercoolerjs: hatoeas-is-for-humans

  • UI 디자이너들은 화면의 세부적인 룩을 통제하고 싶어함 리소스에 가능한 어떤 액션은 큰 버튼으로, 어떤 것은 메뉴에 숨기거나 UI에 아예 표시하지 않을 수도 있음 액션이 특정 상태마다 동적으로 API 응답 기반으로 렌더링된다면, 모든 액션이 똑같이 보이게 됨 그래서 RESTful API는 흔한 웹 프론트엔드 UI 구현에는 부적절하다고 봄

    • 이 주장에는 다수 오류가 있음

      1. UX 디자이너는 제품 개발 주기 전체에 관여하며 무조건 통제권을 갖고 있진 않음. UI 내 특정 액션 배치는 액션의 "state"와 별개임. 즉, 상태가 제한하면 UX도 그 제약을 따라야 함
      2. 아키텍처적으로 상태 체크를 래핑하면 "if (state === something)"만큼 "if (resource.links['action'] !== null)"이 훨씬 낫기도 함. 대부분의 state 변화는 서버에서 validation이 필요하고, 이를 서버에만 구현하면 프론트 복잡도도 낮아짐 나는 HATEOAS 앱을 꽤 오래 개발했고, HAL4J도 관리 중임. 복잡성은 있지만 UI 디자인 자체가 진입장벽은 아님
    • 내 경험상, "RESTful API" 개발이 UI랑 직접 연관되는 일은 많지 않았음 진짜 UI만 필요하다면 API 자체가 불필요함, 그냥 서버 주도 방식(옛날 DWR 등)으로 해도 됨

  • HATEOAS가 현실에서는 거의 쓰이지 않는 것 같은데 왜 아직도 이렇게 논의되는지 잘 이해가 안 됨 정말 이걸 쓰는 곳이 있는지, 그리고 실제로 어떤 "자동 탐색 클라이언트"가 서버 정보를 사전에 몰라도 되는지 궁금함

    • ACME(Let’s Encrypt의 프로토콜)가 HATEOAS 기반임을 상기함. 이건 사실상 대부분의 HTTPS 서비스에서 사용됨 HTTP 자체도 원래 제대로 쓰면 HATEOAS 프로토콜임 "auto-discovery"는 링크 타입이나 ‘next’ 등으로 리소스 탐색이 가능한 것임. 단, 클라이언트가 "next" 의미는 사전에 알고 있긴 해야 함 LLM도 이런 자동 탐색에 강함

    • 엔터프라이즈급 비디오 감시 시스템에서 HATEOAS를 활용했었음 버전/권한 문제를 API 레벨에서 훌륭하게 해결했음 여러 RFC도 같이 활용함 다만 문제점 1순위는 사람들이 모델을 무너뜨리는 방향으로 "편리함"을 추구하다가 오히려 복잡성을 유발함 또, JSON은 본질적으로 하이퍼텍스트 포맷이 아니라서, application/json에 HATEOAS를 강제로 심으려고 하면 억지스러웠음

    • HATEOAS를 사용해 댓글을 입력하고 있고, 바로 지금 답글도 달고 있음 이걸 처리하는 "마법의 자동 탐색 클라이언트"는 바로 "웹 브라우저"임

    • htmx가 가장 현실적인 시도일 수 있음

    • OData 같은 표준도 거의 안 쓰이고, 그나마 popular하지도 않음 HATEOAS는 인기/표준도 부족해서 더더욱 확장되지 않는 듯

  • 언제나 이 논의에서 놓치기 쉬운 건 백엔드 API 소비자의 유형임 REST와 HATEOAS는 보통 백엔드를 직접 소유하지 않는 서드파티가 소비할 때 의미가 커짐 예로 전통적인 HTML 페이지의 최종 소비자는 브라우저 사용자임 최근의 MCP도, 다양한 JSON RPC API에 대해 "디스커버리와 해석"이 필요한 케이스라 등장함 반면 프론트와 백엔드가 1:1로 맞물릴 경우 REST의 이점이 비용 대비 크지 않음 더 generic하게 문서화/스펙을 짜야 하고, 실무에서는 separation of concerns를 무시하고 생산성을 높이려는 도구(trPC 등)가 오히려 유용할 때가 많음 프로토타입 시에는 end-to-end 통합이 빠름

  • HATEOAS와 schema reference(XSD, JSON Schema 등)로 동적 탐색 클라이언트가 가능하다는 주장에 대해, 현실적으로 JSON schema의 "additionalProperties" 같은 기능이 오히려 문제의 원점을 반복하게 함 "out of band" 방식으로 문서 전달하는 게 더 견고하다고 봄 그렇다면 만약 "_links"에 단순히 Swagger 문서 링크 하나만 제공하고, 그 self path 정보를 클라이언트가 소화하게 하면 어떨까? 그럴 거라면 "_links"가 왜 존재해야 하지? 그렇게 복잡한 JSON 문서를 다루는 클라이언트가 있다면 오히려 Swagger 템플릿 등으로 훨씬 더 정보밀도, 동적성이 뛰어남 CRUD 링크만 가지고는 API 전체를 제대로 설명하기 부족하며, JSON schema로 모든 걸 커버하는 것도 불가능함

  • 그냥 HTTP API라고 부르면 모두가 행복해짐 REST 자체는 애초에 API용으로 설계된 게 아니었음 애초부터 REST는 사람이 받는 정보시스템을 위한 것이지, 프로그램을 위한 건 아니었음