REST와 RESTful API 정리
05 Jan 2021REST란
REpresentional State Transfer의 줄인 말로, 풀어 쓰면 나타낼 수 있는 자원들의 상태를 주고 받는걸 의미한다. 즉, 자원을 표현할 수 있는 것들로 구분짓고, 그 자원들의 상태를 주고 받는 것이다.
여기서 자원(Resource)은 흔히 말하는 데이터이며, 데이터는 DB에 들어가는 정보일 수도 있고, 사진, 동영상등 소프트웨어에서 관리하는 모든것을 의미한다.
REST는 HTTP 프로토콜을 그대로 사용하며, HTTP 설계의 장점을 그대로 살릴수 있는 아키텍쳐다.
REST API 란
서비스 API를 REST기반으로 구현한 것이다.
REST API는 자원(Resource)를 URI로 나타내고, 행위(Verb)를 HTTP Method로 나타낸다.
그리고 해당 자원에 대한 행위를 CRUD Operation으로 적용한다.
HTTP Method | CRUD | 설명 |
---|---|---|
POST | Create | 해당 URI의 리소스를 생성 |
GET | Read | 해당 URI의 리소스를 조회 |
PUT | Update | 헤당 URI의 리소스를 수정/갱신 |
DELETE | Delete | 해당 URI의 리소스를 삭제 |
REST의 6가지 원칙
1. Client-Server
- Client와 Server는 서로간의 의존성 없이 개발되어야 한다.
클라이언트는 자원의 URI만 알면되고, 그 외 비즈니스적 로직은 서버가 해결하며 서버는 자원을 API를 통해 클라이언트에게 제공한다.
서버 또한 클라이언트의 Context(쿠키, 클라이언트의 상태 정보 등)를 저장 하지 않고, Context는 클라이언트가 관리한다. 서로의 책임을 명확하게 하고 서로간의 의존성을 없앤다.
2. Stateless
- REST는 stateless하다(= 상태가 없다). 즉, 어떤 요청에 의한 작업을 할 때, 별도의 상태 정보가 필요로 하지 않다.
서버는 클라이언트의 Context 정보를 저장 하지 않는다.
이전에 클라이언트가 보낸 HTTP요청의 어떠한 상태 정보도 저장하지 않으며, 모든 요청을 별개의 요청으로 인식, 매번 새롭게 처리한다.
3. Cacheable
Caching(캐싱)은 HTTP에서 가장 중요한 기능 중 하나다. 캐싱을 통해 대량에 요청에 대한 서버의 확장성이 늘어나고 서버의 부하가 줄어든다.
REST는 HTTP 프로토콜을 사용하기 때문에, 캐싱 가능한 자원에 대해 캐싱이 가능하다 그리고 캐싱 가능한 자원에 대해 항상 Cachable 하다고 선언해줘야 한다.
4. Uniform Interface
- 자원은 자신을 나타내는 URI를 통해 노출되고, 사용된다.
REST에서 서버와 클라이언트의 서로간의 의존성이 없이 개발된다. 따라서 서로간의 규약을 지키며 개발되야 서로간의 통신이 가능하다. Uniform Interface는 REST를 위한 표준 인터페이스와 같다.
Uniform Interface에서 하나의 자원은 자신을 나타내는 하나의 URI를 가지며, URI로 지정된 자원들은 통일되고 한정적인 인터페이스로 동작한다.
5. Layered System
- 클라이언트는 API 서버만 호출한다. 하지만 호출된 API 서버 내부에선 Layered System로 계층화되어 구현되어 있을 수 있다.
클라이언트는 API 서버 하나만을 호출하지만, 호출 되는 API 서버 내부에서는 역할에 따라 서버를 나누고 다중 계층으로 구성될 수 있다.
예를 들어, 비지니스 로직을 처리하는 서버 A, 데이터를 저장하는 서버 B, 인증을 처리하는 서버 C와 같이 역할에 따라 서버를 나누고 다중 계층으로 구성 할 수 있다. 흔히 볼 수 있는 패턴인, 프록시, 게이트웨이 서버도 Layered System에 포함되는 개념이다.
6. Code on Demand (선택사항)
- 일반적으로 Static한, 정적인 리소스를 주고 받지만, 만약 필요하다면 실행가능한 코드를 스크립트나 애플릿 형식으로 응답 받을 수 있다.
해당 원칙은 필수적이지는 않다. 필요에 의해 선택 사항이다.
“RESTful하다” = 해당 6원칙을 지켜 구현한 웹서비스를 나타내는 표현
HTTP 응답 코드
REST한 HTTP 요청은 HTTP 상태 응답 코드로 응답한다.
REST API는 요청 시 URI, HTTP Method를 잘 지키는 것 뿐만 아니라 응답시 HTTP Status Code 또한 잘 지켜서 응답해야 한다.
1. 2xx Success 성공 응답
200 OK
요청이 성공적으로 처리됐습니다.
POST나 PUT일 경우, 해당 리소스가 성공적으로 처리된 수행결과가 응답 값에 전송됐다는 의미. GET일 경우, 해당 리소스가 응답 값에 성공적으로 불러와졌다라는 의미를 나타낸다.
201 Created
요청이 성공적이었으며, 새로운 리소스가 생성됐습니다.
일반적으로 POST 혹은 PUT에 대한 응답으로 온다.
202 Accepted
클라이언트의 요청은 성공적이었으나, 서버가 아직 요청을 다루고 있거나 프로세스를 처리 중에 있습니다.
예를 들면, 해당 요청이 배치에 등록되어, 배치가 돌아 간후 결과를 알 수 있는 경우 같은 비동기 처리일 때 사용된다. 클라이언트는 해당 요청에 대한 처리 완료 여부를 Callback 혹은 Polling을 통해 알 수 있다.
Callback: 해당 작업이 완료되면 서버가 클라이언트에게 알려주는 것
Polling: 해당 작업의 상태를 클라이언트가 주기적으로 서버에 요청을 통해 조회하는 것
204 No Content
요청은 성공적이나, 제공할 컨텐츠가 없습니다.
PUT을 통해 해당 자원을 수정하려 했으나, 수정된 내용이 없을 경우 혹은 DELETE를 통해 해당 자원을 삭제했을 경우 사용될 수 있다.
2. 3xx Redirection 리다이렉션 메시지
300 Mutiple Choice
요청에 대해 하나이상의 응답이 가능합니다.
POST요청에 대해, 응답 값이 캐싱된 값일 때 사용될 수 있다.
301 Moved Permanetly
요청한 리소스의 URI가 변경되었습니다.
클라이언트가 요청한 리소스의 대한 URI가 변경되었을 때 사용되는 응답 값. 응답 시, Location Header를 통해 변경된 URI를 표시해줘야 한다.
3. 4xx Error 에러 응답
400 Bad Request
요청이 유효하지 않습니다.
클라이언트의 요청이 잘못된 문법의 요청이거나 요청 유효성 검증을 통과하지 못했을 경우 사용된다.
예를 들어, 요청 필수 값으로 String 형태의 username이 필요 한데, Number 형식으로 username이 요청 왔을 경우 400에러를 응답한다.
401 Unauthorized
인증되지 않은 요청입니다.
인증되지 않은 클라이언트의 요청의 대한 응답값으로 사용된다.
예를 들어, 로그인이 안된 사용자가 사용자 정보를 요구할 때 401로 응답한다.
403 Forbidden
해당 요청의 대한 권한이 없습니다.
클라이언트가 해당 리소스에 대한 접근 권한이 없을 경우 발생. 인증이 된 클라이언트라 하더라도 서버가 응답하고 싶지 않은 리소스 일 경우 사용된다. 401
과의 차이점은 서버가 사용자가 누구인지 안다는 것이다.
예를 들어, 관리자만 접근 가능한 정보를 일반 사용자가 요청했을 경우 사용 가능.
403
자체가 해당 리소스가 존재한다는 것을 나타내기 때문에, 존재 유무 조차 나타내고 싶지 않다면 400
이나 404
를 사용하는 것을 권장한다.
404 Not Found
요청받은 리소스를 찾을 수 없습니다.
요청 받은 해당 경로가 존재하지 않거나, 경로에 요청한 자원이 존재하지 않을 경우 사용된다. 경로와 자원은 결국 URI에 포함된 것이기에 존재하지 않는 URI에 요청을 보냈을 때 사용되는 응답 값이다.
405 Method Not Allowed
허용되지 않은 HTTP Method입니다.
클라이언트가 요청한 리소스에 대해 요청한 HTTP Method가 사용 불가능 할 경우 사용되는 응답 값이다. 해당 자원은 존재하지만 HTTP Method가 잘못된 요청이란 의미.
4. 5xx Server Error 서버 에러 응답
500 Internal Server Error
서버 처리 중 에러가 발생 했습니다.
서버에서 해당 요청을 처리 중 에러가 발생했을 경우 사용되는 응답 값.
예를 들면, 잘못된 코드로 인해, 서버가 해당 요청을 처리하던 도중 NullPointerException이 발생 했을 경우, 내부 로직을 수행 할 수 없는 상태로 에러가 발생. 500 에러를 응답한다.
References
https://restfulapi.net/ https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html https://meetup.toast.com/posts/92 https://sanghaklee.tistory.com/61 https://developer.mozilla.org/ko/docs/Web/HTTP/Status