REST API
일반적인 인식
- URI를 통해 자원을 지정한다
- HTTP 메서드로 자원에 대해 어떠한 행위를 할 것인지 명시한다
- 로이 필딩 (REST 개념 창시자)
- "내 논문 어디에도 CRUD에 대한 내용은 없다, HTTP 메서드는 REST가 아니라 웹 아키텍처의 일부이다"
- REST API란 REST 아키텍처 스타일에 부합하는 API 이다

REST의 조건
- Client - Server
- Stateless
- Cache
- Uniform Interface
- Layered System
- Code-on-demand

- 자원에 대한 식별
- 자원 : 이름을 지닐 수 있는 모든 정보, 개념적인 대상
- 자원 = 객체 : 객체의 상태는 변화하므로 변하지 않는 고유의 식별값이 필요하다. 즉 URI를 통해 자원을 식별해야 한다.
- 예) 파일, 문서, 사람 등
- 표현을 통한 자원에 대한 조작
- 표현 : 특정한 상태의 자원에 대한 표현
- 자원은 다양한 방식으로 표현이 가능하다
- 예) 파일, 문서, HTTP 엔티티 등
- 현재 상태를 표현 : 클라이언트가 'user/1' 에 get 요청을 전송하면 서버는 'user/1'의 현재 상태를 HTTP 엔티티로 전송한다
- 기대되는 상태를 표현 : 클라이언트가 자원의 기대되는 상태를 'image'로 표현하여 서버로 post 요청을 전송하면 서버는 이 표현을 바탕으로 새로운 이미지 자원을 생성하고 '/image/1' 이라는 식별자를 할당한다
- 즉, REpresentational State Transfer (표현된 (자원) 상태 전송)
- 자기 서술적 메세지
- 메세지는 스스로에 대해 설명해야 한다.
- 누구에게? 기계(컴포넌트)에게 설명해야 한다.
- 클라이언트와 서버 사이에는 수많은 컴포넌트(중개자)가 존재한다. 컴포넌트는 메세지의 내용을 참고하여 적절한 작업을 수행한다.
- 예1) Host 헤더 필드에 도메인명을 기재해야만 자기서술적이라고 볼 수 있다.
- 가상호스트 문제 : 하나의 IP 주소에 복수의 도메인명이 존재하는 가상 호스트가 존재할 수 있어 IP주소만으로는 요청 대상을 찾아낼 수 없다. HTTP 1.1부터 Host 헤더 필드에 도메인이 기재되지 않은 요청은 서버에서 거절해야 한다고 스펙에 명시
- 예2) 캐시 관련 헤더를 통한 캐시 전략 지정
- 클라이언트와 서버 간에 첫번째 요청에서 특정 컴포넌트에 일정 기간동안 캐시에 넣는 경우 두번째 요청부터는 서버까지 찾아가지 않아도 해당 컴포넌트로부터 캐시된 데이터를 제공받을 수 있다
- 예3) HATEOAS (Hypermidea as the Engine of Application State) : 하이퍼미디어를 통한 어플리케이션 상태를 변경할 수 있는 엔진(인터페이스)을 제공해야 한다.
- 개별 URI를 일일이 기억하는 것이 아니라 HTML의 a 태그 등을 활용해 페이지 이동이 가능하다. 이것을 어플리케이션 상태 변경이라고 한다.
- 의문 : 이것은 프론트엔드의 영역이 아닌가?
- 만약 서버가 a 태그에 담긴 html을 그대로 전송한다면 HATEOAS를 위배하지 않았다고 주장할 수 있다.
- 그러나 일반적인 API는 프론트엔드와 백엔드 사이에 JSON 형식의 데이터를 주고 받고 프론트엔드는 JSON을 통해 화면을 구성한다.
- 그렇지만 JSON에 URI등 서버에 요청하는 정보를 포함시키면 HATEOAS에 위배되지 않았다는 것이 많은 사람들의 주장
- 이렇게까지 REST를 추구해야 할까?
- 로이 필딩 "만약 본인이 개발하는 시스템에 대해 완전히 통제할 수 있다고 생각한다면 REST에 부합하는지 아닌지에 대해 시간을 낭비하지 말라", "Uniform Interface 제약 조건은 기본적으로 비효율적이다. 상황에 따라서 최적이 아닐 수 있다"
API 설계의 방향성
- 진짜 REST API 만들기 (aka.로이 필딩의 RESTful API)
- 그런 REST API로 괜찮은가 이용준 님 유튜브 영상 참고
- 로이 필딩의 박사 논문 Chapter 5,6 참고
- Spring 공식 문서의 Spring HATEOAS 프로젝트 참고
- REST 스타일을 참고한 API 만들기 (aka. HTTP API)
- REST 제약조건 부분적으로 준수(URI 자원 명시)
- HTTP 스펙을 적절하게 활용
- 일반적인 API 컨벤션 참고
- microsoft github - REST api guidelines (그러나 이런 API를 함부로 REST 라고 생각하지 말 것, http 기반으로 만들어졌다고 해서 무조건 REST라고 부르는 경향 있음)
- 다른 API 표준 선택하기 (e.g. graphQL API)
- graphQL API : '/graphql'이라는 단일 엔드포인트만을 제공, URI 자원 명시 조건 위배
- spring for GraphQL 공식 문서 참고
참고 : 정의 REST API