본문 바로가기
개발 관련/http

REST (2)

by lazysnack 2022. 7. 14.

지난 포스팅 에서는 REST 의 개요와 로이 필딩이 말하는 6가지 제약사항 그리고, 리처드슨 성숙도라는 것에 대해서 알아봤습니다.

개념 위주로 알아갔는데요. 이번에는 약간(?) 실전 위주로 어떤 것들이 있는지 알아보려고 합니다.

1. REST 형 API 디자인

1. 리소스 명명

  • REST형 API는 사용하는 클라이언트 입장에서 봤을 때 의미가 분명해야 합니다.
  • 리소스를 어떤 명사로 할 때엔 데이터 구조가 어떻게 생겼는지, 클라이언트가 어떤 식으로 사용할 가능성이 클지 미리 파악을 해야 합니다. (설계를 잘 해야겠죠..?)

2. 동사가 아닌 명사로

  • 리소스명은 동사가 아니라 명사로 시작하며, 리소스는 리소스를 해야할 일은 HTTP 메소드를 통해 표현합니다.
  • ex) 전체 사용자를 의미하는 명사 users 와 사용자 식별 ID 를 합쳐 /users/1234 와 같이 표현
  • 리소스를 정한 다음엔 HTTP 메소드로 하고싶은 걸 정하면 됩니다. (ex. 조회라면 GET, 생성은 POST)

3. 자기 서술형으로

  • 리소스는 자신을 가장 잘 나타내는 명사로 명명
  • URI나 HTTP메소드를 처음 봤을 때 어느 리소스를 어떻게 하겠다는 것인지 바로 눈에 들어오지 않으면 REST 형 URI 라고 할 수 없습니다.

4. 단수 아닌 복수형으로

  • 리소스명은 데이터 집합을 나타내기 때문에 복수형으로 표기해야 합니다. (ex. 유저들 = users)
  • 복수형 명사는 서비스의 여러 데이터를 나타내고 ID는 그런 데이터 중에 한 인스턴스를 가리킴 (ex. users/1234)

5. HTTP 메소드

  • HTTP1.1 명세에는 8개의 HTTP 메소드가 존재하지만, 자주 쓰이는 것은 GET, POST, PUT, DELETE

5-1. GET

  • 조회하는 메소드로 멱등성을 보장합니다. (100번을 호출해도 100번 같은 결과)
  • 요청 성공 시 200 (OK) 응답 코드를 보내며, 없으면 404 (not found), 형식이 잘못되면 400 (bad request) 입니다.
  • GET users/1234/posts 의 URI 는 1234 사용자의 모든 포스트를 조회하는 URI 입니다.

5-2. POST

  • 주어진 컨텍스트에서 리소스를 새로 만드는 메소드입니다.
  • 새 리소스를 생성한 뒤 컨텍스트에 묶고 ID 를 할당합니다.
  • 새로 추가할 정보를 본문에 넣고 요청을 하면 됩니다. (ex. POST users/1234/posts)

5-3. PUT

  • 알려진 리소스를 수정할 때 사용합니다.
  • 요청 본문에 리소스의 수정 후 버전이 있고, HTTP 응답코드 200 을 반환합니다.(ex. PUT users/1234)
  • 수정할 내용만 보내는 것이 아니라 수정할 내용을 포함한 리소스 표현형을 통째로 보냅니다.

5-4. DELETE

  • 리소스를 삭제할 때 사용합니다. (ex. DELETE /users/1234)
  • 삭제가 성공하면 200 을 삭제할 리소스가 존재하지 않으면 400을 반환합니다.

2. REST 예시

사용자(users) 리소스와 팔로워(follows) 대해서 REST 의 표현 방법을 보겠습니다.

  • 사용자를 새로 등록
    POST  /users
  • 사용자 조회
    GET  /users/1234
    GET  /users (모든 사용자 조회)
  • 사용자 정보 수정
    PUT  /users/1234
  • 사용자 삭제
    DELETE  /users/1234
    DELETE  /users (모든 사용자 삭제)
  • 1234 사용자의 전체 팔로워 조회
    GET  /users/1234/followers
  • 1234 사용자의 팔로워로 등록
    POST  /users/1234/followers
  • 1234 사용자를 팔로워한 4567 의 정보
    GET  /users/1234/followers/4567
    혹은
    GET  /users/4567
  • 4567이 1234의 팔로워 해제
    DELETE  /users/1234/followers/4566

    3. HATEOAS

HATEOAS 는 리처드슨 성숙도 모델 중 가장 높은 단계의 REST 구현체입니다.

예시로 GET /posts 라는 URI 를 통해 자신이 볼 수 있는 게시물에 대한 리소스를 요청한다라고 해보겠습니다.

{
  "posts" : [
    {
      "id" : 123,
      "title" : "기생충",
      "content" "이러저러한 내용입니다."
      "links" : [
          {
              "rel" : "self",
          "href" : "/posts/123"
          "method" : "GET"
        },
        {
          "rel" : "replies",
          "href" : "/posts/123/replies"
          "method" : "GET"
        },
            {
          "rel" : "recommends",
          "href" : "/rest/posts/123/recommends"
          "method" : "GET"
        },
            {
          "rel" : "owner",
          "href" : "/rest/posts/123/users"
          "method" : "GET"
        }
      ]
    }
  ]
}

이런 형태가 나옵니다.


각각 설명을 해보면, 게시물은 1개를 볼 수 있으며, 아이디, 타이틀, 내용이 있습니다.


여기까지만 보면 일반 응답과 크게 다르지 않은데요. 여기서 links 가 주목할 만한 요소라고 할 수 있습니다.


links 를 보면 3개로 구성되어 있습니다. relhref는 현재의 리소스와 연결되는 관계를 나타내며, method는 해당 리소스를 얻으려고할 때 사용할 HTTP 메소드 입니다.


위에서는 self 는 본인, replies 는 해당 글의 댓글들, recommends 는 추천한 사람들, owner 는 작성자 라고 할 수 있습니다. rel 에 대해서는 특별히 정해진 규약은 없어서, 명확히 알아볼 수만 있으면 됩니다.


이런 식으로 클라이언트가 다른 리소스도 볼 수 있도록 관련 링크 정보를 함께 주면 힘들이지 않고 API 를 확장할 수 있는 장점이 있습니다.


다른 곳도 있겠지만, 제가 찾은 곳에서는 PayPal 에서 HATEOAS 를 사용하여 구축을 했고, 링크를 보면 쉽게 이해할 수 있습니다.

4. 정리

이번에는 직접 설계를 할 떄를 중점으로 예시를 들어봤는데, 적당히 지키면서도 안 지키는 듯한? 그런 느낌을 받는 요즘입니다.


좀 더 좋은? 명쾌한? 리소스 명을 찾아가면서 만들어야 겠습니다.


HATEOAS 의 경우에는 들어본 적은 있지만, 실제로 본 적은 없네요. 클라이언트 입장에서는 편할 것 같아 보이지만, 서버 입장에서는 굉장히 귀찮을 것 같고, 어차피 API 문서는 서로 공유 해야 할 텐데...? 라는 생각이 듭니다만 익숙해지면 유추하기 편할 것 같다는 생각은 드네요.


Reference

'개발 관련 > http' 카테고리의 다른 글

HTTP 메시지  (0) 2022.07.14
1. HTTP 개관  (0) 2022.07.14
REST (1)  (0) 2022.07.14