REST API는 Representaional State Transfer API의 약자로써,
REST 아키텍처의 제약 조건을 준수하는 API 를 의미합니다. 이 REST 제약 조건을 잘 준수함을 RESTful 하다고 표현합니다.
REST는 무엇일까?
REST는 표준 혹은 프로토콜 같은 것이 아니라, 일반적으로 통용되는 규약입니다.
따라서 아래의 내용은 정답이 아니라 일반적으로 권고되는 규칙입니다.
REST는 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하기 때문에 웹의 장점을 최대한 활용하는 아키텍처입니다.
또한 REST API 는 Stateless 하게 각 HTTP 요청은 서로 연관되지 않고 독립적이어야 하고, 따라서 요청과 요청 사이에 일시적으로 저장되는 상태가 없어야합니다.
REST API의 구성요소
- 자원(Resource)
REST API는 HTTP의 URI를 사용해 자원을 명시합니다. 이때 리소스란 클라이언트에서 접근할 수 있는 모든 개체, 데이터, 서비스가 포함됩니다. - 행위(Verb)
REST API는 HTTP의 Method (POST, GET, PUT, PATCH, DELETE 등)를 사용하여 명시된 자원에 대한 CRUD(Create, Read, Update, Delete) 명령을 실행합니다. - 표현(Representaion)
REST API에서 리소스는 다양한 형태로 표현될 수 있습니다. 가장 많이 사용되는 형태는 JSON이고, XML, TEXT, RSS 등의 표현이 존재합니다.
REST의 특징
1. 리소스 중심 디자인
그리고 REST API는 리소스 중심으로 디자인 됩니다. 즉, REST API는 비즈니스 엔티티에 집중해야합니다. 만드는 서비스가 이커머스라면 비즈니스 엔티티는 고객, 주문, 상품 등이 될 것입니다.
리소스는 각각을 고유하게 식별하는 URI가 존재하는데, 예를 들어 어떤 블로그 서비스의 특정 포스트 리소스는 아래와 같은 URI로 표현할 수 있습니다.
https://some-blog-service.com/posts/1
또한 많은 REST API가 요청과 응답의 형식으로 JSON을 채택합니다. 예를들어 위 요청에 대한 응답은 아래와 같을 수 있습니다.
{
"postId": 1,
"title": "REST API가 뭘까?",
"content": "REST API는 Representational Sta..."
}
리소스를 표현할 때 실제 저장된 데이터를 그대로 표현하려하지 않아도 됩니다. 포스팅이라는 리소스는 실제 관계형 데이터베이스에서는 여러 테이블이 Join 되어 표현되겠지만 (예를 들어 Posting 테이블과 Comment 테이블), 이 내부 구현을 그대로 리소스로 표현하지 않고, 포스팅이라는 단일 엔티티로 표현해보면
{
"post": {
"postId": 1,
"title": "REST API가 뭘까?",
"content": "REST API는 Representational Sta..."
},
"comments": [
{
"commentId": 1,
"content": "감사합니다"
}
]
} // BAD
{
"postId":1,
"title":"REST API가 뭘까?",
"content":"REST API는 Representational Sta...",
"comments":[
{
"commentId":1,
"content":"감사합니다"
}
]
} // GOOD
2. HTTP 메서드에 따른 API 작업 정의
RESTful 하게 구현된 REST API는 HTTP 메서드를 아래와 같은 행위에 맞도록 디자인합니다.
- GET
명시된 URI에 해당하는 리소스를 가져온다.
일반적으로 HTTP 상태 코드 200을 반환하고, 리소스를 찾을 수 없을 경우 404를 반환한다. 요청은 정상적으로 처리되었지만, 보여줄 데이터가 없을 경우 (예를 들어 검색결과가 없을 경우) 204를 반환한다.
- POST
명시된 URI에 새 리소스를 생성한다.
리소스가 성공적으로 생성되었을 경우 HTTP 상태 코드 201을 반환하고, 반환할 결과가 딱히 없을 경우 204를 반환한다. 리소스를 생성할 때 클라이언트가 잘못된 요청을 전송했을 경우 (예를 들어 양수여야 하는 필드를 음수로 전달한 경우) 400을 반환한다.
- PUT
명시된 URI를 새 리소스로 대체하거나, 없다면 새로운 리소스를 생성한다.
- PATCH
명시된 URI에 해당하는 리소스의 일부분을 업데이트한다.
PATCH는 앞서 이야기한 PUT과 비슷해 보이는데, 어떤 차이점이 존재할까? PUT은 리소스의 모든 정보를 업데이트 한다. 즉 새로운 리소스로 대체한다. 하지만, PATCH는 리소스의 일부분만을 업데이트 한다는 차이점이 존재한다.
- DELETE
지정된 URI에 해당하는 리소스를 제거한다. 삭제가 성공하면 응답으로 빈 본문을 반환하고, HTTP 상태 코드 204를 반환한다. 존재하지 않는 리소스에 요청한 경우 404를 반환한다.
3. REST 관점에서의 HTTP Status Code
REST API는 클라이언트의 요청에 대한 처리 결과를 HTTP Status Code를 이용해 표현할 수 있습니다.
2XX - 성공 응답
클라이언트의 요청이 유효하고, 서버도 그 요청을 성공적으로 처리했을 때 반환하면 적절한 상태코드이다.
- 200 (OK) : 클라이언트의 요청을 서버가 정상적으로 처리했음.
- 201 (CREATE) : 클라이언트의 요청을 서버가 정상적으로 처리했으며, 새로운 리소스가 생성되었음.
- 202 (Accepted) : 클라이언트의 요청을 서버가 정상적으로 수신했지만, 아직 요청을 완료하지 못했음. 서버의 작업이 오래걸릴 경우에 비동기적으로 요청을 처리하기 위해 사용하는 응답 코드이다.
- 204 (No Content) : 클라이언트의 요청을 서버가 정상적으로 처리했지만, 응답할만한 데이터가 없음. DELETE 등의 메소드를 사용하여 리소스가 제거되었을 경우, PUT 등의 메소드로 리소스를 업데이트 하였으나 변화가 없을 경우 반환하면 적절한 상태코드이다.
성공에 대한 응답을 모두 200 으로 처리해도 큰 문제는 없지만, 클라이언트에게 자세한 정보를 제공하기 위해서는 조금 더 적절한 상태 코드를 반환하는 것이 좋다.
4XX - 실패 응답
클라이언트의 요청이 유효하지 않을 경우 반환하는 상태코드이다.
- 400 (Bad Request) : 필수 필드 누락, 유효성 검사 실패 등 클라이언트의 요청이 유효하지 않을 경우 반환하는 실패 응답. 400 응답 코드와 함께 에러의 이유를 함께 Body로 명시해주는 것이 좋다.
- 401 (Unauthorized) : 인증정보(로그인 등)이 필요한 요청인데 불구하고, 인증정보가 존재하지 않은 경우에 반환하는 실패 응답. 이름만 보면 Authorize (인가) 관련 응답인 것 같지만, Authenticate (인증) 에 관한 응답이라고 한다.
- 403 (Forbidden) : 인증된(Authenticated) 클라이언트가 권한이 없는(Unauthorized) 경우 반환하는 실패 응답. 401 과 그 용도를 혼동하지 않도록 주의하자.
- 404 (Not Found) : 클라이언트가 요청한 자원이 존재하지 않을 경우 반환하는 실패 응답.
- 405 (Method Not Allowed) : URI에 해당하는 자원은 존재하지만, 요청한 메소드를 허용하지 않을 경우 반환하는 실패 응답. 예를 들어 GET 메소드로 접근할 수 있는 자원이지만 PUT 으로 수정은 허용하지 않을 경우에 반환하기 적절한 상태코드이다.
- 409 (Conflict) : 클라이언트의 요청이 서버의 상태와 충돌이 발생한 경우 반환하는 실패 응답. 충돌의 의미가 굉장히 모호하여 명확한 기준을 세우는 것이 중요할 것 같다.
- 429 (Too Many Requests) : 클라이언트가 단기간에 너무 많은 요청을 보냈을 경우 응답하는 실패 코드.
인증(Authenticate)은 클라이언트 자신이 주장하는 사용자와 클라이언트가 실제 같은 사용자인지 검증하는 로그인 같은 과정을 의미한다. 반면, 인가(Authorized)는 인증이 된 이후 클라이언트가 해당 요청에 대한 권한이 있는지 검사하는 것을 의미한다.
5XX - 서버 에러
클라이언트의 요청은 유효하지만, 그 작업을 수행하는데 있어 서버에서 오류가 발생했을 경우 반환하기 적합한 코드이다. 정말 예상치 못한 경우를 제외하고는 클라이언트에게 5XX 에러와 그 내용을 보여줘서는 안된다.
etc. 좋은 URI 설계를 위한 여러가지 규칙
- URI의 맨 뒤에는 / 가 붙지 않는다.
- 즉, /posts 와 /posts/ 는 동일한 리소스를 가리킨다.
- 계층적 관계를 나타낼 때 / 를 사용한다.
- /posts/1/comments 는 포스팅 컬렉션, 개별 포스팅 개체, 개별 포스팅의 코멘트 컬렉션을 계층적으로 나타낸다.
- 밑줄(_)을 사용하지 않는다. 대신, 가독성을 위해 하이픈(-) 을 사용한다.
- /best_posts 대신 /best-posts 로 표현하자.
- 대소문자를 섞어 쓰지 않고, 소문자만을 사용한다.
- URI에 파일 확장자를 포함하지 않는다.
- 행위는 URI에 표기하지 않는다. URI는 동사가 아니라 명사를 기반으로 디자인 해야한다. 즉, 리소스에 대한 작업이 아니라 대상 리소스를 중심으로 디자인한다.
-
https://some-blog-service.com/posts // 좋음 https://some-blog-service.com/create-post // 좋지 않음
'(펌)개념 정리' 카테고리의 다른 글
이벤트 버블링과 이벤트 캡처링 (0) | 2022.11.12 |
---|---|
var, let, const의 차이점 (0) | 2022.11.12 |
API란 무엇인가 (0) | 2022.11.10 |
HTTP와 HTTPS의 차이점 (1) | 2022.11.10 |
Http 메서드 중, Get과 Post의 차이점 (0) | 2022.11.10 |