REST API 란 표현된 자원의 상태를 주고 받는 방법을 정리한 아키텍처 스타일이다.
첫번째 제약조건 : Client - Server
- api를 통해 정보를 교환하는 주체는 클라이언트와 서버구조를 가져야한다.
- 클라이언트와 서버의 분리를 통해 서로 의존하지 않는 구조를 가져야한다.
두번째 제약조건 : Stateless(무상태성)
- 클라이언트는 상태를 저장하지 않는다.
- 클라이언트의 각 리퀘스트는 서버가 리퀘스트를 이해하는데에 필요한 모든 정보를 포함해야 한다.
세번째 제약조건 : Cache(캐시)
- 데이터복사본을 임시 저장 위치에 저장하여 보다 빠르게 액세스할 수 있도록 하는 프로세스인 캐싱을 통해 네트워크 효율성을 높인다.
- 리퀘스트에 대한 리스폰스에 캐시 가능 및 불가능 여부가 들어있어야 한다.
네번째 제약조건 : Uniform interface(일관된 인터페이스)
- 전체 시스템을 잘 파악할 수 있도록 일관된 인터페이스를 제공해야한다.
- 이를 통해 구현체가 서비스와 별도로 독립적으로 진화할 가능성을 얻게된다. (예를 들어 클라이언트가 업데이트 되어도 서버를 함께 업데이트할 필요가 없어진다.)
다섯번째 제약조건 : Layered System(계층화된 시스템)
- 클라이언트는 서버에 직접 연결되었는지, 중간 서버를 통해 연결되었는지 알 수 없어야 한다.
여섯번째 제약조건 : Code on Demand(주문형 코드)
- 서버에서 보낸 코드를 클라이언트에서 실행할 수 있어야 한다.
- 선택적 제약 조건이며 지키지 않아도 REST에는 문제가 없다.
이렇게 6가지를 보면 괜히 어려워지는데, 서버-클라이언트 구조의 웹 서비스에서 HTTP프로토콜을 사용하여 리퀘스트와 리스폰스를 주고 받는다면, 네번째 제약조건을 제외한 5가지의 제약조건 대부분이 지켜지게 된다.
리퀘스트(클라이언트)와 리스폰스(서버)의 구조
=> 첫번째 제약조건 (Client-Server)만족
stateless(무상태성)과 connectionless(비연결성)
=> 두번째 제약조건(stateless)만족
헤더의 Cache-Control을 통한 캐시 가능 여부 명시
=> 세번째 제약조건(Cache)만족
레퀘스트와 리스폰스를 보내는 주체는 중간계층을 신경쓰지 않아도 되는 구조
=> 다섯번째 제약조건(Layerd System)만족
서버의 코드를 담을 수 있는 body
=> 여섯번째 제약조건(Code on Demand)만족
그렇다면 네번째 제약조건(일관된 인터페이스)은 어떻게 지킬 수 있을까?
이 제약 조건은 개발자가 api를 만들때 가장 영향을 많이 받는 제약 조건이다.
흔히 api를 만든다 라고 하면 어디로 어떻게 무엇을 담아 요청을 보내야 하는지를 정하게 되는데, 그것을 결정하는 제약 조건이, 네번째 제약조건인 일관된 인터페이스 제약조건이다.
네번째 제약 조건에는 4가지 하위 제약조건이 있다.
REST의 '자원의 식별'제약 조건은 접근하고자 하는 자원을 명시하고, 그 자원을 식별할 수 있어야 한다는 내용을 담고 있다. 웹에서는 URI를 사용하여 자원에 대한 식별을 하고 있는데, URI에 제어하고자 하는 자원에 대해 명시하고, 그 자원을 식별할 수 있는 변하지않는 ID와 같은 식별자를 URI에 포함시켜야 한다.
자원의 식별 제약조건을 지키도록 URI를 만들 수 있는 규칙
- 명사형 사용
URI는 동작(동사)을 가리키는 대신에, 자원(명사)를 가리켜야 한다. 자원에는 속성이 있듯이, 명사는 동사가 가지지않는 속성을 가지기 때문이다./members /articles
- 반환(응답)하는 자원의 종류에 따라 단수형/복수형 사용하기
여러개의 자원을 반환한다면, 복수형. 단 1개의 자원을 반환한다면 단수형을 사용한다./members #멤버목록(복수) /members/1 #멤버목록(복수)/중 1번멤버(단수)
- 계층 표현을 위하여, 슬래시 사용 (마지막엔 /를 붙이지 않는다.)
자원들간의 계층표시를 위하여 슬래시를 사용한다./articles /articles/1 /articles/1/comments
- 파일 확장자 붙이지 않기
/articles.html (X) /articles (O)
- 목록에 필터가 필요할 경우, 쿼리 문자열을 사용
/articles/1/comments?sort=latest
- URI에 동사 사용하지않기
/members/1/delete (X) DELETE /members/1 (O)
POST, PUT, PATCH는 HTTP리퀘스트에서 HTTP메소드가 다른것 이외에는 기술적차이가 없다. 즉, POST리퀘스트로 수정을 구현할 수 있고, PUT리퀘스트로 생성을 구현할 수 있다는 의미이다. 하지만 일반적으로 각 HTTP메소드 마다 정해진 의미대로 사용하는것을 권장하기 때문에 정해진대로 사용하는것이 RESTful하다.
상태코드는 굉장히 많은데, 자주 사용되는 상태코드들이 있다.
100번대 (정보응답)
100 Continue (계속)
- 요청의 첫 부분을 받아서 다음 요청을 기다리고 있다는것을 알려준다.
- 이미 요청을 완료 했다면 해당 응답을 무시할 수 있다.
200번대 (성공응답)
200OK (성공)
- 클라이언트의 요청이 성공적으로 처리되었다는것을 의미하며, 주로 요청한 페이지를 서버가 제공했다는것을 알려준다.
201 Created (생성됨)
- 요청이 성공적으로 처리되어 새로운 자원을 생성했다는것을 의미한다.
204 No Content(콘텐츠 없음)
- 요청을 성공적으로 처리했으며, 콘텐츠(body)를 제공하지 않는다는것을 의미한다.
300번대 (리다이렉션 메시지)
301 Moved Permanently(영구 이동)
- 요청한 자원이 새로운 위치로 영구 이동했음을 나타낸다.
- 클라이언트는 서버가 전달한 리스폰스의 location 헤더에 작성된 주소로 이동한다.
302 Found (임시 이동)
- 요청한 자원이 일시적으로 이동했음을 나타낸다.
- 클라이언트는 향후 다시 해당 자원을 요청할 때도 동일한 주소로 해야한다.
304 Not Modified (수정되지 않음)
- 마지막 요청 이후 요청한 자원은 수정되지 않았다는것을 알려주며, 서버가 콘텐츠를 전달하지 않는다.
- 클라이언트는 이전에 전달받은 자원을 계속해서 사용할 수 있다.
400번대 (클라이언트 에러 응답)
400 Bad Request (잘못된 요청)
- 클라이언트의 요청을 서버가 이해할 수 없을을 의미한다.
401 Unautorized (권한 없음)
- 클라이언트가 해당 요청에 대한 응답을 받기 위해서는 추가적인 인증이 필요하다는것을 의미한다.
403 Forbidden (금지됨)
- 클라이언트가 요청한 자원에 접근할 권한이 없음을 의미한다.
- 401과는 달리 인증된 클라이언트이지만 인가되지 않았음을 의미한다.
404 Not Found (찾을 수 없음)
- 클라이언트가 요청한 자원을 서버가 찾을 수 없음을 의미한다.
405 Method Not Allowed (메소드 허용되지 않음)
- 클라이언트가 요청한 HTTP메소드가 허용되지 않았음을 의미한다.
500번대 (서버 에러 응답)
500 Internal Server Error (내부 서버 오류)
- 서버에서 오류가 발생하여 요청한 작업을 수행할 수 없음을 의미한다.
502 Bad GateWay (잘못된 게이트웨이)
- 서버가 요청을 처리하는데 필요한 작업을 수행하던중 요청을 처리하는 중간 단계의 서버인 게이트웨이로부터 잘못된 응답을 받았음을 의미한다.
503 Service Unavailable (서비스 사용 불가)
- 서버가 해당 요청을 처리할 준비가 되지 않았음을 의미한다.
- 일반적으로 유지 보수를 위해 작동이 중단 되거나 과부하가 걸렸을때 나타나며, 일시적 상황에 사용된다.
504 Gateway Timeout (게이트웨이 시간 초과)
- 서버가 응답을 제한 시간안에 줄 수 없는 상태임을 의미한다.