TIL 22

모모·2021년 12월 25일
0

TIL

목록 보기
22/28

REST API

REST API란?

  • 웹 앱에서는 HTTP 메소드를 이용해 서버와 통신하며, 클라이언트-서버간 적절한 데이터와 리소스를 요청/응답하기 위한 메뉴판으로서 API를 사용

  • 알아보기 쉽고 잘 작성되었음을 판단하는 지표를 REST API라고 하며, 이 REST 방법론을 실용적으로 적용하기 위한 REST 성숙도 모델(RMM)이 존재함

  • REST 성숙도 모델은 총 4단계로 나누어짐

    • 0 단계: 단순히 HTTP 프로토콜을 사용하는 단계

    • 1 단계: 개별 리소스와의 통신을 준수하는 단계. 즉, 모든 자원은 개별 리소스에 맞는 엔드포인트를 사용해야 하며, 받은 리소스에 대한 정보를 응답으로 전달해야 함
      • 엔드포인트 작성 시 동사, HTTP 메소드, 어떤 행위에 대한 단어 사용이 아닌, 리소스에 집중한 명사 단어를 사용하는 것이 바람직함
      • 요청에 따른 응답으로 리소스를 전달할 때에도 사용한 리소스에 대한 정보와 함께 리소스 사용에 대한 성공/실패 여부를 반환해야 함

    • 2 단계: CRUD에 맞는 적절한 HTTP 메소드를 사용하는 단계
      • GET: 특정 리소스의 표시를 요청. 서버의 데이터를 변화시키지 않음
      • POST: 요청마다 새로운 리소스를 생성
      • PUT: 리소스를 요청 payload로 교체. 요청마다 같은 리소스를 반환(멱등성)
      • PATCH: 리소스의 부분을 수정하는데 사용

    • 3 단계: 하이퍼 미디어 컨트롤(HATEOAS: Hypertext As The Engine Of Application State)을 적용하는 단계. 요청은 2단계와 동일하지만 응답에는 리소스의 URI를 포함한 링크 요소를 삽입하여 작성하는 점이 다름. 이때 응답의 링크 요소는 응답을 받은 다음 할 수 있는 다양한 액션을 위해 많은 하이퍼미디어 컨트롤을 포함함

REST API 적용 예제

Q1. 앱에 국제화에 대한 요구사항이 추가되어 다음과 같이 요청에 따라 국제화가 적용된 응답이 API 서버로부터 제공되어야 합니다. 응답을 받기 위해 어떤 방법으로 요청을 보내도록 개선하는 것이 좋을까요?

// 한국어
{ "category": ["한식", "이탈리안", "일식", "중식"] } 

// 영어
{ "category": ["Korean", "Italian", "Japanese", "Chinese"] }

A1. Accept-Language 헤더에 따라 다른 응답을 제공한다.

  • 언어별로 별도의 엔드포인트를 작성할 수도 있지만, 기존 엔드포인트를 대신하는 것은 하위 호환성을 고려하지 않은 방식
  • 그보다 더 좋은 예는 Accept-Language 헤더를 요청에 함께 제공하는 것
  • 이는 기존 엔드포인트를 그대로 활용할 수도 있다는 장점이 있으며, Accept-Language 헤더의 목적이 애초에 클라이언트가 이해할 수 있는 언어 설정이 무엇인지 알려주는 것이므로 해당 상황에 적합함

Q2. 도서 검색 사이트에서 도서 제목을 바탕으로 검색 기능을 구현하려고 합니다. 요청이 REST 원칙에 적합하도록 하려면 어떻게 해야 할까요?

요청
GET /books
[헤더 생략]

{ "query": { "title": "code" } }


정상 응답
HTTP/1.1 200 OK
[헤더 생략]
{
	"books": [
      	 {
          "isbn": "9780132350884", 
          "title": "Clean Code",
          "author": "Robert C.Martin",
          "price": "$42.47" 
         },
         { 
          "isbn": "0735619670", 
          "title": "Code Complete", 
          "author": "Steve McConnell", 
          "price": "$24.17" 
         }
     ]
}

A2. GET 요청에는 Query Parameter를 사용해야 한다.

  • 도서 제목을 바탕으로 검색하는 기능을 구현한다는 것은 GET 요청을 사용하여 데이터를 조회하는 것을 의미
  • 그러나 GET 요청의 경우 body가 존재하지 않기 때문에 이를 Query Parameter를 이용하여 구현해야 함

Q3. 게시판에서 10번 게시물을 삭제하는 엔드포인트를 작성하려고 합니다. 가장 적절한 방법은 무엇인가요?

A3. DELETE /articles/10

  • DELETE /articles body: { "id": "10" }와 동일한 리소스에 대한 요청이지만, 아래의 경우와 같이 본문(body)을 통해 전달하는 것보다는 엔드포인트에 리소스를 명시하는 편이 낫다
  • DELETE에 본문(body)을 실을 수 없는 것은 아니나, HTTP 스펙에 근거하여, 많은 백엔드 구현에서 본문을 같이 전달할 경우 DELETE 요청 자체를 거절하는 경우를 종종 발견할 수 있다
  • 따라서, 애초에 엔드포인트에서 어떤 리소스를 삭제하는지 명시하는 편이 더 낫다

0개의 댓글