
REST (Representational State Transfer)는 웹 서비스를 설계하는 데 사용되는 아키텍처 스타일임. REST는 자원을 기반으로 한 구조를 따르며, 클라이언트와 서버 간의 상호작용에서 상태를 유지하지 않음(Stateless). 웹의 기본적인 요소들을 활용하여 HTTP 프로토콜을 기반으로 자원을 관리하고, 이를 통해 클라이언트-서버 통신을 효율적으로 할 수 있도록 설계됨.
GET /users (모든 사용자 조회)
POST 자원을 생성함. POST /users (새로운 사용자 생성)
PUT 자원을 업데이트함. PUT /users/1 (ID 1인 사용자 정보 수정)
DELETE 자원을 삭제함. DELETE /users/1 (ID 1인 사용자 삭제)
GET
조회(Read) : 정보 요청, URI가 가진 정보를 검색하기 위해 서버에 요청함.
POST
생성(Create) : 정보 입력, 클라이언트에서 서버로 전달하려는 정보를 보냄.
PUT
수정(Update) 자원을 모두 변경 : 정보 업데이트, 주로 내용을 갱신하기 위해 사용함. (데이터 전체를 바꿀 때)
PATCH
수정(Update) 자원의 일부를 변경 : 정보 업데이트, 주로 내용을 갱신하기 위해 사용함. (데이터 일부만 바꿀 때)
DELETE
삭제(Delete) : 정보 삭제.
REST는 클라이언트와 서버가 명확히 분리된 아키텍처를 요구함.
클라이언트는 사용자 인터페이스(UI)를 관리하고, 서버는 데이터를 관리하는 역할을 수행함.
둘 간의 의사소통은 API를 통해 이루어짐.
클라이언트와 서버 간의 책임이 분리되어 의존성이 줄어들고 독립적으로 발전할 수 있음.
서버는 데이터를 처리하고, 클라이언트는 사용자 경험을 관리하므로 각각의 발전과 유지보수가 용이함.
예시로 웹 브라우저(클라이언트)와 서버가 독립적으로 동작하며, 클라이언트는 서버로부터 리소스를 요청하고 이를 렌더링함.
REST는 Stateless를 강조함.
즉, 서버는 클라이언트의 이전 요청 정보를 저장하지 않음.
클라이언트의 각 요청은 모든 필요한 정보를 포함해야 하며, 서버는 각 요청을 독립적으로 처리함.
서버 확장이 쉬워지고 여러 서버에 걸쳐 요청을 분산할 수 있음.
세션을 관리하지 않아 서버가 리소스를 절약할 수 있음.
예시로 클라이언트가 인증 요청을 할 때, 매번 API 요청에 인증 토큰을 포함해야 하고, 서버는 이를 통해 사용자를 검증함. 서버는 이전 요청의 상태를 기억하지 않음.
REST에서는 응답이 캐시 가능해야 함. 서버는 응답에 대해 캐시 가능한지 여부를 명시해야 하고, 클라이언트는 이를 따라 캐시를 관리함.
이를 통해 네트워크 트래픽을 줄이고 성능을 향상시킬 수 있음.
빈번하게 요청되는 리소스를 캐시하면 서버 부하가 줄어들고, 클라이언트는 빠르게 응답을 받을 수 있고 네트워크 성능을 크게 개선할 수 있음.
예시로 자주 변경되지 않는 데이터(예: 제품 목록)는 클라이언트 측에서 캐시하고, 일정 시간 동안 다시 서버에 요청하지 않음.
REST는 계층화된 아키텍처를 허용함. 클라이언트는 중간 계층(예: 로드 밸런서, 프록시)을 통해 서버에 접근할 수 있으며, 중간 계층의 존재는 클라이언트에게 투명하게 작동함.
시스템 확장성을 높일 수 있고 로드 밸런서나 프록시 서버를 추가해 성능을 향상시키거나 보안을 강화할 수 있음.
각 계층이 독립적으로 동작하므로 관리가 용이함.
예시로 클라이언트가 요청을 할 때 중간에 캐시 서버나 로드 밸런서를 통해 데이터가 전달되지만, 클라이언트는 이러한 중간 계층의 존재를 알 필요가 없음.
REST는 일관된 인터페이스를 강조함.
클라이언트와 서버 간의 인터페이스는 일관성이 있어야 하며, 이러한 일관성은 시스템을 쉽게 이해하고 사용할 수 있게 함. HTTP 표준 프로토콜만 지키면 특정 언어나 기술에 종속되지 않고 여러 플랫폼에서 API 사용이 가능함.
시스템의 일관성을 유지함으로써 클라이언트가 새로운 리소스나 API를 배우기 쉽게 만듦.
개발자가 시스템을 쉽게 확장하고 유지보수할 수 있음.
Uniform Interface 에는 4가지 제약조건들이 존재함.
https://api.example.com/users/123는 사용자 123번에 대한 정보를 식별하는 URI임. 이 URI를 통해 사용자는 고유하게 식별되며, 해당 리소스에 접근할 수 있음.클라이언트는 리소스를 직접 변경하는 것이 아니라, 해당 리소스의 표현(representation)을 전송하거나 수신해서 리소스를 조작함. 표현은 JSON, XML 등의 형태로 서버와 주고받음. 이 표현을 수정하여 서버로 보내면, 서버는 리소스의 상태를 수정함.
PUT https://api.example.com/users/123
{
"name": "John Doe",
"email": "john.doe@example.com"
}
각 메시지(요청 또는 응답)는 그 자체로 모든 정보를 포함하고 있어야 함. 클라이언트가 추가적인 컨텍스트 없이도 요청을 이해하고 처리할 수 있도록 메시지 안에 필요한 정보를 다 담아야 함. 즉, 헤더, 메타데이터, 상태 코드 등을 포함해 어떤 리소스에 대해 어떤 작업을 할지 명확하게 표현해야 함.
요청 메시지
POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123
{
"name": "John Doe",
"email": "john.doe@example.com"
}
클라이언트는 응답 메시지에서 하이퍼미디어 링크를 통해 리소스 상태를 탐색하고, 다음 행동을 취할 수 있어야 함. 즉, 클라이언트는 서버로부터 받은 링크들을 따라가면서 애플리케이션의 상태를 전환함. 서버는 클라이언트가 어떤 리소스에 접근하고 어떤 작업을 할 수 있는지 링크로 제공함.
응답 메시지
{
"id": 123,
"name": "John Doe",
"email": "john.doe@example.com",
"_links": {
"self": {
"href": "https://api.example.com/users/123"
},
"update": {
"href": "https://api.example.com/users/123",
"method": "PUT"
},
"delete": {
"href": "https://api.example.com/users/123",
"method": "DELETE"
}
}
}
REST에서 서버가 클라이언트에게 실행 가능한 코드를 다운로드하여 실행할 수 있는 기능을 제공하는 것을 의미함.
예시로 클라이언트가 서버에서 자바스크립트 파일을 다운로드하고, 이를 통해 UI 상호작용을 처리하거나 추가적인 기능을 수행할 수 있음.
이 기능은 시스템에 유연성과 확장성을 제공할 수 있다는 장점이 있음.
하지만 잘 사용되지 않음.
선택적 원칙인 이유는 REST의 기본 철학인 단순성과 확장성을 해치지 않기 위해서임.
클라이언트 측에서 실행되는 코드는 서버 측의 컨트롤을 벗어나기 때문에 악용될 수 있는 위험이 존재함.
서버에서 생성된 코드가 클라이언트 플랫폼에 따라 호환되지 않을 수 있다는 문제가 있음. REST는 다양한 클라이언트와 상호 작용해야 하는데, 서버 측에서 실행 가능한 코드가 만일 특정 플랫폼에 종속되게 된다면 해당 API의 활용도가 떨어지게 됨.
code on demand를 지원하면 서버에서 반환되는 코드는 동적이므로 클라이언트에서 캐싱이 어려움. 클라이언트 측에서 실행 가능한 코드가 자주 변경된다면 캐싱을 적용하기 어렵고, 매번 코드를 다운로드해야 하므로 성능에 악영향을 미칠 수 있음.
REST 논문이 작성될 당시의 웹은 거의 정적 document 였고 웹 클라이언트도 웹 브라우저 뿐이였음. 당시의 클라이언트는 지금의 js 와는 다르게 로직을 구현하기 쉽지 않았던 환경이었기 때문으로 추측됨.
REST API는 REST 아키텍처 스타일을 따르는 API를 의미함. API는 서로 다른 소프트웨어 애플리케이션이 데이터와 기능을 공유하기 위해 상호작용하는 방법을 정의함.
자원 경로(Resource Path)
HTTP 메소드
요청과 응답(Request/Response)
상태 코드(Status Code)
1xx Informational(조건부 응답): 요청을 받아서 처리 중임을 나타냄. 클라이언트는 서버로부터 더 많은 응답을 기다려야 함.
2XX Successful(성공): 클라이언트의 요청이 성공적으로 처리되었음을 나타냄.
3xx Redirection(리다이렉션): 클라이언트가 다른 URL로 이동해야 함을 의미함. 주로 리소스가 이동되었거나 리소스를 요청하기 위해 추가 작업이 필요할 때 사용됨.
4xx Client Error(요청 오류): 클라이언트의 요청에 문제가 있음을 나타냄. 잘못된 요청, 권한 문제 등이 있을 수 있음.
5xx Server Error(서버 오류): 서버의 문제로 인해 요청이 처리되지 않았음을 나타냄. 서버 측의 오류나 장애를 의미함.
표현 형식
http://api.example.com/users/1
[Bad]
http://api.example.com/users/
[Good]
http://api.example.com/users
[Bad]
http://api.example.com/users/{id}/Addresses
[Good]
http://api.example.com/users/{id}/addresses
[Bad]
http://api.example.com/users/{id}/user_addresses
[Good]
http://api.example.com/users/{id}/user-addresses
요청이 성공하면 200 OK, 생성된 경우 201 Created 등의 상태 코드를 적절히 반환해야 함.
에러 발생 시 400, 404, 500 등 적절한 에러 코드를 포함하여 응답해야 함.
REST API 에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않고 Accept header 를 사용함.
[Bad]
http://api.example.com/users/{id}/profile.jpg
[Good]
GET /users/{id}/profile HTTP/1.1
Host: api.example.com
Accept: image/jpg
http://api.example.com/users/{id}/cart/checkout
http://api.example.com/users/{id}/playlist/play
URI의 형식을 복수형으로 사용하는 것이 실무에서 많이 사용
http://api.example.com/users
클라이언트와 서버가 분리되어 독립적으로 개발되고 확장될 수 있음. 서버는 API를 통해 다양한 클라이언트를 지원할 수 있음 (웹, 모바일, 데스크톱 등).
REST API는 데이터를 전달하는 형식(JSON, XML, HTML 등)이 유연하고, HTTP 프로토콜을 기반으로 동작하므로 전 세계적인 표준과 호환됨.
REST API는 HTTP의 캐시 메커니즘을 지원하여, 클라이언트 측에서 캐싱을 통해 성능을 최적화할 수 있음.
HTTPS를 통해 데이터를 암호화할 수 있으며, OAuth2, JWT 등 다양한 인증 방식을 쉽게 통합할 수 있음.
REST API는 일관성 있는 인터페이스를 제공하고, 자원 중심의 설계 덕분에 간결하고 직관적인 URI를 가짐.
REST API는 무상태성을 유지해야 하므로, 매번 모든 데이터를 클라이언트가 전달해야 함. 이로 인해 자주 요청을 보내는 경우, 데이터를 반복해서 전송해야 하는 비효율이 있을 수 있음.
REST는 HTTP 프로토콜에 강하게 의존함. 다른 프로토콜을 사용할 때 REST의 특징을 완전히 활용하기 어려울 수 있음.
REST는 요청-응답 모델을 기반으로 하기 때문에, 실시간 통신이 필요한 애플리케이션에서 한계가 있음. 이 경우 WebSocket 같은 다른 기술이 필요할 수 있음.
Over-fetching: 클라이언트가 필요한 것보다 더 많은 데이터를 받아야 하는 상황.
Under-fetching: 클라이언트가 필요한 데이터를 다 받지 못해 여러 번 요청해야 하는 상황.
RESTful API는 REST 원칙을 따르는 API를 의미함. 즉, REST 아키텍처 스타일에 맞게 설계되고 구현된 API를 가리킴.
RESTful의 "ful"은 "REST를 따르는"이라는 의미로, REST의 원칙을 엄격하게 준수한 API를 의미함.
REST 아키텍처 스타일을 따르는 모든 API를 가리킴. REST의 일부만을 사용하거나 엄격하게 준수하지 않아도 REST API라 할 수 있음.
REST의 모든 원칙을 엄격하게 준수한 API를 가리킴. RESTful API는 더 엄격한 REST 설계 원칙을 따름.