하는 일은 크게 Create, Read, Update, Delete 네 가지임
도서관으로 예시를 들어서 생각해보자
Create : 정보를 생성해서 넣음
- 새로운 책의 정보를 입력하는 것
Read : 정보를 조회
- 책들의 목록 또는 특정 책의 정보를 받아와 읽는 것
Update : 정보를 변경
- 현존하는 특정 책의 정보를 변경하는 것
Delete : 정보를 삭제
- 어느 책의 정보를 삭제하는 것
우리가 사용하는 대부분의 서비스들이 API를 통해 하는 일들이 4가지로 구성되어있음
POST https://api.happybeenbooks.com/v1/books
-> 새 책의 정보 받아오기
GET https://api.happybeenbooks.com/v1/books
-> 책들의 목록 받아오기
GET https://api.happybeenbooks.com/v1/books/1
-> 색인정보가 1인 책의 정보 조회하기
PUT https://api.happybeenbooks.com/v1/books/20
-> 색인번호가 20인 책의 정보 수정
PATCH https://api.happybeenbooks.com/v1/books/7
-> 색인번호가 7인 책의 대여 상태 변경
DELETE https://api.happybeenbooks.com/v1/books/123
-> 색인번호가 123인 책을 삭제하는 요청



GET https://api.happybeenbooks.com/v1/books
GET https://api.happybeenbooks.com/v1/books/status=available
특정 조건으로 필터링하려면 query parameter를 사용하면 됨
status가 avaiable인 대여가 가능한 상태의 책들만 가져옴
GET https://api.happybeenbooks.com/v1/books/page=1&size=10
GET https://api.happybeenbooks.com/v1/books/1
[
{
"id": 1,
"title" : "Good code",
"author" : "hyebeen"
}
]
RESTful API에서 권장되는 또 다른 원칙
Hypermedia
As
The
Engine
Of
Application State
각 요청의 응답에, 가용한 다른 요청들의 정보를 포함시키는 것
'이 리소스에 관해 이런 기능들도 이와 같이 요청할 수 있다'고 첨부하는 것임
[
{
"id": 1,
"title" : "Good code",
"author" : "hyebeen",
"links": [
{"rel": "self", "href": "https://api.happybeen.com/v1/books/1"},
{"rel": "update", "href": "https://api.happybeen.com/v1/books/1"},
{"rel": "delete", "href": "https://api.happybeen.com/v1/books/1"}
]
}
]
위 코드에서 links부분에 해당됨
식당에서 메인 메뉴 주문했을 때 디저트 메뉴판도 같이 주는 것과 같음
위 링크 정보들을 통해서, 개발자들은 API 문서들을 보지 않아도 다음에 어떤 요청을 보낼 수 있는지 살펴볼 수 있음
또한, 이 부분의 API의 세부사항이 변경되더라도 클라이언트에서 이 정보를 참조하게 만들면 클라이언트의 코드를 수정할 필요도 없어짐
각 리소스는 그것의 상위 또는 하위 리소스를 가질 수 있음
책의 경우, 각각에 대한 리뷰들이 달릴 수 있으니 리뷰를 하위 리소스로 갖는다고 할 수 있음
그래서 색인번호가 1인 책에 해당하는 리뷰들ㅇ르 조회하려면 이와 같이 URI를 작성하면 됨
이를 통해 각 요청이 응답으로 받고자 하는 정보들 뿐만 아니라, 리소스들이 서로 어떤 관계를 갖는지 URI를 통해 쉽게 파악할 수 있음
{
"title": "Hello JS",
"autor": "been",
"published_date": "2024-08-10",
"isbn": "1234567890"
}
{
"id": 4,
"title": "Hello JS",
"autor": "been",
"published_date": "2024-08-10",
"isbn": "1234567890",
"status": "available"
}
PUT과 PATCH의 차이는 전체를 수정하는지, 부분적으로 수정하는지 여부임
특정 항목의 정보를 전체적으로 대체 -> PUT 요청
특정 항목의 정보를 부분적으로 대체 -> PATCH 요청
소포상자의 크기는 같지만, 색으로 용도가 다르게 표시된 것임
수정은 특정 항목에 관한 것이기 때문에 어떤 책인지 명시하는 식별자를 붙여줌
PUT 요청
PUT https://api.happybeenbooks.com/v1/books/1
{
"title": "Hello JS",
"autor": "been",
"published_date": "2024-08-10",
"isbn": "1234567890",
"status": "available"
}
{
"message": "Book update successfully"
}
{
"id": 1,
"title": "Hello JS",
"autor": "been",
"published_date": "2024-08-10",
"isbn": "1234567890",
"status": "available"
}
PATCH 요청
{
"status": "rented"
}
{
"id": 1,
"title": "Hello JS",
"autor": "been",
"published_date": "2024-08-10",
"isbn": "1234567890",
"status": "rented"
}
{
"status": "rented"
}
DELETE https://api.happybeenbooks.com/v1/books/1
{
"message": "Book deleted successfuly"
}
우편물에 도장이 찍히거나 스티커가 붙어 오는 것처럼, 서버의 응답에는 요청을 처리한 결과를 알려주는 상태 코드가 담겨옴
성공적인 요청(Success) : 2XX
200번대 상태코드
클라이언트 요청의 문제(Client Error): 4XX
400번대 상태코드
URI가 잘못되었거나, 권한 외의 요청을 하는 경우
서버측의 오류(Server Error): 5XX
500번대 상태코드
이와 같은 상태 코드들로 각 요청이 어떻게 처리되었는지를 명확하게 나타내주어야 함
클라이언트의 상태 정보가 서버에 저장되지 않아야 한다는 것
즉, 서버는 클라이언트에 대해 아무것도 기억하지 않아야 한다는 것임
때문에 클라이언트의 요청이 몇 번째 반복되어도 필요한 모든 내용을 포함하고 있어야 함
Idempotent(멱등성)과도 연결됨
클라이언트가 같은 요청을 몇 번을 보내도 언제나 같은 답이 돌아와야 함(실제 데이터가 바뀐 경우 제외)
클라이언트와 서버는 서로에 대해서는 기억하지 않아야 하지만 자신이 어떤 응답을 보냈는지, 자신이 어떤 응답을 받았는지는 기억해 두는게 좋음
이처럼 한 번 얻어낸 데이터를 또 쓸 수 있도록 저장해 두는 것을 Casheability(캐싱)이라고 함
클라이언트에서 어떤 요청에 대한 응답을 캐싱해두면 같은 데이터가 필요할 때마다 요청을 보내지 않아도 되고,
서버도 특정 요청에 대해 응답한 바를 기억해 두면
다른 클라이언트가 같은 요청을 보냈을 때
또 데이터 베이스에서 정보를 캐낼 필요 없이
가지고 있는 것을 바로 보내면 됨
RESTful API에서는 각 요청이 나타내는 바가 뚜렷하니까 그것마다 캐싱을 해두기가 수월함