REST API, HTTP - Before You Study Spring (2)

강지혁·2022년 8월 22일
2

Before You Study Spring

목록 보기
3/3

지난 게시글에서 웹서버와 WAS에 대해 정리하면서, 서버 애플리케이션의 발전 흐름을 다루었다.
이번 시간에는 RESTful API의 의미를 타고 들어가면서, 애플리케이션 서비스 간 통신의 발전 과정도 겸사겸사(?) 담아보려고 한다.

🐦 들어가기 전 잡담

동아리 세미나를 준비하면서, 작년에 준비했던 자료를 좀 돌아보고 있다.
갓 휴학했을 때 쯤 만들어뒀던 것이라서, 확실히 뭔가 학생다운(?) 느낌이 많이 나는 것 같다. ㅋㅋㅋㅋ

와플스튜디오 서버 세미나에서는 REST API 서버를 구축하는 법에 대해 설명한다.
그리고 요즘 대부분의 서버는 RESTful 하게 개발한다..고 한다.

그러면 자연스럽게 드는 질문.

  1. RESTful 하다는게 뭘까?
  2. 왜 RESTful하게 만들게 되었을까?

자료에서 기본적인 HTTP 프로토콜의 구성과 REST 정의들을 깔끔하게 다루고 있기는 한데,
RESTful API 라는게.. 파고 들어가면 생각보다 더 혼란스러운 것이더라 😅

그래도 REST의 탄생 맥락과 사용 흐름에 대해서 한 번 정리가 되면 좋을 것 같아서 블로그에 남겨두고자 한다.

(혹시 HTTP에 대한 이해가 선행되어있지 않으신 분들을 위해 HTTP도 정리를 해두었다. HTTP가 뭔지 정의하는 것이 힘들다면, HTTP 섹션부터 읽으면 되고, 아니라면 그냥 아래 섹션부터 보셔도 될 것 같다.)

RESTful API에 대한 통상적인 시각

REST : Representational State Transfer
API : API (😅)

세미나 같은 곳에서 RESTful API를 소개한다거나 할때의 통상적인(?) 개념을 설명하라고 하면, 개인적으로는 아래 문장 정도로 요약할 것 같다.

REST API는 클라이언트-서버 서비스 간 통신을 잘 수행하기 위한 인터페이스다. URL을 통해 자원(Resource)을, HTTP METHOD를 통해 자원의 접근(Access)를 정의한다.

(아래 이미지는 AWS의 설명 일부를 발췌한 것)

REST API의 주된 용도는 '시스템 간'의 커뮤니케이션이다.
네트워크 및 비즈니스 애플리케이션들이 발전함에 따라, HTTP & HTML을 하나의 서버가 고객(유저)한테 바로 서빙하지 않고, 시스템끼리 정보를 주고받는 경우가 더러 생겼다.

이렇게 서비스끼리 정보를 주고받는 세상에서 가장 중요한 것은, 유연성과 독립성이다.
아무도 서드-파티 애플리케이션의 변경사항으로 인해 본인 앱이 수정되어야 하는 상황을 원치 않는다. (Git이 정말 엉망진창이 될 것이다.)

따라서 클라이언트-서버 간의 통신에서

  1. 구체적인 프로그래밍 언어나 기술 스택을 분리하고도, 서로 알아먹게 이야기 할 수 있으며
  2. 특별하고 복잡한 규칙, 라이브러리 없이 범용적으로 쓸 수 있는 API 디자인이 필요하다.
  3. 마지막으로 변경 사항에 강인한 표준 형식이 잘 지켜져야 한다.

RESTful API는 단순한 스펙을 바탕으로 서비스 간 통신을 지원한다.
특별한 뭔가가 그래서 사실 없다. HTTP만 잘 이해하고 있으면, 자원에 대한 접근을 HTTP 메시지에 잘 녹여내는 것으로 충분하다고도 할 수 있는 것이다.

REST API의 특징

REST API에는 6가지의 특징이 있다.

  1. Client - Server
  2. Stateless
  3. Cache
  4. Layered System
  5. Code-on-Demand (optional)
  6. Uniform Interface

6번 Uniform Interface가 REST API의 핵심이다.

  • 1~4 : HTTP를 잘 사용하는 것만으로도 충족이 되고
  • 5번 : 서버가 클라이언트에게 실행 가능한 코드 (ex: js) 를 제공할 수 있어야 한다는 것인데, 상술되어있듯이 안 지켜도 된다.

Uniform Interface

앞서 표준 형식이 필요하다는 이야기를 했는데, REST는 엄격한 Uniform Interface를 지킬 것을 제안한다. 그래야지만, 웹 세계에서 빈번한 스펙 변경이나 기술의 업데이트와 무관하게, 안전하고 지속 가능한 통신이 가능하니까..!

그 조건은 아래와 같다.

  • Identification of resources
    • 요청은 리소스를 식별할 수 있어야 한다.
    • URI만 보고 리소스를 확인 가능하다면, 조건을 만족시킨다.
  • Manipulation of resources through representations
    • 요청은 자원에 대한 접근을 나타내야 한다.
    • HTTP Method를 통해 접근을 잘 명시해주면, 조건을 충족한다 볼 수 있다.
  • Self-descriptive messages
    • 메시지는 스스로를 잘 설명할 수 있어야 한다 ❗️
  • Hypermedia as the engine of application state (HATEOAS)
    • 애플리케이션은 하이퍼링크를 통해 상태를 옮겨다닐 수 있어야 한다 ❗️

그런데 여기서 ❗️ 표시를 해둔 아래 두 조건은, 통상적인 RESTful API들이 거의 대부분 지키지 않는다. 두둥 탁..

REST API, 사실은 이렇습니다..

그런 REST API로 괜찮은가? 라는 내용의 강연을 바탕으로 재정리했습니다.

REST는 1998년, Microsoft Research에서 대학원생 로이 필딩에 의해 세상에 공개된다.
당시 빠르게 발전 중이던 HTTP에는 한 가지 문제가 있었는데,
"하위 호환성"을 지켜야 해서 쉽게 수정을 할 수가 없다는 것이었다.

REST는 이에 대한 대안이었다. 즉 REST란 필딩에 의해 고안된, 네트워크 기반의 소프트웨어들이 "잘 (수정사항으로 인해 구버전 웹들이 다 뭉개지지 않고)" 동작할 수 있는 하나의 아키텍처 디자인이다.

REST "API"

웹의 태동기에, API라는 것들도 줄줄이 탄생하기 시작한다.

API의 시초는 SOAP이라고 하는 형태의 프로토콜이었으나, REST에 기반한 API들이 훨~~씬 간단해서, 아래와 같이 시장은 REST API를 선택하게 되었다.

REST 그렇게 하는 거 아님!

그런데, 정작 창시자 로이 필딩은 REST가 쓰이는 방식이 마음에 안 들었다고 한다.
그 이유가 바로 상술했던 ❗️ 표시 조건들, Self-Descriptive, HATEOAS 조건을 제대로 지키고 쓰는 API들이 잘 없기 때문이라고 한다.

Self-Descriptive Message: 애플리케이션은 스스로를 충분히 설명할 수 있어야 한다.

애플리케이션에서 아래와 같이 Response 메시지를 가져갔다고 치자.
이러면 이 애플리케이션은 본인을 설명할 수 있을까?

HTTP/1.1 200 OK
Content-Type: application/json

[ { "op": "remove", "path": "/a/b/c" } ]

아니다. op, path가 무슨 뜻인지 메시지만을 보고는 이해할 수가 없다.

여기서 op, pathapplication/json-patch+json 미디어타입에서 약속되어있는 포맷인데, Content-Type을 이것으로 교체한다면, 메시지만을 보고 어떻게 해석할 지 확인할 수 있게 된다.

따라서 위 예제에서 엄격한 REST 스펙에 맞추기 위해서는, Content-Type 헤더를 교체해야 한다. 그 전까진 REST API는 아니다. (적어도 로이 필딩 기준에서는..)

HATEOAS: 하이퍼링크를 통해 앱 상태를 전이할 수 있어야 한다.

JSON 기반의 REST API 응답들은 대부분 HATEOAS 요건을 충족시키지 못하고 있다.
HATEOAS란, 하이퍼미디어 (:= 하이퍼링크) 등의 수단을 통해 앱 상태를 이리 저리 옮겨다닐 수 있어야 함을 의미한다.

아래의 Link 헤더는, HATEOAS를 만족시켜주는 다른 자원으로의 링크가 된다.

HTTP/1.1 200 OK
Content-Type: application/json
Link: </articles/1>; rel="previous",
			</articles/3>; rel="next";

{
	"title": "The second article",
	"contents": "blah blah..."
}

그러면 어떻게 해야할까..? 🥺

HATEOAS, Self-Descriptive 없는 API들은 '엄밀한 의미에서' REST API가 아니게 되었다.
그러면, 통상적인 의미에서 REST API를 개발해오던 우리는 모든 API를 REST 명세에 맞게 다시 수정해야 할까?

"REST emphasizes evolvability sustain on uncontrollable system. If you think you have control over the system or aren't interested in evolvability, don't waste your time arguing about REST." - Roy T. Fielding

로이 필딩의 대답은, NO이다.
대답을 이해하려면, 앞서 살펴봤던 REST의 출발 맥락을 같이 보면 된다.
REST는 근본적으로, 통제할 수 없는 (여러 곳에서 동시다발적으로 일어나는) 제각각의 HTTP 사용을 효과적으로 제어하기 위해 탄생했다.

따라서, 만약

  1. 시스템 전체를 통제할 수 있고,
    => 클라이언트, 서버가 같은 시스템 안에 있을 때, 통제 가능할 때
  2. 진화에 관심이 없다면
    => 업데이트나 변경에 대한 내성 측면의 진화를 의미하는 것 같다.

REST를 따지는 것은 불필요하다는 것이다.

이를 두고 해석하는 방식이 제각기 다른 것 같긴 한데, 회사 내부에서 REST API를 사용한다. 함은 곧 시스템이 조직 단위로 통제됨을 의미할 테니..

개인적으로는 엄격하게 REST API를 지키지 않아도 된다고 생각한다.
(이러한 형태를 여전히 REST API라고 부르는 것이 옳은지는.. 나도 잘 모르겠다 😅)

(사견) : 느낌만 가지자!

통상적으로 공유되는 REST API에 대한 느낌만 가져도 된다..고 생각한다.
엄격한 REST API의 마지막 두 가지 기준은, 알잘딱(?)하게 제껴도 된다는 것이다,,

앞서 OOP에 대한 글을 쓸 때, 프로그래밍은 결코 실무와 분리할 수 없는 영역이라고 나름의 견해표명을 해두었었다.

창시자(Roy Fielding)가 마음에 안 들어 할 수는 있지만, REST API는 통상적인 개념 (self-descriptive message, HATEOAS 빠진 version) 만으로도 클라이언트-서버 협업 방식에 큰 도움이 된다.

이미 이러한 "통상적" 견해를 기반으로 REST API 구축을 돕는 프레임워크 지원도 많아져있는 상태다.

따라서 굳이 진정한 REST API란 뭔지, 모든 것을 따질 필요는 없다고 생각한다.
다만 로이 필딩께서 왜 현재의 REST API를 못마땅하고 계신지,
REST의 출발이 무엇이었는지를 이해하고 있다면, 충분하지 않을까 생각함..!

REST 관련, 참고하면 좋은 자료들 :
Microsoft REST API Guidelines
https://github.com/wafflestudio/seminar-2021
https://www.redhat.com/ko/topics/api/what-is-a-rest-api

HTTP의 역사

HTTP가 뭔지는 사실 Mozilla 링크만 봐도 바로 이해하실 수 있다.
HTTP에 대해서는 맥락만 훑으면서 지나가겠다.

HTTP는 하이퍼텍스트를 전송하는 프로토콜이다.

CERN에서 일하고 계시던 Tim Berners-Lee 아저씨가, 부서 이동이 잦은 내부 사정 때문에 동료들끼리 서로 컨텍스트 공유가 잘 안되는 것이 불편해서 만드셨다.

(첫 웹 모습을 구경하고 싶다면 여기로)

인터넷에서 문서들이 공유되기 시작했을 때, 현실의 책과는 다르게, 링크 (하이퍼링크)를 누르면 다른 페이지로 슝~ 날라가는 시스템이 얼마나 멋져 보였을까?

그래서 그 당시 사람들은, 새로운 포맷의 문서들을 두고 이건 그냥 텍스트가 아니라 "하이퍼텍스트" 라고 불렀다.

이 때 WWW, HTML, HTTP가 탄생했다.

  • World Wide Web : 문서를 공유하기 위한 클라이언트
  • HTML : 하이퍼텍스트 마크업 언어, 즉 하이퍼텍스트를 표현하는 규칙 (언어)
  • HTTP : 하이퍼텍스트 전송 프로토콜, 서로 어떤 식으로 문서를 주고받을 것인지에 대한 규칙

HTTP는 이게 전부다. 웹에서 문서를 어떻게 주고받을 지 약속해둔 프로토콜이다.
흐름과 메시지 양식만 기억하면, HTTP에 대한 큰그림은 더 볼 것이 없다.

HTTP 클라이언트 - 서버 흐름

  • 정보를 교환하고 싶은 클라이언트와, 정보를 제공해 줄 서버가 존재한다.
  • 둘 사이 TCP 커넥션을 연다.
  • HTTP 양식에 맞춘 HTTP 메시지를 통해 클라이언트는 서버에게 응답을 요청한다.
  • 응답이 오면 읽는다.

HTTP 메시지

내가 자세히 설명하는 것보다, Mozilla 링크를 거는게 훨씬 낫다.

미니멀하게 기억하는 법은 아래와 같을 것 같다 ,,

요청 - METHOD, URL, HEADER, BODY
응답 - Status Code, HEADER, BODY

HTTPS

HTTP는 패킷이 갈취당하면, 무슨 내용이 오고가는 지 전부 보인다.
웹에서 점차 많은 것들을 공유하게 되었기 때문에, 통신 내용을 암호화할 필요가 있었다.
따라서 SSL 인증서를 바탕으로 안전하게 정보를 공유하는 HTTPS가 탄생했다.

HTTP/3

우리 세상의 법이 계속 발전하고, 바뀌듯이, HTTP도 발전하고 있다.
HTTP는 현재 HTTP/3가 최신이며, HTTP 3는 무려 올해 여름에 표준화되었다.

못다한 설명은 다른 뛰어난 개발자 분의 블로그 링크들로 대신한다..
HTTP/3: https://ykarma1996.tistory.com/86
HTTPS: https://brunch.co.kr/@sangjinkang/38
HTTP의 전체 흐름: https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP

0개의 댓글