본문 바로가기

Backend/Architecture

REST란? RESTful API 설계, 장단점

REST (Representational State Transfer)

제 멋대로 해석하면 리소스를 보기 쉽게 표현하며 상태를 전송한다.
HTTP의 주요 저자인 Roy Fielding(로이 필딩)이 웹 설계의 우수성에 비해, 웹의 장점을 제대로 사용하지 못한다며 발표한 네트워크 아키텍처에요.

REST 원리를 따르는 시스템을 RESTful이라 하고,
REST 원리로 개발한 API를 RESTful API라고 부르면 되요.
또한, 열정적으로 REST를 옹호하는 사람들을 RESTarians라고 부른다고 하네요.

 

https://ko.wikipedia.org/wiki/REST

 

REST - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 둘러보기로 가기 검색하러 가기 대한민국의 힙합 음악가에 대해서는 R-EST 문서를 참조하십시오. REST(Representational State Transfer)는 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다. 이 용어는 로이 필딩(Roy Fielding)의 2000년 박사학위 논문에서 소개되었다. 필딩은 HTTP의 주요 저자 중 한 사람이다. 이 개념은 네트워킹 문화에 널리

ko.wikipedia.org

Applied to Web services (RESTful API)

URI and HTTP Method in a RESTful API

 

HTTP METHODS

Collection resource
https://gofnrk.blogspot.com/board
Member resource
https://gofnrk.blogspot.com/board/:id
GET 모든 리소스를 가져온다. (Retrieve) :id로 하나의 리소스를 가져온다. (Retrieve)
POST 리소스를 등록한다. (Create) 리소스를 등록한다. (Create)
PUT 모든 리소스를 교체한다. (Replace) :id로 하나의 리소스를 교체한다. (Replace)
리소스가 존재하지 않을 경우 생성한다. (Create)
PATCH 모든 리소스를 수정한다. (Update) :id로 하나의 리소스를 수정한다. (Update)
DELETE 모든 리소스를 삭제한다. (Delete) :id로 하나의 리소스를 삭제한다. (Delete)

PUT은 수정이 아니에요. 리소스를 교체하는 개념이에요.
예를 들어 존재하는 필드를 보내지 않으면 해당 필드의 데이터는 모두 null로 바뀌게 되요.
흔히 우리가 알고 있는 update의 개념으로 사용하는 메서드는 PATCH입니다.

URI Design (URI 디자인)

1. 리소스는 되도록 명사를 사용한다.
2. 슬래시(/)는 계층관계를 나타낸다. 마지막에는 슬래시(/)를 붙이지 않는다.
/users/me/profile (O)
/users/me/profile/ (X)

3. 밑줄(_)을 사용하지 않고 하이픈(-)을 사용한다.
(REST 방식이 아니더라도 그렇게 해주세요. URI는 밑줄쳐서 구분하는 경우가 많아서요
/users/me/profile-preview (O)
/users/me/profile_preview (X)

4. URI 경로는 소문자로 나타낸다. (RFC-3986(URI 문법 형식)
/users/me/profile-preview (O)
/users/me/profilePreview (X)

5. 파일 확장자를 포함하지 않는다.
확장자를 알려야한다면 Header에 Accept를 사용하면 되요.
/users/me/picture -Accept: image/png (O)
/users/me/picture.png (X)

6. 리소스 간의 관계 표현은 "/리소스/리소스ID/관계가 있는 리소스"로 설계한다.
/users/:userid/profile/boards/:boardid/comments
/flowers/:flowerid/colors/colorid

HTTP Status Code (HTTP 상태 코드)

실제 비즈니스에서 자주/가끔 보이는 상태코드만 정리해봤어요.

(개인적인 기준일 수 있습니다.)

200(OK, 성공) : 정상적으로 데이터를 응답받은 경우 (GET, PUT)
201(Created, 생성) : 스토리지에 리소스를 생성하는 경우 (POST, PUT 리소스 생성)
204(No Content, 콘텐츠 없음) : 정상적으로 처리했으나 body에 표시할 데이터가 없는 경우 (PATCH, DELETE 요청 성공)

302(Found, 임시 이동) : 원하는 리소스가 이동되어 리다이렉트시키는 경우
304(Not Modified, 수정되지 않음) : 캐싱 처리하는 경우

400(Bad Request, 잘못된 요청) : 클라이언트가 값을 잘못보낸 경우
401(Unauthorized, 권한 없음) : 인증하지 않은 상태에서 인증을 해야 사용할 수 있는 API를 요청한 경우
402(Payment Required, 결재 필요) : 결재를 해야 사용할 수 있는 API를 요청한 경우
403(Forbidden, 금지됨) : 권한이 없는 리소스에 접근한 경우
404(Not Found, 찾을 수 없음) : 리소스가 없을 때
409(Conflict, 충돌) : 리소스 충돌, 예를 들어 유니크한 리소스를 등록할 때 이미 존재하는 경우

422(Unprocessable Entity, 처리할 수 없는 엔티티) : 요청이 제대로 구성되었지만 비즈니스 오류로 인해 처리할 수 없는 경우, 409보다 조금 더 범용적인 의미로 사용

500(Internal Server Error, 내부 서버 오류) : 서버에서 발생하는 오류
503(Service Unavailable, 서비스를 사용할 수 없음) : 주로 점검 알림
504(Gateway Timeout, 게이트웨이 시간초과)

Architectural constraints (아키텍처 제한 조건)

Client-Server (클라이언트-서버) : 일관적인 인터페이스로 분리되어야 한다.
REST에만 국한되는 내용은 아니에요. 클라이언트와 서버를 분리하면 서로 간의 의존성이 줄어들어 유지보수가 용이하고 확장성이 좋아져요.

Statelessness (무상태성) : 
클라이언트의 컨텍스트가 서버에 저장되면 안된다.
각각의 요청 들어오는 메시지로 처리하기 때문에 구현이 단순해져요. 인증 처리는 클라이언트에 토큰 형태로 저장하고, 서버에서는 인증을 검증하는 기능만 구현되면 되요.

Cacheable (캐시 가능) : 
클라이언트의 응답을 캐시할 수 있어야 한다.
예를 들어, 모든 사용자가 같은 응답을 받는 데이터는 캐싱하여 응답시간을 줄이고 서버 부하를 줄일 수 있어요. 보통 Last-Modified나 E-Tag를 이용해서 구현해요.

Layered System (계층화 시스템) : 
서버는 계층화하여 구성할 수 있고 클라이언트는 이를 알 수 없다.
서버는 로드밸런싱, Proxy 등을 사용하여 계층화할 수 있어요. 하지만, 클라이언트는 중간 서버와 통신하는지 실제 서버와 통신하는지 알 수 없어야 해요.

Code on Demand <optional> : 
서버가 클라이언트에 코드를 전송하여 실행하게 한다. 

Uniform Interface (인터페이스 일관성) : 
아키텍처를 단순화시키고 작은 단위로 분리한다.

Advantages and Disadvantages (장단점)

Advantages (장점)

  • 검색엔진에 최대한 많은 페이지가 인덱싱되기를 원하는 경우 REST로 설계하고 html을 서버사이드 렌더링하여 sitemap을 형성하는 것이 깔끔해요.
  • 알아보기 쉬운거? API 명세서를 읽지 않고도 요청을 알아보기 쉽다는 것이 가장 큰 장점이라고 생각해요. 또한, 약간의 HTTP 상태코드만 알고 있어도 서버의 응답을 분석하기가 수월한 것 같아요. 사실 API 아키텍처에서 알아보기 쉬운 것보다 강한 장점은 없다고 생각해요.

Disadvantages (단점)

  • 비표준. 이 말은 공식화된 레퍼런스가 없기 때문에, 사람마다 다르게 해석하여 사용할 수도 있다는 뜻이에요. 이건 다른 API 아키텍처에 비한 단점이라기보다는 아쉬운 점이라고 보는게 맞는 것 같습니다.
  • 특정 클라이언트에서는 HTTP Method나 상태코드 중에 사용할 수 없는 것들이 있어요. 특히 SI 프로젝트에서 레거시(Legacy) 서버를 사용하는 경우 보안 상의 이유(대부분 낡은 잘못된 지식)로 방화벽에서 막아두는 경우도 있어서 잘 확인해서 해결해야 해요. 실제 프로젝트에 도입할 때에는 충분히 사전 검토할 필요가 있어요.
  • 실제 API를 개발할 때 REST로 디자인하면 답이 없는 경우(굉장히 복잡한 비즈니스)가 종종 있어요. 모든 케이스에 대해 완벽할 수 없다는 얘기에요. 설계자와 실무 개발자의 온도차라고나 할까요.

Shoud I use it? (꼭 써야하나?)

웹 페이지가 최대한 많이 검색엔진에 노출되길 원한다면, 위의 장점에서 언급하였듯이 REST로 URI를 설계하고 서버사이드에서 렌더링하는 것이 유리해요.

 

이런 경우가 아니라면?

쓰는 것은 본인 자유라고 봐요!
웹의 장점을 누구보다 잘 활용하여 설계하였고, 그만큼 완성도도 높아요.

웹 기반에서 개발하는 사람들이 처음 REST를 접하고 사용하다 보면, 저절로 고개가 끄덕여지는 아키텍처인 것 같아요.

 

특히, 간단한 웹사이트를 신속하게 만들 때 굉장히 효과적인 것 같아요.


그렇지만 굳이 물타기식으로 무조건적으로 따르지는 않았으면 좋겠어요.

결국에는 본인의 프로젝트에 맞는 아키텍처를 선택하는 것이 가장 좋아보이네요.

 

시간의 여유가 된다면, 더 좋은 아키텍처를 고민하고 설계하는 것도 개인이나 팀의 발전에도 좋은 영향을 줄 수 있지 않을까 생각해요.