ha-ah

로그, 게으른 로그

연재 목록

  1. REST - 긴 여정의 시작
  2. REST - HTML Form에서 GET/POST만 지원하는 이유
  3. REST - 논문(요약) 훑어보기
  4. REST - REST 좋아하시네
  5. REST - Roy가 입을 열다
  6. REST - 당신이 만든 건 REST가 아니지만 괜찮아
  7. REST - 논문 읽기(To Do)

논문

REST의 사전적인 의미부터 알아보자.

‘바쁜 개발자들을 위한 REST 논문 요약’을 요약 + WhatIsRest.com + 지난 며칠간 블로그와 댓글을 뒤져가며 얻은 지식 + 내 생각을 적어보려고 한다.

REST 제약 조건

논문에서는 아무것도 없는 웹 스타일에서 시작해, 제약 조건을 하나씩 추가해 나가며 REST 스타일을 유도해 나가는 과정을 통해 REST를 설명한다.

  1. Starting with the Null Style
  2. Client-Server
  3. Stateless
  4. Cache
  5. Uniform Interface
  6. Layered System
  7. Code-On-Demand

각 제약 조건을 취하면서 발생하는 trade-off도 언급하고 있으나 여기서는 넘어가기로 한다.

Client-Server

보통 생각하는 서버-클라이언트를 의미.

여기서 의문이 들었던 게, Client-Server라는 게 과연 제약조건이라고 할 수 있는 건가? 그러니까, 제약 조건을 어기는 게 과연 가능한가?

이 제약조건은 클라이언트와 서버의 역할을 명확하게 구분한다 정도로 생각하면 될 것 같다.

서로의 관심사를 분리하여 각각의 로직의 독립적인 진화를 지원해야 한다(중요).

Stateless

모든 요청은 필요한 모든 정보를 담고 있어야한다.

요청 하나만 봐도 바로 뭔지 알 수 있으므로 가시성이 확보된다.

API 문외한 입장에서 가장 이해가 안 됐던 부분 중 하나였다. 인증을 위해 쿠키를 심고 세션에서 필요한 정보를 가져오는 경우, 이는 stateless인가 아닌가?

  • 정답 : Session 정보 활용한다면 stateless가 아니다

REST에서는 각각의 요청에 서버가 필요한 정보가 모두 담겨야 한다.

Cache

모든 서버 응답은 캐시 가능한 지 그렇지 않은 지 알 수 있어야 한다.

캐시를 고려한 설계가 필요하다.

Uniform Interface

구성요소(클라이언트, 서버 등) 사이의 인터페이스는 균일(uniform)해야한다.

  • 이것만으로는 무슨 말인지 모르겠다

WhatIsREST.com의 내용을 구글 번역으로 돌려보면

  • 소비자는 많은 소비자와 서비스에서 표준화 된 방법, 미디어 유형 및 공통 리소스 식별자 구문을 통해 서비스 기능에 액세스합니다라고 나오는데,
    미디어 유형이나 리소스 식별자 등을 의미하는 문법이 구성요소나 호환 시스템 간 동일해야 한다는 의미

균일한 인터페이스가 필요한 이유는

  • 서버 입장에선 어떤 클라이언트든 상관없이(내가 보내주는 것을 이해할 수 있을까 걱정없이) 표준에 의한 응답을 해줄 수 있고
  • 클라이언트 입장에선 hypertext를 통해 다음 상태로의 이동을 해야하는데, 표준화된 방식을 통해 해당 서버의 특성을 알 필요가 없어진다
  • 서로의 특성을 알지 못해도 커뮤니케이션이 가능할 수 있어야, 각각 독립적으로 진화할 수 있는 유연한 시스템이 만들어진다

REST는 네가지 Interface 제약조건으로 정의된다

네가지 Interface 제약조건에서 언급된 내용을 구글 번역으로 좀 더 상세히 살펴보자.

  • 이 자원의 추상적 정의는 웹 아키텍처의 핵심 기능을 가능하게 합니다
  • 유형이나 구현에 따라 인위적으로 구별하지 않고 많은 정보 소스를 포괄함으로써 보편성을 제공합니다
  • 표현에 대한 참조의 늦은 바인딩을 허용하여 요청의 특성에 따라 내용 협상을 수행 할 수 있습니다
  • 저자는 개념의 단수 표현보다는 개념을 참조 할 수 있으므로 표현이 바뀔 때마다 기존의 모든 링크를 변경할 필요가 없습니다

1. identification of resources

리소스를 식별하는 방법이 동일해야 한다. 우리는 보통 URI를 쓰기 때문에 어쩐지 당연한 말처럼 느껴진다.

2. manipulation of resources through representation

representation의 개념은 이응준님 블로그에서 다루고 있다.

리소스의 표현계층(representation)을 리소스의 식별자(URL)로부터 분리한 것은 REST에서 아주 주요한 관점이다.

RESTful 응용 프로그램은 동일한 URI에서 동일한 자원의 표현을 둘 이상 지원할 수 있다.

3. self-descriptive messages

요청이나 응답 메시지에는 이를 이해하기 위한 모든 정보가 포함되어야 한다.

4. hypermedia as the engine of application state

줄여서 HATEOAS라고도 하지만 REST를 사랑하는 이들은 종종 이렇게 줄여부르는 걸 싫어하기도 한다(똑똑하고 재수없게 보이려면 ‘HATEOAS라고 줄여 부르는 건 바보같다’라고 말하면 된다).

훗날 블로그에서 Roy는 이 부분을 가장 강조하는데, 어쩌면 사람들이 가장 안 지키고 있기 때문일 지도 모르다는 생각을 했다.

그리고 이를 언급할 때 주로 hypertext라는 표현을 사용한다.

논문에서 hypermedia라고 한 것은 단지 text가 아닌 매체를 고려했기 때문이고,

일반적인 API에서는 거의 hypertext라고 표현하면 된다.

음? 우리가 HTML 페이지에서 맨날 보는 그 hypertext라는 용어가 맞나?

맞다. 제시된 hypertext 위에서 application 상태를 변경하는 주체가 client가 되어야 한다는 게 핵심이다.

조대협님의 블로그에는 HTTP Response에 다음 Action이나 관계되는 리소스에 대한 HTTP Link를 함께 리턴하는 것이라고 언급이 되어 있다.

  • 뭔가…이상한데…틀렸다고 하기는 뭣 하지만 온전히 이해가 되는 문장은 또 아니다. 다른 사람의 의견을 더 들어보자

What HATEOAS actually means

  • 다들 혼란스러워하는 것 같은데 직접 로이 필딩에게 물어보지 그래?
  • 로이의 문장은 명확하고, 모호하지도 않으니 그냥 읽어보길 바란다
  • 로이가 HTTP 표준의 기여자라는 것을 잘 생각해보자
  • 이 논문의 주제는 WWW가 잘 동작하고 확장성도 좋고, REST가 WWW 아키텍쳐 위에서 동작한다면, 이 역시 잘 동작하고 확장성이 좋다는 것이다
  • 4가지의 제약 조건은 결국 URI를 사용해서 MIME-typed 문서를 GET/PUT 등으로 전송하는 것 + HATEOAS
  • WWW := URI + HTTP + MIME + Hypermedia
  • Hypermedia라는 건 hypertext를 확장한 개념
  • 좀 더 정확하게 쓰자면, HATEOAS := hypermedia documents as the state of state
  • 로이의 배경을 생각하면 그는, 하이퍼링크가 없는 HTML 도큐먼트를 상상조차 못할 인물이다
  • 그가 언급한 Hypermedia란 문서 자체를 의미한다
  • 로이는 HTTP통신에 Link header를 넣어도 여전히 RESTful 할 수 있지만, 합당한 이유가 있어야 한다고 했다
    • 역주) 헤더에 넣으면 이를 처리할 수 없는 클라이언트도 있을 수 있기 때문에..라고 했는데 당시에는 LINK가 정식 표준이 아닌 때였기 때문인 것 같음
  • HATEOAS를 정확히 구현한 것은 문서안에 있는 링크다
  • HATEOAS라는 다음 상태 변경을 위한 링크(form 링크 등)를 제공해야 한다는 것

이 문서도 좀 제멋대로 해석한 부분이 있는데, Roy는 단지 HTTP만을 염두에 둔 게 아니다. HTTP이거나 HTML 문서이거나 그런 게 중요한 게 아니다.
HATEOAS라는 걸 응답에 다음 액션에 관한 링크를 전달하는 것 정도로 생각하면 안 된다.

  • 응답에 링크를 주렁주렁 달고 다니면 HATEOAS가 되는가? NO!
  • 서버는 Hypermedia를 통해 다음 액션에 대한 선택지를 클라이언트에게 줘야한다
  • 클라이언트는 서버의 독자적인 진화에 영향을 받아선 안 되며, 서버 상의 구현에 의존하면 안 된다

결국 HATETOAS의 목적은 (서버-클라이언트 간 의존성을 분리해야만 가능한) 독자적인 진화와 확장을 보조하는 것이며, hypermedia는 그 목적을 이루는 데 기여해야 한다

Layered System

클라이언트든 서버든 미들웨어 구성요소를 추가할 수 있는 구조.

하지만 Client-Server 사이에선 그 구성요소가 추가되는지, 다른 서비스와 추가로 통신하는 지 여부는 관심없다.

서버와 클라이언트 간 상호 작용을 일관성있게 유지해야 한다.

Code-On-Demand (Optional)

서버가 네트워크를 통해 클라이언트에 프로그램을 전달하면 그 프로그램이 클라이언트에서 실행될 수 있어야한다. (Java applet이나 Javascript 같은 것을 말함).

다만 이 제약조건은 필수는 아니다.

thanks to

로이 필딩의 논문

이응준님의 블로그에서 많은 영감을 얻음

WhatIsREST.com

네가지 제약조건에 대한 짧은 설명

HATEOAS가 진짜로 의미하는 것

연재 목록

  1. REST - 긴 여정의 시작
  2. REST - HTML Form에서 GET/POST만 지원하는 이유
  3. REST - 논문(요약) 훑어보기
  4. REST - REST 좋아하시네
  5. REST - Roy가 입을 열다
  6. REST - 당신이 만든 건 REST가 아니지만 괜찮아
  7. REST - 논문 읽기(To Do)

HTML Form에서 GET/POST만 지원하는 이유

쉬어가는 마음으로 다음 장을 위한 사전 지식을 하나 쌓아보자.

왜 PUT과 DELETE를 지원하지 않는가에 대한 정리

  • 일본어다. 구글 번역기를 돌려보자

PUT/DELETE를 Form에 넣으려는 시도는 위 글에서 가장 자세히 나오긴 했다.

(구글 번역이 훌륭하긴 해도) 일본어라 원본을 알아볼 수가 없으므로,
대신 stackexchange에 올라온 글로 짧게 정리해봤다.

  • 초기 HTML5 draft에는 포함되어 있었고 Firefox의 베타 버전에서는 잠시 구현하기도 했었다.
  • W3C는 이 문제를 bug report 10671에서 논의를 했는데,
  • Mike Amundsen이란 사람이 언급하길
    • 리소스를 수정하기 위해 PUT과 DELETE를 실행하는 건 모던 브라우저의 XmlHttpRequest 객체를 사용하면 간단한데, 스크립트를 사용하지 않는 상황에선 쉽지 않다.
    • 이 패턴은 많은 일반적인 웹 프레임웍/라이브러리에서 기본으로 구현하고 있다.
    • (그리고 이를 우회하는 방식에 대한 문제를 언급함)
  • Tom Wardrop란 사람도 흥미로운 관점을 제시함
    • HTML은 HTTP와 떼려야 뗄 수 없는 관계다. HTML은 인간을 위한 HTTP 인터페이스다. 따라서 왜 HTTP에서 필요한 메소드를 모두 제공하지 않는 것인가에 대해 자동으로 의문을 가질 수 밖에 없다. 기계는 PUT과 DELETE를 할 수 있으면서 인간은 왜 안 되는가?
    • HTML이 시맨틱한 마크 업을 보장하는 데 많은 시간을 할애하면서, 시맨틱한 HTTP 요청을 보장하기 위한 노력을 하지 않았다는 것은 모순이다.
  • 결국 이 버그는 (HTML editor인) Ian Hickson에 의해 고치지 않는 것으로 결정났다.
    • “PUT을 form 메소드로 사용한다는 것은 말도 안 된다. 네가 form payload를 통해 PUT을 해야할 일은 없을 것이다. DELETE도 payload가 없어야만 말이 된다. 그러니 역시 form에서 제공할 이유가 없다.”
  • 하지만 포기하지 않고 추가 드래프트가 올라와 있다

일본어로 정리된 글에서도 왜 PUT과 DELETE가 Form에서 적합하지 않은지는 생각하진 않은 것 같다.

추가된 드래프트도 결국 애초의 HTML Form이 가진 기능/목적을 우회하여 Form을 활용한 PUT/DELETE를 실행할 수 있도록 Form의 기능 확장(extension)을 요구하고 있다.
여기에서 DELETE는 크게 이질감이 없지만, PUT의 경우 payload를 통해 헤더를 구성하는 방식을 제안하고 있다. 그 방식은 꽤나 어색해서 과연 HTML 에디터나 커뮤니티 차원에서 받아들일 수 있을지는 미지수이다.

이슈를 닫아버린 Ian Hickson 입장에선 Form에서 PUT/DELETE를 지원하는 게 너무 당연하게 말도 안 되는 일이라고 생각했을 것 같다. 이유는,

  • Form은 서버에 정보를 제출하기 위해 존재한다
  • GET과 POST는 form에 존재하는 대화형 컨트롤에 입력된 값을 보낸다
  • POST와 PUT의 가장 큰 차이
    • RFC2616에서는 ‘요청 URI의 다른 의미’라는 표현을 썼고
    • RFC 7231에서는 ‘동봉된 representation에 대한 다른 의도’라는 표현을 썼다
    • POST에서의 요청 대상 리소스는 동봉된 representation을 ‘처리하는’ 주체이고
    • PUT에서는 동봉된 representation은 대상 리소스의 상태를 대체한다. 즉, 리소스 자체가 되어야 한다
  • 따라서
    • GET은 form에 있는 정보를 줄테니 나에게 리소스(representation)를 줘
    • POST는 form에 있는 정보를 줄테니 이걸로 처리 좀 해줘
  • 라는 의미가 되지만,
    • DELETE에서 URI는 리소스를 정확하게 식별하고 요청을 보내기 때문에 form을 통해 값을 전달할 게 없으며
      • 권한을 획득하기 위해선 header를 이용해야할 것 같다
    • PUT도 전송해야할 것은 대상 리소스를 대체할 representation 그 자체인데, 대상 리소스더러 조각난 form 데이터를 처리하라고 보낼 수는 없는 노릇

연재 목록

  1. REST - 긴 여정의 시작
  2. REST - HTML Form에서 GET/POST만 지원하는 이유
  3. REST - 논문(요약) 훑어보기
  4. REST - REST 좋아하시네
  5. REST - Roy가 입을 열다
  6. REST - 당신이 만든 건 REST가 아니지만 괜찮아
  7. REST - 논문 읽기(To Do)

Representational State Transfer

바쁜 개발자들을 위한 REST 논문 요약

REST는 Representational State Transfer의 줄임말로, 웹을 위한 네트워크 기반 아키텍처 스타일이다. REST는 Roy T. Fielding이 그의 박사학위 논문 “Architectural Styles and the Design of Network-based Software Architectures” 에서 처음 소개하였다.

아하.

가장 중요한, Roy의 실제 논문을 아직 읽지 못했다. 논문의 대략적인 내용은 위에 링크를 걸어둔 이응준님의 블로그로부터 이해를 했다.

REST와 HTTP를 이해하기 위해 필수적인 representation의 개념도 그 분의 블로그에서 얻을 수 있으니 미리 보고 올 것을 권한다.

  • representation이란 용어를 단순히 ‘표현’이라고만 번역하기에는 뭔가 놓치는 의미가 있는 것 같아서, 일단은 계속 representation이라고 부르겠다

몇 가지 이해 안 되던 부분은 실제 논문으로부터 갈증을 해소하기도 했지만,

논문 전체를 자세히 해석해 나가기에는 지금 좀 지쳤으니 (언젠가) 후속으로 정리를 해야겠다.

지금 시점에는 내가 RESTful하게 설계할 일이 없을 것 같긴 하지만,

웹을 이해하기에는 꽤 좋은 관점이 들어있(다고 추측이 된)다.

REST 아키텍처 스타일

바쁜 개발자들을 위한 REST 논문 요약을 읽기에도 바쁜 개발자들을 위해 요약하자면,

논문에서 Roy는 소프트웨어 아키텍처, 네트워크 기반 어플리케이션 아키텍처, 네트워크 기반 아키텍처 스타일 등을 설명하고,

네트워크 기반 아키텍처의 요구사항, 해결해야할 문제 등을 제시하는데 이에 대한 해결책으로 REST 아키텍처 스타일을 제안한다.

REST는 소프트웨어 아키텍처가 아닌 아키텍처 스타일(architectural style)이라고 정의한다.

후속으로 올릴 REST에 대한 논쟁에서도 REST는 아키텍처 스타일이라고 여러번 강조한다.

많은 IT 용어가 건축에서 왔는데(건축 뿐이겠는가..), 영어권에서는 동일한 단어를 사용하는 서로 다른 용어(동음이의)가 우리말로 번역되면서 각각 다른 단어로 표현되곤 한다.

따라서 어떤 IT 용어가 가진, 원래의 단어에서 오는 뉘앙스나 메타포를 놓치는 경우가 많아 비영어권 국민으로서 참 아쉽다.

많은 REST 논쟁에서 REST를 이해 못하는 사람들이 좀 더 구체적으로 예시를 들어줄 것을 요구하면, 사람들은 REST가 아키텍처 스타일이라고 강조하는 경우가 많았던 것 같다.

아키텍처 스타일(architectural style)은 건축양식을 의미한다.

중세에 고딕양식이 유행을 했다는 말은 고딕양식에 기반해 건물을 설계하고 이 설계를 구현한 건물이 많았다는 말이고(내가 건축 양식의 문외한임은 미리 고백한다),

고딕 성당을 지으려는 설계자는 이 양식을 지키는 선에서 ‘알아서’ 설계를 해야한다.

시장은 설계나 세부 구현에 대한 이해없이 고딕 양식이라는 틀 안에서 요구사항을 제시할 것이고 그러다보면 설계에서도, 구현에서도 best practice가 퍼지게 되겠지.

수십개의 성당을 지어야 하는 작업 반장의 커뮤니티에서는 이 세부 구현이 곧 고딕 양식이다라고 인식될 수 있다. 그가 얼마나 뛰어난 작업 반장인지와는 상관없이.

물론 이런 식의 건축 양식이 시간을 두고 확립되었다면, REST는 태초에 명확한 제약사항이 존재했다는 차이가 있긴 하다.

기와집이라는 건축양식이 있다고 할 때, 청기와 주유소는 과연 기와집인가? (기와는 맞는데 집이 아닌가? 흠..)

아니라면 기와집이라는 건축양식을 현대에는 의미를 확장해야할 필요가 있지 않은가?

어쩌면 사회적 합의를 봐야할 지도 모르겠다.

REST처럼 작성자가 확실하며, 애초에 확실한 제약 사항이 있는 분야도 합의의 대상인가?


REST에 관해서는 온갖 블로그와 구현체에서 서로 다르게 해석하고 있다.

작성자의 역량 + 독자의 역량이 오해를 재생산하기도 한다.

그러니 지금 이 정리를 본 누군가도 역시 오해를 얻어가리라 믿는다. 나 때문이든 당신 때문이든.

우선 REST에 대해 알아보자.

API Design

생각해보니 내가 API를 제대로 만들어 본 적이 없었더랬다.

GraphQL이 재미있어 보이니 써보고는 싶은데,

사실 난 인증을 붙인 프로덕션 레벨의 코드를 만들어 본 적이 없다.

왜 좋은가를 설명하려면 널리 퍼진 아키텍처 스타일을 기반으로 설명하면 좋을텐데,

나는 REST는 설명할 수 있던가? HTTP는?

나는 정확히 설명할 수 없다.

그럼 해야지.

지금까지는 지식 습득의 드라이브를 발표를 통해 얻었다면, 이제 블로그에 정리하면서 익혀보려고 한다.

What to do

‘정확히 알기’ 그 첫번째 과정으로 API 디자인에 도전해본다.

이 시리즈가 끝날 즈음이면 나는

  • API 서버를 구축해서 인증을 붙여본다
  • 전통적인 RESTful API와 GraphQL 서버 모두 구현
  • REST에 대해 제대로 설명하게 된다
  • 여러 인증 과정을 경험해본다
  • HTTP에 대해 설명을 할 수 있게 된다

동시에

  • HTTP 완벽가이드 릴레이 세미나
    • HTTP 완벽가이드로 적당히 완벽히 알기(금새 또 적당히 적당히 하려는 버릇이..)
    • 여기에 몇가지 간단한 책(그림으로 배우는 시리즈)도 참고로 읽기

And how?

검색과 블로그와 책으로부터 얻은 지식을 에버노트에 거칠게 정리한 다음 블로그에 옮겨 담기로..

내가 은연 중 피하려고 했던 것들

기술 블로그와 신세 한탄이 섞여있겠지만,

익숙하지 않은 것을 시도해보기로 했다.

그리고 2017.05.18 오늘

오랜만에 제창된 임을 위한 행진곡

RIP. Chris Cornell

0%