REST(Representational State Transfer)란 웹에 존재하는 모든 자원(이미지, 동영상, 텍스트 등의 데이터)에 고유한 URI를 부여하여 해당 자원에 대한 주소를 지정하는 방법론이다. 현재 가장 널리 사용되는 방식이며 RESTful API는 이러한 REST의 특징을 지키면서 API의 엔드포인트 구조를 구현하는 방식이다.
각 엔드포인트는 리소스를 표현하는 고유의 URI 주소를 가지고 있어 해당 리소스에 행할 수 있는 행위를 HTTP 메소드 표현을 처리할 수 있게 된다.
URI의 개념은 URL의 superset으로 URI가 URL을 포함하고 있는 상위 set이다. URI는 Uniform Resource Identifier, URL은 Uniform Resource Locator이다. 마지막 뒷 단어가 다르다는 점을 주목하자. URL은 요청하는 주소가 실제 파일의 위치에 대한 정보(locator), URI는 의미 있는 식별자(identifier)를 뜻한다. 예를 들어 어떤 pdf파일 하나를 담고 있는 주소(브라우저에 보여지는 주소)를 보면 마지막에
경로.pdf
로 끝나는 경우가 있다. 이는 URL이라고 볼 수 있으며, URI는 URL처럼 특정한 파일을 가르키지는 않는다.
RESTful API 통신의 간단한 예시를 살펴보자.
클라이언트 Request
서버 Response
200 OK
{
"id": 1,
"name": "동물복지 계란"
"price": 5000
}
RESTful API라는 것은 URI 주소가 어떻게 생겼는지 살펴 보면 알 수 있다. REST한 API는 상황에 따라 path parameter와 query parameter를 사용하여 통신을 할 수도 있다. 이 두 가지에 대해 알아보자.
크롬 브라우저를 사용하여 json 파일을 확인할 경우, json 파일을 사람이 보기 좋게 정렬하고 꾸며주는 크롬 extension들이 있다. 구글에 chrome json extesion과 같은 검색어로 검색 후 설치해서 사용해보자.
다른 API 구현 방식으로는 GraphQL이라는 방식도 있다. 여기서 다룰 주제는 아니지만, RESTful과의 차이점을 간단하게 정리하자면 프론트엔드 쪽에서 서버의 데이터 전체에 접근해서 필요한 정보를 직접 쿼리해야 하는 방식이다.
path parameter가 무엇인지 예시 API URI로부터 알아보자.
지금부터 이 글에서 사용할 API 주소는 https://jsonplaceholder.typicode.com/ 라는 무료로 제공되는 테스트 REST API 주소로, 실제로 클릭해서 데이터를 살펴볼 수 있다.
GET https://jsonplaceholder.typicode.com/posts
위 API에서 posts의 모든 데이터를 GET method로 가져올 수 있다.
GET https://jsonplaceholder.typicode.com/posts/1
posts 중 id가 1인 post의 데이터를 얻을 수 있다.
GET https://jsonplaceholder.typicode.com/posts/1/comments
post 중 id가 1인 post에 있는 comments의 데이터를 얻을 수 있다.
위와 같이 'path/path/path' 와 같은 형태의 API URI로 통신을 하게 된다. 이것이 path parameter를 사용하여 통신을 하는 것이다. GET의 예시만 들었는데, 물론 POST, PATCH, DELETE 와 같은 method로 해당 API URI에서 통신을 할 수도 있다. URI는 같을 수 있으며, 주고받는 데이터 request body, response body가 method별로 다를 것이다.
클라이언트 입장에서는 API 명세서에 맞게 적절한 request body를 보내고 response body를 받으면 된다. 서버 입장에서는 받은 request에 알맞게 response를 보내면 되는 것이다.
마찬가지로 예시 API URI로부터 API가 무엇인지 알아보자.
GET https://jsonplaceholder.typicode.com/comments?postId=1
형태를 살펴보면 ?postId=1
이라는 쿼리문처럼 생긴 부분이 있다. 본능적으로 느껴지는 그것! postId가 1인 comments를 가져오는 건가? 하면 그것이 맞다. 그리고 위 path parameter에서
GET https://jsonplaceholder.typicode.com/posts/1/comments
이런 주소를 예시로 들었는데, 이것과 동일한 데이터를 가져오게 되는 것이다. Query string 방법의 경우, 쿼리문 형태이기 때문에 아래와 같이 더 복잡한 조건을 줄수도 있을 것이다.
GET https://jsonplaceholder.typicode.com/comments?postId=1&id=5
위 무료 API에서 제공하는 기능은 아니지만, query string을 이용하면 여러 방법으로 받아올 수 있다. id의 역순으로 데이터를 받아오는 것이 구현되어 있다면, 그러한 방식으로 query string을 주소에 작성하여 데이터를 받아 올 수 있다는 것이다. 받아오는 데이터의 갯수를 제한해서 가져오는 것 또한 query string으로 구현할 수도 있다. 검색 기능이 있는 곳에서 검색어에 따른 결과 데이터를 받아올 때도 사용할 수 있을 것이다.
위에서 언급했던 것 처럼
위 주소는 똑같이 postId가 1인 comments 데이터를 가져오는, 같은 결과를 만들어낸다.
그렇다면, 언제 어떤 방법을 사용해야 할까?
Query parameter는 Filtering, Sorting, Searching일 경우에 사용한다. 따라서 Path parameter는 따로 정제되지 않은 데이터를 가져올 때 사용하면 된다.
RESTful 한 API를 이해하기 위해 RESTful하지 않은 API URI과 RESTful하게 바꾼 예시이다.
나쁜 예시 => 좋은 예시
위 변화의 핵심은 페이지(view)가 중심이 되어 받는 것이 아니라 자원(데이터)가 중심이되어 API를 만들어야 한다는 것이다.
현재 진행중인 마켓컬리 사이트 클론에서 백엔드와 프론트엔드 통신에 사용한 테스트 코드이다. 아직 완성 단계가 아니라 간단한 코드이다. 아래 코드는 리엑트에서 장바구니에서 하나의 제품에 대해 수량을 추가하는 코드이다.
addItem = e => {
fetch("http://10.168.1.160:8000/order/cart", {
method: "PATCH",
body: JSON.stringify({
cart_item_id: e.target.id,
delta: "plus",
}),
})
.then(res => res.json())
.then(result => {
result.MESSAGE === "SUCCESS" ? this.getData() : console.log("실패!");
});
};
{/*이외에도 수량 감소, 삭제(DELETE) 등에 대한 함수가 있다.*/}
getData = async () => {
const response = await fetch("http://10.168.1.160:8000/order/cart");
const data = await response.json();
this.setState({ cartData: data.items_in_cart });
};
우리가 주목해야할 것은 RESTful API 관점에서 주소 이름이다.
장바구니에서 수량 삭제와 추가(PATCH), 아이템 삭제(DELETE), 장바구니 데이터 받아오기(GET) 모두 같은 API URI에서 이루어진다는 점이다. 즉, 장바구니 데이터가 중심이 되어 order/cart
라는 URI에 method에 따라 행할 수 있는 행위를 정하는 것이다. /order/cart/add
라는 곳에서 수량 조절을 것이 아니라는 점에서 RESTful API라고 할 수 있다.
"/order/cart/add 라는 곳에서 수량 조절을 것이 아니라는 점에서 RESTful API라고 할 수 있다." 이 부분에서 감동 먹고 갑니다 ㅠㅠ by API 개발자