지난 포스팅 에서는 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개로 구성되어 있습니다. rel
과 href
는 현재의 리소스와 연결되는 관계를 나타내며, 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 |