공부하며 정리해보기 - 1. REST API
1. REST의 구성
1) 자원(RESOURCE) - URI (Uniform Resource Identifier)
- 자원은 REST에서 관리하는 모든 데이터를 의미합니다. 에를 들어, 사용자 정보, 게시글, 상품 등… 다양한 내용이 자원이 될 수 있습니다. 자원은 특정 위치를 URI로 표현합니다.
- URI란? : 인터넷 상에서 자원을 식별하는 고유한 주소입니다. 웹 브라우저에서는 URL 등으로도 많이 알려져 있습니다.
URI를 통해 클라이언트는 서버의 자원에 접근할 수 있습니다.
예시 : /users/j-plum - ID가 j-plum이라는 사용자에 대한 자원
/products/12345678 - ID가 상품번호가 12345678인 상품에 대한 자원.
(예시의 users와 products가 자원이되고 , 각각의 ID는 특정 자원을 식별하는 데 사용합니다.)
2) 행위(Verb) - HTTP Method
- 행위는 자원에 대해 수행할 동작을 정의합니다. REST 에서는 이 동작을 HTTP 메서드로 표현합니다.
HTTP 메서드는 클라이언트가 서버에 요청을 보낼 때 사용하는 규칙입니다.
- HTTP Method란? : HTTP Method는 클라이언트 서버 간의 상호작용을 정의하는 표준 방법입니다.
- GET : 자원을 조회할 때 사용합니다. (서버의 데이터를 가져올 목적)
- 예시 : GET /users/j-plum - ID가 j-plum인 사용자의 정보를 가져옵니다.
- POST : 새로운 자원을 생성할 때 사용합니다.
- 예시 : POST /users - 새로운 사용자를 생성합니다.
- PUT : 자원을 업데이트(수정)할 때 사용합니다.
- 예시 : PUT /users/j-plum - ID가 j-plum인 사용자의 정보를 수정합니다.
같은 URI라도 HTTP 메서드(GET, POST, PUT, DELETE)에 따라 서버가 수행하는 작업은 다릅니다
- 예시 : PUT /users/j-plum - ID가 j-plum인 사용자의 정보를 수정합니다.
- DELETE : 자원을 삭제할 때 사용합니다.
- 예시 : DELETE /users/j-plum - ID가 j-plum인 사용자를 삭제합니다.
추가 내용
- 동일한 URI를 사용하더라도 HTTP 메서드에 따라 서버가 수행하는 작업은 다릅니다
( 위의 예시는 /users/j-plum 라는 URI를 반복해서 사용하고 있습니다. )
동일한 URI를 사용하는 장점
장점
- 간결함 : 동일한 URI를 반복적으로 사용하면서, URI를 간소화하고 가독성을 높일 수 있습니다. 이로 인해 URI의 구조가 복잡해지지 않으며, 이해하기 쉬운 API를 설계할 수 있습니다.
- 의미 전달 : URI와 HTTP 메서드를 조합함으로써, 자원에 대한 조작 의도를 명확하게 전달합니다. 예를 들어, /users/j-plum URI는 특정 사용자를 나타내며, GET, PUT, DELETE 메서드를 통해 조회, 수정, 삭제와 같은 다양한 작업을 수행할 수 있음을 직관적으로 알 수 있습니다.
- GET /users/j-plum: j-plum이라는 사용자의 정보를 조회합니다.
- PUT /users/j-plum: j-plum이라는 사용자의 정보를 수정합니다.
- DELETE /users/j-plum: j-plum이라는 사용자를 삭제합니다.
3) 표현(Representation)
- 표현은 자원의 상태나 데이터를 전달하는 방식을 의미합니다. 서버는 클라이언트의 요청에 따라 자원의 상태를 다양한 형식으로 반환할 수 있습니다. 주로 JSON이나 XML형식으로 표현됩니다.
- 표현이란? : 표현은 자원의 실제 데이터를 포험하며, 이를 통해 클라이언트는 서버로부터 자원의 상태를 확인하거나 필요한 데이터를 받을 수 있습니다. 표현은 자원의 구조와 내용을 설명합니다.
예시 : 만약 사용자가 /users/j-plum URI에 GET 요청을 보내면, 서버는 ID가 123인 사용자의 정보를 반환합니다.
{
"id": j-plum,
"name": "JJ",
"email": "j.plum@gmail.com"
}
2. REST의 특징
1) Uniform Interface (유니폼 인터페이스)
- Uniform Interface는 클라이언트가 서버 리소스와 상호작용하는 방식을 일관성 있게 정의합니다. 이로 인해 클라이언트는 URI로 지정된 리소스에 대한 작업을 통일되고 제한적인 인터페이스를 통해 수행할 수 있습니다.
예시 : 만약 사용자가 /users/ j-plum URI에 GET 요청을 보내면, 서버는 ID가 j-plum인 사용자의 정보를 반환합니다. 이때 모든 리소스에 대해 GET, POST, PUT, DELETE와 같은 HTTP 메서드가 일관되게 사용됩니다.
2) Stateless (무상태성)
- REST는 무상태성을 지니고 있어 서버는 클라이언트의 이전 요청에 대한 정보를 저장하지 않습니다. 즉, 각 요청은 독립적으로 처리되며, 서버는 요청을 받을 때 필요한 모든 정보를 요청 본문이나 URL에서 받아야 합니다.
만약 사용자가 POST /login 요청을 통해 로그인했다면, 서버는 이후 요청에서 이 사용자의 로그인 상태를 기억하지 않습니다. 클라이언트는 이후의 요청에서 인증 토큰 등을 헤더에 포함시켜야 합니다.
조금 더 자세하게 정리해 보겠습니다.
REST의 무상태성 원칙은, 서버가 클라이언트의 상태를 저장하지 않는다는 것을 의미합니다.
이 원칙에 따라, 각 요청은 독립적이며 자급자족적인 정보를 포함해야 합니다. 서버는 이전 요청의 상태나 세션정보를 기억하지 않으며, 클라이언트로부터 받은 각 요청을 그 자체로 완전한 정보로써 처리합니다.
1. 독립적 : 독립적이라는 것은 각 요청이 다른 요청과 연관되지 않는다는 것을 의미합니다. 하나의 요청이 다른 요청의 상태나 결과에 의존하지 않는다는 뜻 입니다.
2. 자급자족적 : 각 요청이 서버가 요청을 처리하는 데 필요한모든 정보를 포함하고 있어야 한다는 것을 의미합니다.
서버는 그 요청만으로 작업을 수행할 수 있어야 하며, 추가적인 상태 정보를 기억할 필요가 없습니다.
여기서 의문점이 생겼습니다
어... GET /users/j-plum 를 통해 j-plum 의 정보를 가져와사 그 정보를 이용해서 다른 API를 이용한다면
독립적인게 아니지않나..? 서로 의존하는 것 같은데.??
이는 클라이언트의 관점에서 입니다.
REST 의 무상태성(Statless)의 원칙과 독립성은 서버 관점에 바라봐야 합니다.
클라이언트 입장에서는 첫 번째 호출에서 얻은 데이터를 통해 두 번째 API를 호출하기 떄문에, 두 요청이 서로 의존하는 것 처럼 보일 수 있습니다.
서버 입장에서는, 각각의 요청이 독립적이고 자급자족적입니다.
서버는 첫번째 요청과 두번째 요청이 서로 관련이 있는지 알 필요가 없고, 기억하지 않습니다.
서버는 필요한 정보를 해당 요청에서 직접 받아 처리합니다.
3) Cacheable (캐시 가능)
- RESTful 서비스는 HTTP 프로토콜을 기반으로 작동합니다. HTTP는 웹 브라우저와 서버가 데이터를 주고 받는 방식에 대한 규칙입니다. 그 중 하나가 캐시(cache) 기능입니다.
캐시란?
- 캐시는 자주 사용하는 데이터를 임시로 저장해 두었다가, 다시 필요할 때 빠르게 꺼내 쓰는 메커니즘입니다.
예를들어, 웹 사이트에 접속할 때 이미 한 번 본 이미지를 매번 서버에서 다시 받아오지 않고, 브라우저가 임시로 저장해 둔 이미지를 재사용 하는것이 캐시 입니다.
그렇다면 RESTful 서비스에서의 캐시는?
- RESTful API는 이런 캐시 기능을 활용할 수 있습니다. 서버는 리소스가 캐시될 수 있는지를 브라우저에게 알려줍니다.
이때 사용되는 것이 HTTP 헤더입니다
HTTP 헤더란?
- HTTP 헤더는 클라이언트(브라우저)와 서버간의 통신에서 추가적인 정보를 담은 메세지 입니다.
요청이나 응답과 함께 전달됩니다.
캐시 관련 HTTP 헤더 예시
- Chahe-control : 서버가 브라우저에게 리소스를 캐시할 수 있는지, 캣할 수 있다면 얼마나 오래 저장할 수 있는지를 알려줍니다.
- 예시) Cache-Control : max-age=3600 => 이 리소스를 1시간동안 캐시할 수있다는 의미입니다.
- Expires : 캐시된 리소스가 언제 만료되는지를 나타냅니다.
- 예시) Expires : wed, 21 Oct 2024 01:01:00 GMT => 이 시간 이후로는 캐시를 사용하지 않고, 서버에서 다시 받아야 한다는 의미입니다.
상황 예시
상황 1 : 자원 요청하기
- 사용자가 웹사이트에서 제품 목록을 보려고 합니다.
- GET /products 를 서버에 요청
- 서버는 제품 목록을 응답하며, Cache-Control : max-age=600 이라는 HTTP 헤더도 같이 보냅니다.(10분간 캐시가능)
- 브라우저는 10분 동안 이 데이터를 저장해두고, 그 시간 내에 다시 요청이 오면 서버에 가지 않고 저장된 데이터를 바로 보여줍니다.
캐시된 데이터를 사용하는 과정
- 사용자가 10분 이내에 다시 동일한 GET /products 요청을 보낸다면, 브라우저는 먼저 캐시를 확인합니다.
- 캐시에서 GET /products 라는 키를 찾습니다. 이 키가 존재하고, 캐시된 데이터가 여전히 유효하면, 브라우저는 서버에 요청을 보내지 않고 바로 캐시된 데이터를 사용자에게 보여줍니다.
- 이로 인해 페이지 로딩 속도가 빨라지고, 서버의 부하도 줄어드는 장점이 있습니다.
캐시 만료 후
- 설정된 유효 시간이 만료되면 더 이상 유효하지 않으므로, 브라우저는 다시 서버에 GET /products 요청을 보내고,
최신 데이터를 받아옵니다. - HTTP 헤더의 내용에 따라 다시 캐
3줄요약
- 브라우저는 GET /products 라는 요청을 키로, 응답 데이터를 값으로 캐시에 저장힙니다.
- 동일한 요청이 시잔 내에 발생하면, 브라우저는 캐시에 저장된 데이터를 서버에 다시 요청하지 않고 바로 사용자에게 제공합니다.
- 이는 서버와 브라우저가 캐시 관련 정보를 HTTP 헤더를 통해 주고받으면서 이루어지는 내용입니다.
4) Self-descriptiveness (자체 표현 구조)
- REST API 메시지는 자체 설명 구조를 가지고 있어, 클라이언트가 별도의 문서 없이도 API의 요청 및 응답을 이해할 수 있습니다. 이 구조 덕분에 시스템은 더 직관적이고 유지보수가 쉬워집니다.
예시 : 서버가 JSON 형식으로 {"userId": j-plum, "name": "Euang", "role": "admin"}와 같은 응답을 반환하면, 클라이언트는 이 메시지의 내용만 보고도 어떤 데이터가 포함되어 있는지 쉽게 이해할 수 있습니다.
5) Client-Server 구조
- REST 아키텍처는 클라이언트와 서버를 분리된 구조로 설계합니다. 클라이언트는 사용자 인터페이스 및 사용자 경험을 담당하고, 서버는 데이터 저장 및 비즈니스 로직을 처리합니다. 이로 인해 두 시스템의 독립성이 높아집니다.
예시 : 클라이언트 애플리케이션은 Angular나 React 같은 프론트엔드 프레임워크로 구현되고, 서버는 Node.js나 Django 같은 백엔드 프레임워크로 구현될 수 있습니다. 클라이언트와 서버는 명확히 분리되어 있어 각자의 역할에 집중할 수 있습니다.
6) 계층형 구조
- REST 서버는 여러 계층으로 구성될 수 있으며, 이를 통해 보안, 로드 밸런싱, 암호화 등 다양한 기능을 추가할 수 있습니다. 이 구조는 클라이언트와 서버 사이에 프록시나 게이트웨이 같은 중간 매체를 사용할 수 있게 합니다.
예시 : 클라이언트는 서버와 직접 통신하는 대신, 먼저 게이트웨이 서버를 통해 요청을 보냅니다. 이 게이트웨이 서버는 요청을 처리하거나 추가적인 보안 계층을 추가한 후 실제 서버로 요청을 전달합니다.
inpa dev - rest api 정리
https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-REST-API-%EC%A0%95%EB%A6%AC
[WEB] 🌐 REST API 구성/특징 총 정리
REST API의 탄생 REST는 Representational State Transfer라는 용어의 약자로서 2000년도에 로이 필딩 (Roy Fielding)의 박사학위 논문에서 최초로 소개되었습니다. 로이 필딩은 HTTP의 주요 저자 중 한 사람으로 그
inpa.tistory.com