본문 바로가기

생각

여태 뜻도 모르고 써온 RESTful 이란 단어에 대해. REST API란?

서론

맨날 REST, RESTful, API 하는데 도대체 뭐냐

서버-클라이언트 구조를 갖는 서비스를 구현할 때 항상 API 서버를 이용하는 architecture 를 사용했다. 사실 내가 병아리시절 알던 API는 REST API 밖에 없어서 REST API 인 줄 알고 썼는데, 돌이켜보면 완전히 RESTful 했던 것은 아니었던 것 같다.

왜냐하면 API를 구현했을 때 GETPOST method만을 이용하기도 했었고, endpoint도 내 멋대로 지정하곤 했었다.(ex. /readMyItems, /foodByOwner 이런 식) 그리고 여전히 caching은 쉽지 않은 영역...

사실 Nexters라는 IT 동아리 면접 때

"RESTful이 뭐냐, REST API 가 뭐냐?"

라는 질문을 받았는데, 나름 잘 대답했던 것 같긴한데, 가슴에 손을 얹고, '야... 나 RESTful이 뭔지 솔직히 아냐..?' 고 묻는다면...'아니...' 였던 것 같다.

(http 가 뭐냐는 질문엔 아무말대잔치를 해버려서 '아... 면접 준비와 기본기가 중요하긴하구나...' 싶었다.)

그래서 기본기를 다지고자 정리해본다.

RESTful 하다의 정의, 원칙에 대한 견해.

개인적으로 일단 RESTful하다는 것은 형용사이므로 꼭 다 만족해야만 한다고 생각하진 않는다.

('예쁜'의 원칙이 있다고 쳤을 때 그 중 하나를 만족 안 한다고 '안 예쁜'으로 정의 할 수는 없듯이...ㅎ)

뭐 블로그마다 RESTful의 원칙!하고 제시된 내용들이 있는데, 잘 정리된 영문글을 참조하면 좋을 듯 하다.

개인적으로는 REST 라는 것이 Server-Client Architecture 중 하나라고 생각했는데, 공부하고 보니 Http Protocol을 이용하는 잘 짜여진 Architecture 자체가 아닐까싶다.

즉 종류라기 보다는 모범의 대명사 같은 느낌. ( REST API는 아니지만 좋은 API server는 GraphQL이 있을텐데, GraphQL 서버라고 해서 REST의 모든 요소에 대해 반대이진 않음. 겹치는 요소들이 많다. )

그럼 RESTful의 원칙들과 REST가 Web을 이용하는 단순히 Server-Client Architecture 의 한 종류가 아닌 그것에 대한 모범의 대명사라고 생각하는 이유에 대해 알아보자.

REST Architecture의 원칙들

Client-Server Architecture

: 당연히 REST는 Client-Server Architecture 임..

Stateless

: 그나마 "모범"에 대한 특징이 아닌 원칙. Stateful하다고 바람직하지 않은 Architecture는 아니니까..


StatelessStateful, Session에 관하여

Stateless란 어떠한 요청에 대해 요청자의 State를 관여하지 않는다는 소리. 즉 같은 요청을 A가 보낼 때와 B가 보낼 때가 같아야한다. 주로 server에 대한 Scaling 과도 관련이 깊은 요소이다.

Stateless할 경우 어떠한 클러스터 내의 어떠한 서버에 요청을 보내든 같은 결과를 얻을 수 있지만, Stateful한 경우, 예를 들어 A의 세션 정보가 A' 서버에 저장되어 있는 경우, A'서버가 아닌 B' 서버에 요청을 보내게 된다면, B'에는 A의 세션 정보가 없으므로 Authentication이 이루어질 수 없다. 하지만 이 또한 서버들이 공유할 수 있는 DB에 session을 관리함으로써 해결하기도 하므로 정답은 없는 것 같다.)


방금 설명했듯 REST 에서는 RESTful authentication 라는 키워드로 다양한 의견이 존재하는 듯하다. 대체로는 authentication을 다소 client 의 임무로 보는 경향이 있다.

Cacheable

: 일반적으로 캐싱이 안 되는 architecture가 좋은 Architecture라고 할 수 있을까...? 반대로 Caching을 이유가 있어 지원하지 않는다고 해서 RESTful하지 않다고 딱 잘라 말할 수 있을까싶다.

Uniform interface

: uniform한 형태를 띄지 않는다면 당연히 API가 늘어나고 사용자가 늘어날 수록 사용하기 힘들겠지...

HTTP 표준을 따르기만 한다면 어떠한 기술로든 API 를 사용할 수 있어야한다는 뜻.

JSON은 가장 유명한 방식일 뿐 꼭 JSON은 아니어도 된다.

Layered System

: RESTful한 서버는 보안, 로드밸런싱, 인증 등의 여러 계층으로 구성될 수 있다. 모듈화된 프로그램을 만들 듯이 각 계층을 분리시켜서 좀 더 오류를 찾기 쉽고, 관리 하기 쉽도록 하려는 것 같다.

클라이언트는 server의 정해진 url에 요청을 보내기만 하면 되고, 서버는 다양한 layer를 이용해 작업할 수 있다.

Code on demand(optional)

: 이건 optional한 항목이므로 원칙이 아니지 않을까싶음... 필요의 경우 client는 server가 전송한 code를 수행할 수 있어야한다는 의미인데, 애초에 REST는 Web에서 HTTP 를 이용해 브라우저든, 앱이든, 어떤 device와 runtime에서도 같게 동작하는 architecture인데, 그러한 architecture의 server에서 전송한 code를 실행한다는 것이... 조금 모순이 아닌가 싶다. code를 그대로 실행한다는 것이 보안이나 안정성에서도 이슈 있을 수도 있고.(만약 java로 짜여진 앱과 js를 이용하는 browser 가 있다면, 같은 코드를 실행할 수 없을테니.)

Self-Descriptive

: API 에 있어 문서화가 참 중요한 요소이기도 하지만 RESTful 하다면 API의 응답만 보고도 어떤 내용을 갖고, 무슨 행위를 하는 API 인지 직관적으로 알 수 있어야한다.


REST API 표현 방식

Method

익히 알고 있겠지만 다양한 HTTP Method 중에 4가지 GET, POST, PUT, DELETE 이용

Endpoint

endpoint는 행위가 아닌 resource 를 나타내어야하고 주로 명사를 이용한다. 동사의 역할은 Http method에게 맡김.

예를 들어 내가 처음 HTTP API를 접했던 Youtube API를 보자.

이런 식으로 commentThreads (명사)라는 resource 를 POST Method(동사, 생성)를 통해 이용한다.

한 때 내가 미흡하게 API Endpoint를 짜던 시절에 만약 어떤 채널의 구독자 명단을 얻으려했다면

GET /users/getUsers/fromChannelId/{channelId} 이런 식으로 짰을 것이지만 아마 이제는 GET /users?type=subscriber&channelId={channelId} 이렇게 좀 더 명확하고 알아보기 쉽게 짰을 것이다.

API 에 대한 보안

보안의 영역은 끝도 없기도 하고, 아직 내가 제대로 이해하기 힘든 부분들도 있다. 그래서 간단하게 생각을 정리해보는 정도로만 적는다. 주로 Authentication, Authorization을 다루고 터널링이나 방화벽, VPN 등의 내용은 생략한다.

Authentication(인증)

주로 사용하는 인증방식들

API Key - 주로 정확히 누가 API를 호출하는 가에 대한 Authentication(누구인가) 보다는 권한을 주는 Authorization(권한이 있는가) 의 기능을 함. 여러 클라이언트가 하나의 API Key를 이용하는 경우가 많다. 따라서 Key가 노출되었을 때의 타격이 큰 편.

API Token - API Key에 Authentication이 좀 더 강화된 느낌. client의 정보를 바탕으로 유효한 API Token을 발급해주고, 그에 따라 누가 API 를 호출하는 지 Authentication이 가능하다. Token은 기본적으로 유효기간을 갖고있고, 유효성을 검증받는다.

HTTP Authorization header - HTTP Protocol의 header에 들어가는 내용으로 Username:Password 꼴을 base64로 인코딩하여 전송함으로써 client의 정보를 담는다.

OAuth - 제3자(ex. 카카오, 페북, 구글) 에게 인증을 받음. OAuth 를 이용한 인증을 통해 Token을 발급받는데 이는 "방문증" 같은 것이다. 예를 올바르게 클라이언트가 OAuth를 통해 카카오 계정으로 인증을 했다면, 그 Token을 이용해 Server는 카카오 계정에 접근할 수 있다.

Authorization

Authorization은 크게 복잡한 것은 없는 것 같다.

주로 Role에 Permission을 부여하고, User 별로 Role을 부여받는 방식이거나

User 별로 직접 Permission을 부여받는 정도인 것 같다.

혹은 user의 정보 자체를 조회하여 권한이 있는 지 확인하는 방식도 사용하는 것 같다. (ex. 게시물 삭제 API의 경우, user가 Admin인지 혹은 게시물 작성자인지 체크한 뒤 맞으면 삭제)


아직 다루지 못한 내용

RESTful Authentication을 비롯하여 SSL, HTTPS, OAuth 등의 내용들. 아래 링크에도 적었지만 조대협님의 시리즈 글 중 3번 째 글에 정말 많은 내용이 있다... 다음에 시간이 된다면 좀 더 읽어봐야겠다.

API에 대한 캐싱 방법.

Http Header에 실리는 자세한 내용들.

content/type에 대하여

좋은 참고 자료

조대협님의 REST API 정리