컴퓨터 상식

REST API 정리

우리로 2020. 10. 28. 23:29

https://www.youtube.com/watch?v=RP_f5dMoHFc

 

이 강연의 내용을 정리하고 내 생각을 첨언했습니다.

 

REST 서론

 

WEB은 정보를 하이퍼텍스트로 연결합니다. WEB이 나온 유래를 생각해봐도 정보 공유의 목적이 컸으니까 어쩌면 당연하겠네요.

 

그 정보를

표현하는 형식은 HTML 

식별자는 URI 

전송 방법은 HTTP Protocol입니다.

 

1990 년 ~ 2000년 대, 웹이 폭발적으로 성장하죠. 

 

당시 대학원생이었던 로이 필딩은 "Web 생태계를 훼손하지 않고 (전송 방법인) HTTP를 향상시킬 방법이 있을까?"를 고민합니다.

 

 

그 답이 HTTP Object Model 입니다. 이걸 4년 뒤, 1998년에 REST라는 이름으로 발표합니다. 그리고 2년 뒤에 박사논문으로 발표합니다. 이 논문을 지금 우리가 읽고 있는거죠.

 

REST가 나온 배경을 알겠는데, 그럼 API는 뭘까요?

 

API는 Application Programming 인터페이스 입니다. 인터페이스는 대상을 추상화한거에요.

'추상화' 라는 건 내부 구현을 바깥에 노출하지 않는 것입니다. 이 추상화 덕분에 우린 골치아픈 일 없이 그 대상을 이용할 수 있습니다. 

 

예를 들어 달콤한 사과를 먹을 때 우리는 그 내부 화학구조를 인지하지 않습니다. 그 내부 구조를 몰라도 사과의 맛을 즐길 수 있어요. 자동차 운전하는 것도 그렇죠. 핸들을 돌리면 바퀴가 몇 도나 돌아가는 지 몰라도 돼요. 

 

우리에게 필요한 건 '사과의 맛', '핸들을 돌리면 바퀴가 돌아간다.' 정도인거죠. 

 

API도 마찬가지에요. Application Program이 어떻게 구현되어있는지는 모르지만 '내가 원하는 동작을 할거야'라고 생각하고 가져다 씁니다. 

 

우린 안을 알 수 없어요. 알 필요도 없죠.

그럼 REST API는 뭘까요?

 

REST를 준수하는 API죠. 동어반복이라 좀 싱겁나요? ㅎㅎ

 

REST API의 역사 

 

이 REST API의 역사를 들여다봅시다.

 

Microsoft가 원격으로 다른 시스템의 Method를 호출할 수 있는 RPC라는 프로토콜을 만들었는데 곧 SOAP으로 진화합니다. 최초의 API라고 볼 수 있는 Salesforce API(2000. 2) 가 SOAP를 사용합니다. 4년 뒤 flicker는 SOAP와 REST를 모두 제공합니다. 

 

당시에 SOAP보다 REST가 상대적으로 단순하고 규칙이 적고 쉬웠습니다. 그래서 SOAP는 인기가 추락하고 REST는 인기가 급증합니다. 

 

2008년에 CMIS라는 게 나오고 REST 바인딩을 지원하기 시작했는데,

 

이를 본 로이 필딩이 "REST가 아니다."라고 얘기했습니다. 그는

 

"REST API는 반드시 hypertext driven이어야 하고 REST API를 위한 최고의 버저닝 전략은 버저닝을 안하는 것이다."

 

라고 덧붙였죠. 현장과 로이 필딩의 생각이 너무나 다르죠.

 

Self-Descriptive Message와 HATEOAS

 

REST API는 REST 아키텍처를 따르는 API이고, REST는 분산 하이퍼미디어 시스템을 위한 아키텍처 스타일입니다. 그리고 이 아키텍처 스타일은 '제약조건의 집합'입니다. 따라서 REST가 말한 제약조건을 모두 따라야 REST라고 말할 수 있어요. 

 

많은 API가 6개 중 5개의 제약 조건을 잘 따르긴 합니다. 근데 Uniform Interface가 문제입니다. 그 중에서도 Self-Descriptive Messages, Hypermedia as the engine of Application State(HATEOAS) 가 준수되지 않고 있습니다.  

 

Self - Descriptive Message는 "메시지는 스스로를 설명해야 한다." 는 의미에요.

보시면 Content-Type이 text/html 이라고 나와있죠. 

이걸 보고 우린 response로 받아온 게 html 이라는 걸 "이해"할 수 있습니다. 이 Response Message의 내용이 'HTML'이라는 걸 알 수 있는거죠. W3C에서 HTML표준을 제정합니다 그 표준에 따라 Response의 data를 이해할 수 있어요. 그리고 Host Header를 통해서 이 요청이 "어디에 대한 요청"인지 알 수도 있습니다. 즉 Response Message만 보고도 이 메시지가 어떤 내용을 담고 있는지 파악할 수 있습니다. 

 

HATEOAS애플리케이션의 상태는 Hyperlink를 통해 전이(Transition)가 되어야 한다.는 의미에요.

HTML은 a 태그로 이 조건을 만족합니다.

<html>
<body>
<a href="www.naver.com"> naver.com </a>
</body>
</html>

 

그러면 이 API는 REST하다고 부를 수 있는거죠. 굉장히 많은 API가 이렇지 않다는 게 문제입니다. 

 

REST API를 구성할 때 꼭 Uniform Interface를 준수해야하는 이유

 

음, 이런 질문이 나올 수도 있어요.

"왜 꼭 Uniform Interface를 준수해야 할까요? 준수하지 않아도 웹 생태계는 잘 돌아가는데요"

 

그렇죠. 참 신기합니다. 웹은 브라우저, 운영체제, 기기에 상관없이 아주 호환이 잘돼요. 

 

자유로워 보이기만 하는 WEB 세상을 지키기 위해 많은 노력을 하는 이들이 있기 때문이죠.

EX)

W3C Working Group --> HTML 표준을 제정

IETF Working Group --> HTTP를 제정.

...

 

HTML5 첫 초안에서 권고안 나오는데까지 6년, HTTP/1.1 명세 개정판 작업하는 데 7년이 걸렸습니다. 

상호운용성(interoperability) 때문에 referer 오타를 아직도 못 고치고 있습니다. charset도 그렇고...(encoding이 맞는 말이죠) 

HTTP 416? 포기했습니다. (만우절... I'm a teapot ) HTTP/0.9도 아직 지원합니다. (대단...)

 

다시 원론으로 돌아와서 

 

Unifom Interface를 지켜야 하는 이유는 독립적 진화때문입니다.

 

서버와 클라이언트가 독립적으로 진화할 수 있도록 만들기 위해 Uniform Interface를 지켜야합니다. 결합도를 낮추는거죠.

 

그래서 서버가 변경되더라도(API, URL 변경 등) 클라이언트는 변경할게 하나도 '없어야만 합니다'. 만약에 서버 구조를 바꿀 때마다 클라이언트도 같이 구조를 변경해야한다면 얼마나 많은 에너지가 들겠어요. 개발자들은 매일 야근을 해야할지도 모릅니다.

REST가 웹의 독립적 진화에 도움을 준 부분

이 REST는 이미 웹에 많은 영향을 미쳤습니다. 

일단 HTTP 자체에 지속적으로 영향을 줬습니다. 예를 들면

· Host 헤더 추가(Self Descriptive Message),

· 길이 제한을 다루는 방법 명시

· URI에서 리소스의 정의가 "식별하고자 하는 무언가"라는 식의 추상적으로 변경

 

등이 있겠죠. 그래서 HTTP/1.1 명세 최신판은 REST를 언급합니다.

(HTTP와 URI 명세의 저자 중 한명이 로이필딩(REST 명세 만든 사람)이니까 어쩌면 이건 당연한거겠죠.)

 

다시 REST API로 돌아가봅시다.

REST API는 REST 아키텍처 스타일을 따라야 하는데, 따르지않는다고 했죠.

그래서 로이 필딩도 이렇게 말했어요.

 

"시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없으면 REST에 대해 따지느라 시간을 낭비하지마라."

 

결국 제약 조건을 따르지 않을거면 REST API라고 부르지 말라는거죠. 

 

우리는 선택의 기로에 섰습니다.

 

1. REST API 구현하고 REST API 부른다.(도전)

2. REST API 포기하고 HTTP API라고 부른다.

3. REST API가 아니지만 REST API라고 부른다(현재 상태)

 

REST API가 어려운 이유와 REST하게 만들어야 하는 이유.

 

REST하게 API를 짜는 게 힘든 이유는 Json의 영향이 큽니다. 많은 REST API가 Media Type으로 Json을 사용하는데, 자유도가 높은만큼 Self-Descriptive 제약을 만족하기가 힘들어요. HATEOAS도 그렇구요.

  HTML JSON
Hyperlink 됨(a 태그 등) 정의되어있지 않음
Self-Descriptive 됨(HTML 명세) 불완전 - 명세 없음(문법만 있음)

 

JSON은 별다른 제약조건이 없기 때문에 그 의미를 해석하려면 API 문서를 따로 만들어야 합니다.

 

IANA에 Media Type을 등록하거나 Response Message의 Profile을 이용해서 해당 API에 대한 명세를 안내할 수 있습니다. 

Profile의 형식을 이용한다는 건 

 

Link = "링크", rel = "profile" 이런식이죠.  (대신 Content Negotiation은 못합니다.)

 

이렇게 지킨 Self Descriptive는 확실히 확장 가능한 커뮤니케이션에 도움이 됩니다. 서버나 클라이언트가 변경되더라도 오고가는 메시지는 언제나 Self Descriptive 하므로 해석할 수 있기 때문이죠.

 

또한 HATEOAS을 잘 지키면 애플리케이션 상태 전이의 late binding이 가능합니다. 쉽게 말해서 서버가 클라이언트에게 주는 링크가 동적으로 변경될 수 있다는 겁니다. 그러면 서버 구조가 바뀌어도 클라이언트는 코드를 수정할 필요가 없습니다. 

 

HATEOAS를 지키기 위해 이 링크를 Response Body의 data로 처리하는 방법이나, JSON으로 하이퍼링크를 정의한 명세를 이용하는 방법도 있는데 기존 API를 명세에 맞게 모두 바꿔야 한다는 단점이 있습니다. 

또는 HTTP Header 중에 Link나 Location Header를 이용하는 방법도 있습니다. 여기에 들어가는 Hyperlink가 반드시 URI일 필요는 없고, 상태나 URI 템플릿 상관없고 '하이퍼링크만' 표현되면 됩니다.

 

간단하게 정리하겠습니다.

REST를 따를까 말까는 API 설계자들이 결정하면된다. 

REST를 따르겠다면 Self-Descriptive와 HATEOAS를 만족시키면 된다. 

 

 

REST에 대해 알아봤는데, 영상을 한번 보시는 걸 추천드려요. 정말 잘 정리되어 있습니다.