도대체 뭐가 RESTful 이라는건가?

요즘에 웹에서 API 기능을 개발한다고 하면 RESTful 이라는 단어를 많이 듣게 된다. 특히 “Single Page WebApp(웹앱)”이 웹 기능을 개발하는 주류 방법이 되면서 더욱 자주 귀에 들린다.  여기에서 그럼 웹앱이라는 것이 뭔지 우선 짚어보고 가보자.  이걸 알아야지 왜 API가 필요한 것이며 그 중에서도 RESTful을 이야기하는지를 알 수 있을 것 같으니 말이다.

웹앱은 뭔가요?

위키페디아에서 이야기하는 웹앱은 다음과 같이 정의한다.

클라이언트/서버 프로그램을 이야기한다. 특이점이라면 모든 클라이언트 코드가 “웹 브라우저”에서 동작된다.

WebApp웹에서 동작되는 것이기 때문에 당연히 웹 브라우저에서 돌아가겠지만 약간 애매한 단어인 “클라이언트/서버”라는 단어가 보인다.  흠… VC++ 언어로 윈도우 클라이언트 프로그램을 만든 경우를 생각해볼까? 한번 설치한 다음에는 그냥 설치된 걸 실행해서 여러분이 필요한 작업을 한다.  실행할 때마다 매번 설치하고 실행하지는 않는다.

반면에 웹은 어떤가? 링크 하나를 누를 때만다 뭔가를 잔뜩 다운로드 받아야 화면이 넘어간다. 내려받는 것들 가운데에는 코드도 있고, 데이터도 있고, 화면도 있다. 뒤죽박죽이다.

클라이언트/서버 프로그래밍을 해본 경험이 이야기하는 바는 화면은 빤하다라는 것이다.   변하는 것은 오직 데이터일 뿐이다. 데이터에 따라 조합된 화면을 사용자에게 제공하면 된다.

웹앱은 이 개념을 웹의 세상에 도입했다.  Markup, CSS로 만들어진 클라이언트 화면과 자바스크립트 코드로 클라이언트를 만든다. 데이터는 Ajax를 활용해서 API 서버를 통해 얻어온다. 주소 조작(Address and history manipulation)을 통해 앱 내부 영역내의 화면 이동을 위해 웹 서버에 클라이언트 화면과 관련된 어떠한 것도 요구하지 않는다. 데이터가 필요한 경우에만 API 서버와 통신한다.

웹앱 개념의 개발을 통해 기존에 로직과 데이터가 범벅이 됐던 웹의 개발이 화면 + 로직 + 데이터로 깔끔하게 분할됐다. 특히 업무 처리와 관련된 부분이 API 서버 영역으로 명확하게 구분되었다.  이걸 유식한 말로 말하면 “Separate of Concerns” 라고 표현한다.  각 영역에서 해야할 일을 명확히 구분짓고, 그 영역에 집중할 수 있게 되었다. 아마도 FEE, SWE 라는 용어 구분 역시 이런 구분이 가능해졌기  때문에 구체화된 것이 아닐까 싶다.

어떻게 API를 만드세요?

그럼 API를 만드는 방법을 생각해보자. API는 좁은 의미로 보자면 클라이언트 프로그램과 서버 프로그램의 상호 규약(Interface)이다.   얼핏 생각해보면 문서에 주절이 주절이 규약을 정해놓고 그것대로 구현되어 있으면 되는거 아닌가?  당연하다.  하지만 우리는 모두가 공감하는 방법으로 개발하길 희망한다.

이러한 희망속에 90년대 말에 SOAP이라는 심플하면서도 절대로 심플하지 않은 개발 방식이 나왔다.  W3C에서 업체의 힘을 빌어 밀어부쳐볼려고 했던 이 규약은 그러나 “심플하지 않다” 라는 절대적 사실 하나만으로 폭망했다.  실제로 진행했던 프로젝트 가운데 하나에서 성능 테스트를 했을 때, RESTful 방식 대비 최소 10배 이상 느린 것을 확인했다.  이후에 다시는 SOAP을 사용하자는 이야기를 하지도 않았고 듣지도 못했다.

저는 RESTful 방식으로 개발합니다.

흠.

요즘 SWE 면접 질문에 대한 답으로 지원자가 흔하게 이야기하는 답이다. 정말?

RESTfulREpresentational State Transfer ful

제대로 파고 들어가볼까?

RESTful, 제대로 하시는거죠?

대부분은 잘 한다고 이야기한다. 하지만 이야기를 하다보면 그리 잘 하는지에 대해서는 정말 ??? 를 두고 싶다.  대부분 RESTful을 한다고 했을 때

  • SOAP과 같은 RPC 형태가 아닌 URI Template의 형태로 요청을 보내고 받는다.
  • 물론 응답은 항상 JSON으로 API 응답을 내려야겠죠?
  • GET을 조회용으로 사용하고, “추가/변경”은 POST/PUT을 사용할려고 한다. 하지만 실제로는 글쎄… 아마 addXYZ 혹은 updateXYZ 등으로 하지 않을까? 물론 POST/PUT을 사용할 것이다. 왜 사용해야만 하는지는 물론 아실테고…

여기에서 더 있을까? 사실 내가 이 수준이었다. 공부하기 전에는. 그래서 사람은 공부를 해야하는 모양이다.

자, 그럼 정말 RESTful이라는 것이 지향하는 것이 뭘까 좀 더 살펴보자.

URI(Resource)/HTTP(Method)/Hypermedia(Link)

사실 RESTful이라는 이야기는 많이 들어봤지만 이 이야기는 전에 들어보지 못했다. RESTful WebService/API 구성과 관련해서 Leonard Richardson이라는 분이 이야기한 개념으로 아래 그림을 통해 살펴보면 빠르게 이해할 수 있다.

RESTful-Stack

API를 통해 우리가 클라이언트와 서버는 대화한다. API를 좁은 범위로 생각해보자.  그럼 API는 특정 리소스 혹은 데이터를 다룬다.  따라서 RESTful 방식에서 API를 설계할 때 URI가 이 리소스를 나타내도록 해야한다. 리소스를 물리적인 것도 될 수 있고, 추상적인 대상도 될 수 있다. 따라서 우리가 비즈니스를 통해 다룰려고 하는 대상 업무를 이런 리소스를 가지고 정의하는게 일반적인 접근일 것이다.

리소스를 다루는 가장 대표적인 방법이 C/R/U/D이다.  RESTful에서는 이것을 HTTP Method를 가지고 정의하도록 권고한다.  CRUD에 일반적으로 대응되는 HTTP Method는 아래와 같다.

  • Create – POST
  • Read or list – GET
  • Update – PUT or POST
  • Delete – DELETE

그런데 왜 권고일까?  HTTP 프로토콜에서 메소드가 의미 자체가 이런 Operation의 의미를 이미 가지고 있고 이미 개발자들 사이에 널리 퍼진 공감대이다.  또한 URI 혹은 다른 것으로 정의한다는 것 자체가 우리가 싫어하는 “중복”일 수 있다. 굳이 다른 토큰이나 키워드를 이를 위해 정의할 필요가 없다.

여기까지가 앞서 언급한 대충 우리가 아는 RESTful 방식이다.  중요하게 기억해야할 사항은 URI는 반드시 리소스를 나타내도록 해야한다.  “리소스”가 중요한 이유는 따로 아래 마이크로서비스 아키텍처 모델에서 좀 더 설명하도록 한다.

마지막 단계에 있는 “멀티미디어”는 그럼 당췌 뭘까? 우리가 구현하는 앱은 리소스를 가지고 CRUD만 하는게 다인가? 그게 목적이라면 그냥 DB에서 SQL 문장 돌리면 되지 굳이 이런 앱을 만들 필요는 없지 않을까?  의미있는 특정 동작을 하기 위함이다.  이 동작은 “리소스의 상태 변경(Transition)“으로 정의된다.  그럼 Transition이랑 멀티미디어랑 어떤 연관이 있을까?

HTML 문서에서 흔히 볼 수 있는 것이 바로 a href 링크다.  문서를 정보의 한 형태라고 가정해보자.  우리가 정보를 얻기 위해 한 문서에서 다른 문서로 사람은 링크를 클릭하면서 자신의 목적을 취한다.  이걸 기계적 관점에서 역으로 해석하면 사람이 보고 있는 문서는 “비즈니스의 상태“를 의미하며 링크를 클릭해서 다른 문서로 이동하는 것이 Transition이다. 한 문서는 다른 문서로 이동할 수 있는 경로를 a href 링크를 통해 사전에 정의한다. 비즈니스의 상태 역시 Transition할 수 있는 상태가 정해져있다.

API 호출은 앱이 처리하는 비즈니스의 상태를 A라는 상태에서 B라는 상태로 변경시킨다. 그리고 B 상태에서 이동될 수 있는 다른 상태 정보를 응답을 통해 알려준다.  이 응답은 현재 상태를 통해 앱이 다음 단계에서 할 수 있는 기능들이 뭔지를 알려준다.  아래 코드 예제와 같이 응답에서 이동 가능한 URI 정보들이 포함된다고 보면 된다.

<dap:link rel="http://relations.restbucks.com/payment" 
          mediaType="application/vnd.restbucks+xml" 
          uri="http://restbucks.com/order/1" />

Richardson Maturity Model

위의 계층 구조에서 바탕으로 우리가 현재 구현하는 RESTful 이라는 수준을 점검해 볼 수 있다. Richardson님이 위 스택을 기준으로 아래와 같이 단계를 구분해놓았다.

  • Level 0 – 하나의 URI을 가지고, 하나의 http method(mainly POST)를 사용한다. 내용에 대한 구분은 XML을 Payload로 사용해서 요청을 구분하는 방식을 취한다.  모든걸 하나의 리소스를 가지고 처리한다.
  • Level 1 – 다양한 URI를 사용하지만 http method((mainly GET)는 하나만 사용한다.  그나마 URI를 통해 요청이나 파라미터를 명시한다.
  • Level 2 – URI도 다양하게 사용하고, http method 역시 용도에 맞게 사용한다.  우리가 웹서비스라고 하는걸 이야기해보세요 하면 다 이 수준에서 이야기를 한다.  대체적으로 CRUD를 하는 웹서비스들이 여기에 포함되며, 대표적인 예는 Amazon S3가 여기에 포함된다.
  • Level 3 – Hypermedia를 활용해서 어플리케이션 상태 변화를 관리하는 수준을 말한다.  어플리케이션의 한 상태에서 다른 상태로의 이동 혹은 이동 가능한 상태를 링크를 통해 제시한다.

이 글을 읽고 있는 분들도 자신이 개발하는 RESTful API가 JSON을 응답으로 제고하는 수준에 머무는 정도인지 아니면 제대로 RESTful을 지향하는지 다시 한번 점검해보는 기회가 됐으면 좋겠다.

마이크로서비스 아키텍쳐와 함께 생각해보자.

앞서 언급한 사항 가운데 중요하게 기억해야할 사항은 URI는 반드시 리소스를 나타내도록 해야한다.  시스템을 Monolithic 방식이 아닌 마이크로서비스 아키텍쳐를 지향한다면 반드시 이 규칙을 따라야 한다.  RESTful 이야기를 하다가 왠 갑자기 뜬금없는 마이크로서비스 아키텍쳐라고?

마이크로서비스 아키텍쳐의 개념을 곰곰히 다시 생각해보자.  이 구조에서는 단위 업무들을 독립화시키고, 이들 업무가 서로 연합(Federation)될 수 있도록 한다.  연합에서 우리는 상대방이 어떤 시스템인지는 굳이 알 필요없다.  단지 연동 시스템이 우리가 필요한 API 규격을 준수하고 이를 제공한다라는 것을 알면 그만이다.  이를 구현하는 최적의 프로토콜이 바로 RESTful이라는 것은 두말할 필요가 없다.

RESTful-toMicroservice

그렇기 때문에 마이크로서비스 아키텍쳐 세상에서는 “리소스”가 시스템의 핵심이다. 해당 리소스에 대한 요청이 증가하거나 업무 로직의 부하가 커진다면 “리소스”를 처리하는 단위만 별도로 분리하는 방식으로 시스템을 확장한다.

물론 이와 같이 마이크로서비스로의 확장에서 서비스 시스템이 늘어나게 됐을 때 이를 Discovery할 수 있는 방안이 필요하다.  이 부분은 나중에 추가적으로 정리해보도록 하겠다.

일단 정리는 여기에서 마무리. ^^;

그래서 RESTful이라는게 뭐라는 건데?

아닌 것부터 이야기하면 JSON으로 응답을 내려주는거… 이건 아니다.

RESTful 방식으로 본인이 개발한다면

  • WHAT – (비즈니스 관점에서) 다룰 대상을 명확하게 인지하고 있고,
  • HOW – 어떤 상호작용들이 표준적인 방법(HTTP Method)으로 정의하였으며,
  • STATE – 일련의 상호작용으로 시작에서 끝에 이르는 상태 변화 과정을 거친다.

라는 것을 “각성“하라는 것이다.

최초의 SOAP을 필두로 웹서비스라는 기술적 개념이 태동했을 때 우리는 말 그대로 기술적인 관점의 가능성을 봤다. 대두되는 기술을 다시 한번 들여다봤을 때 그 안에서 우리가 한단계 더 나아가기 위해서는 기술을 어떤 관점에서 활용하고 적용하는게 올바른지를 꾸준히 생각해봐야 할 것 같다.

– 끝 –

8 Comments

  1. 멀티미디어 부분이 이해가 잘 안가서 그런데요.
    예를 들어
    앱에서 해당 글 공유하기를 눌렀을때 다른 앱들로 넘어가는게 멀티미디어의 링크라고 볼수 있나요?

    • Frontend 관점보다는 Backend 관점에서 살펴보시는게 빠르실 것 같습니다.
      쇼핑몰에서 “주문”이라는 개념을 가정해보면, 고객이 주문을 넣은 상태에서 “결제” 상태와 “취소” 상태 두 가지로 이동이 가능할 것 같습니다.
      이 두가지의 이동 가능한 상태를 보통 링크를 통해 Backend에서 링크(하이퍼미디어)의 개념으로 제공한다고 보시면 됩니다.

      HATEOAS라는 키워드로 검색해보시면 좀 더 다양한 정보를 얻으실 수 있을 것 같네요.

Comments are closed.