RESTful 하다. (REST API와 RESTful 정리)
API 란
개인적인 정의입니다.
Interface의 정의:
- 복잡한 로직을 사용(접근)하기 편하게 구현한 것
API(application programming interface)의 정의:
- 앱 서비스에서 존재하는 사용자에게 제공될만한 기능들을 사용하기 편하게 구현한 것
ex )
- TV 리모컨 : TV 채널을 돌리기 위해서 일어나야할 리모컨 안에서의 복잡한 작업을 사용자는 알 필요도 없이 사용하기 편하게 버튼 하나 누름으로 채널을 바꿀 수 있게 구현하였다.
REST API 란
REST는 Representational State Transfer의 약자이며 해석하자면 상태(행동, 정보)을 나타낼 수 있는 전송이라 할 수 있습니다.
REST는 아키텍처 스타일이고 프로토콜이나 표준이 아닙니다. 그저 정보를 가진 쪽(server) 요청을 보내거나 받을 시의 통신과정에서
다음과 같은 구조적 형태(스타일)를 갖추고자 하는 것 입니다.
배경
HTTP 프로토콜이 사용되고 이 프로토콜을 버전업을 시키려하는데 기존 버전과 상호운용하게 할 순 없을까? 그리고 Server와 Client를 독립적으로 진화시킬 순 없을까? 에서 시작 됩니다.
그리고 로이 필딩이라는 학자가 REST 란 개념을 떠올렸고 이후 자신의 박사논문으로 확립시켰습니다.
당시엔 SOAP(Simple Object Access Protocol)이란 XML 전송 방식의 프로토콜이 있었지만 복잡함이 있어 REST에게 밀렸습니다.
형태
- 자원(Resource) : HTTP URI
- server에 있는 자원 인식자 ex) '/cats/1'
- 자원에 대한 행위: HTTP Method
- HTTP Method의 POST, GET, PUT, DELETE가 CRUD 동작에 매핑되어져 표현됩니다.
- 추가적인 표현(정보) (Representatioins): HTTP Message Pay Load
- Client가 자원에 대한 조작 요청 시 이를 보고 반응합니다. JSON, XML을 주로 선택합니다.
이 세 정보로 전송 시 그 전송이 어떠한 의도를 가지고 있는지 추측할 수 있습니다.
JSON 혹은 XML로 데이터를 주고 받습니다.
특성
- Server - Client 구조
- 한 쪽이 자원을 요청하고 다른 한 쪽이 자원을 제공하는 Server - Client 구조입니다. 필요한 정보들을 스스로 가질 수 있어 복잡함이 줄어듭니다.
- Stateless(무상태성)
- HTTP 프로토콜을 바꾸지 않고 내부 스타일을 정한 것이 기에 HTTP 프로토콜이 Stateless(무상태성)을 가집니다. 통신하는데 있어서 서로에 대한 정보를 저장하지 않습니다. 즉 각 요청을 완전히 별개의 것으로 인식하고 처리하게 됩니다. 처리방식에 복잡함이 줄어듭니다.
- Cacheable(캐시 가능)
- HTTP 프로토콜을 따르기에 Last-Modified, E-Tag 태그를 사용하여 캐싱이 가능합니다.
- Layered System(계층화)
- 계층화를 하여 앞단에 로드밸런서, 시큐리티, 프록시 등을 둘 수 있어서 유연합니다.
- Client가 직접 엔드 서버에 연결할 필요가 없게되니 보안성이 높아집니다.
- Uniform Interface(일관적인 인터페이스)
- Resource 조작을 일관성있게 수행한다. 다양한 환경에서 독립적으로 사용할 수 있습니다.
- Server-Client의 결합도를 낮춥니다.
- Code-On-Demand(선택사항)
- Client가 응답을 받고 처리할 때 어떻게 처리할 지에 대한 Code를 Server로부터 제공 받을 수 있습니다.
장점
HTTP 프로토콜을 그대로 사용하여 추가적인 환경변경이 없습니다.
유연한 구조, 캐싱을 통한 성능향상 기대가 가능합니다.
Server와 Client가 독립적으로 발전할 수 있습니다. (Server의 기존 API가 내부적으로 바뀌었다 하여 Client에서 반드시 바꿀 필요는 없습니다.)
(특성 부분과 비슷한 내용입니다.)
단점
표준이 존재하지 않기에 환경마다 다 다른 형태를 지닐 수 있습니다.
사용가능한 Method가 4개라 구체적인 행동을 표현하기에는 한계가 있을 수 있습니다.
point-to-point 통신모델을 기본으로 하여 Server와 Client가 연결을 맺어야하는 경우에 적합하지 않습니다.
보안에 관한 부분이 없습니다.
RESTful 이란
그래서 RESTful이란 REST한 특성을 잘 나타내는 API를 이르는 말입니다.
개인적으로는 위와 같은 특성을 가지면서도 REST API 형태만 보고도 그 행동을 짐작할 수 있게 만들어진 API라고 생각합니다.
Uniform Interface 제약조건
- 자원을 식별 할 수 있어야 한다.
- URL(Uniform Resource Locator) 만으로 어떤 자원을 제어하려하는 지 알 수 있어야한다. 자원의 위치와 종류도 알아야 한다.
- Server가 제공하는 정보는 JSON이나 XML의 형태로 HTTP body에 포함되어야 한다.
- 행위는 명시적이여야 한다.
- 의미적으로 일관성 있게 HTTP Method와 URI를 정해서 만들어야한다.
- 자기 서술적이여야 한다.
- 데이터에 대한 메타정보만으로 어떤 종류의 데이터인지, 데이터를 위해 어떤 애플리케이션을 실행해야 하는지 알 수 있어야 한다.
- 정보를 얻기 위해 데이터 원본을 봐야만하게 하는 일은 일어나선 안된다.
- HATEOAS(Hypermedia as the Engine of Application State)
- 클라이언트 요청에 대해 응답을 할 때, 추가적인 정보 제공의 링크를 포함해야한다. 독립적인 컴포넌트 사이에 연관관계를 주기 위함이다.
- 서버의 링크가 바뀌어도 HATEOAS를 위해 포함된 링크를 따라 가면 되기에 Server의 진화에 Client가 유연하게 대처할 수 있다. 즉 SErver와 Client가 독립적으로 진화할 수 있게 돕는다.
REST API design guide
URI
- 도큐먼트 : 객체 인스턴스나 데이터베이스 레코드와 유사한 개념
- 컬렉션 : 서버에서 관리하는 디렉터리라는 리소스
- 스토어 : 클라이언트에서 관리하는 리소스 저장소
- URL는 정보를 자원을 표현해야 한다.
- resource는 동사보다는 명사를, 대문자 보다는 소문자를 사용한다.
- resource의 도큐먼트 이름으로는 단수 명사를 사용해야한다.
- resource의 컬렉션 이름으로는 복수 명사를 사용해야한다.
- resource의 스토어 이름으로는 복수 명사를 사용해야한다.
- Ex) GET /Member/1 → GET /members/1
- 자원에 대한 행위는 HTTP Method(GET, PUT, POST, DELETE 등)로 표현한다.
- URL에 HTTP Method가 들어가면 안된다.
- Ex) GET /members/delete/1 → DELETE /members/1
- URL에 행위에 대한 동사 표현이 들어가면 안된다. (즉, CRUD 기능을 나타내는 것은 URL에 사용하지 않는다.)
- Ex) GET /members/show/1 → GET /members/1
- Ex) GET /members/insert/2 → POST /members/2
- 경로 부분 중 변화하는 부분은 유일한 값으로 대체한다. (즉, :id는 하나의 특정 resource를 나타내는 고유값이다.)
- Ex) student를 생성하는 route : POST /students
- Ex) id=12인 student를 삭제하는 route : DELETE /students/12
- 슬래시 구분자 ( / )는 계층 관계를 나타내는데 사용한다.
- URI 마지막 문자로 슬래시 ( / )를 포함하지 않는다.
- 즉 URI에 포함되는 모든 글자는 리소스의 유일한 식별자로 사용되어야 하며 URI가 다르다는 것은 리소스가 다르다는 것
- 역으로 리소스가 다르면 URI도 달라져야 한다.
- 하이픈 ( - )은 URI 가독성을 높이는데 사용한다.
- 밑줄 ( _ )은 URI에 사용하지 않는다.
- URI 경로에는 소문자가 적합하다.
- URI 경로에 대문자 사용은 피하도록 한다.
- 파일확장자는 URI에 포함하지 않는다.
- REST API 에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않는다. 대신 Accept Header 를 사용한다.
- ex) GET: http://restapi.exam.com/orders/2/Accept: image/jpg
- 리소스 간에 연관 관계가 있는 경우
- /리소스명/리소스ID/관계가 있는 다른 리소스 명
- ex) GET: /users/2/orders (일반적으로 소유의 관계를 표현할 때 사용)
응답상태코드
- 1XX : 전송 프로토콜 수준의 정보 교환
- 2XX : 클라이언트 요청이 성공적으로 수행됨
- 3XX : 클라이언트는 요청을 완료하기 위해 추가적인 행동을 취해야 함
- 4XX : 클라이언트의 잘못된 요청
- 5XX : 서버쪽 오류로 인한 상태코드
현실
REST는 표준이 아니기에 환경에 따라 다 다른 형태를 지닙니다. 실제 REST API라 하는 것들을 봐도 자기 서술적, HATEOAS를 지키는 API를 찾기 힘듭니다. 그러니 RESTful을 의식하면서 자신의 문제와 환경에 맞게 REST API를 잘 설계하여 일관성 있게 관리하는 것이 더 중요해 보입니다.
참고자료
- https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_
- https://meetup.nhncloud.com/posts/92
- https://aws.amazon.com/ko/what-is/restful-api/
- https://spoqa.github.io/2012/02/27/rest-introduction.html
- http://amazingguni.github.io/blog/2016/03/REST%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4-1
- https://khj93.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-REST-API%EB%9E%80-REST-RESTful%EC%9D%B4%EB%9E%80
- https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
- https://hanamon.kr/rest-api/
- https://thalals.tistory.com/335#google_vignette
- https://www.redhat.com/en/topics/api/what-is-a-rest-api
- https://www.techtarget.com/searchapparchitecture/definition/RESTful-API
- https://velog.io/@somday/RESTful-API-%EC%9D%B4%EB%9E%80#rest%EC%9D%98-%EB%8B%A8%EC%A0%90%EB%93%A4
https://youtu.be/RP_f5dMoHFc