REST API란 무엇일까?

반응형

REST(Representational State Transfer)는 HTTP를 사용하여 통신하는 API를 구축하기 위한 아키텍처 스타일입니다. RESTful API로 간주되려면 다음 여섯 가지 핵심 제약 조건을 준수해야 한다고 합니다. 1. 클라이언트-서버방식 2. 무상태 3. 균일한 인터페이스 4. 캐시 가능
5. 계층형 시스템 6. 코드 온 디멘드 6번째는 선택사항입니다. 이들이 REST와 어떤 관련이 있는지 확인해봅시다. 

클라이언트와 서버 방식

이 원칙은 클라이언트와 서버를 물리적으로 나누라는 의미가 아니라, 책임을 명확히 분리하라는 뜻이다.
이렇게 구분하는 이유는 각 컴포넌트가 서로의 구현 세부 사항에 의존하지 않도록 하기 위함이다.

클라이언트는 클라이언트 상태를 책임진다.
여기서 말하는 상태란 화면 전환, 사용자 입력, UI 흐름과 같은 사용자와의 상호작용 상태다.

반대로 서버는 리소스의 상태를 책임진다.
데이터를 어떻게 저장하고, 어떤 규칙으로 변경하며, 어떤 표현 형태로 전달할지는 서버의 책임이다.

이처럼 역할을 분리함으로써
클라이언트와 서버는 각각 독립적으로 개발 변경 배포될 수 있으며,
이것이 REST가 대규모 분산 환경에서 확장성을 가질 수 있는 핵심 이유 중 하나다.

무상태

HTTP는 stateless한 프로토콜입니다.
이 말은 HTTP 자체가 요청과 요청 사이의 상태를 저장하지 않는다는 뜻입니다.

REST 역시 이러한 HTTP의 특성을 그대로 계승하여,
서버가 요청 간의 상태를 기억하지 않는(stateless 한) 구조를 지향합니다.
즉, REST에서는 서버가 어떤 상태를 저장하지 않아야 합니다.

그렇다면 여기서 말하는 상태(State) 는 무엇을 의미할까요?

REST에서 말하는 상태란,
데이터가 존재하느냐의 문제가 아니라, HTTP 요청을 처리하기 위해 서버가 '기억하는 정보'를 의미합니다.

조금 더 정확히 말하면, 이전 HTTP 요청이 있었음을 전제로, 다음 HTTP 요청을 처리하기 위해 서버가 저장하는 정보
이것이 REST에서 말하는 상태입니다.

이 지점에서 자연스러운 의문이 생깁니다.
"서버는 데이터의 상태를 DB에 저장하는데, 그렇다면 이것도 무상태를 어기는 것 아닐까?"라는 질문입니다.

하지만 이는 REST를 위반한 행위가 아닙니다.
REST에서 말하는 무상태성은 HTTP 요청의 흐름에 대한 상태를 저장하지 말라는 제약이지,
비즈니스 리소스의 상태를 저장하지 말라는 의미는 아닙니다.

즉, REST의 무상태성은 요청 처리 관점의 상태에 대한 이야기이지, 도메인 데이터의 상태를 부정하는 개념은 아닙니다.

균일한 인터페이스

균일한 인터페이스란 클라이언트와 서버가 정해진 규칙(인터페이스)을 통해서만 통신하도록 강제하는 제약입니다.
그렇다면, 정해진 규칙은 무엇을 말하는 걸까요?
HTTP에는 4가지 축으로 설명하고 있습니다.

1. 리소스는 URL로 식별한다 (자원 중심)

URL은 무엇을 가리키는가에 있습니다. 행위(동작)는 URL에 넣지 않습니다.

/getUser, /createOrder ❌
/users/1, /orders/10 ⭕

2. 행위는 HTTP Method로 표현한다

REST에서는 행위를 URL이 아니라 HTTP Method로 표현합니다.

  • GET → 조회
  • POST → 생성
  • PUT / PATCH → 수정
  • DELETE → 삭제

이 원칙이 지켜질 경우, URL은 자원을 나타내고 HTTP Method는 그 자원에 대해 수행할 행위를 나타내게 됩니다.

하지만 실무에서는 이 규칙을 의도적으로 우회하는 경우도 존재합니다.
그 이유는 모든 도메인 로직이 CRUD 형태로만 표현되지는 않기 때문입니다.

예를 들어 결제 취소라는 행위를 생각해보면, 이를 DELETE로 표현할 수 있을지 고민하게 됩니다.
겉보기에는 "결제 삭제"처럼 보일 수 있지만, 실제로 결제 취소는 데이터를 제거하는 행위가 아니라
결제 상태를 변경하는 도메인 행위에 가깝습니다.

이처럼 도메인 의미를 HTTP Method에 정확히 대응시키기 어려운 경우,
실무에서는 가독성과 의도를 명확히 드러내기 위해 다음과 같은 형태를 선택하기도 합니다.

POST /payments/{id}/cancel

 

행위를 HTTP Method로 표현하는 것이 REST의 원칙이지만, 실무에서는 인프라 제약, 도메인 표현의 명확성, 협업 효율성 등을 고려하여
이 규칙을 알고도 선택적으로 우회하는 경우가 많습니다.

3. 메시지는 스스로 의미를 설명해야 한다

REST에서는 HTTP 메시지가 자기 기술적(Self-descriptive) 이어야 합니다.
즉, 요청이나 응답 메시지 하나만 보더라도 별도의 문맥이나 추가 설명 없이 그 의미를 이해할 수 있어야 한다는 뜻입니다.

이를 위해 HTTP는 다음과 같은 표준 요소들을 제공합니다.

  • HTTP Method → 요청이 어떤 행위를 수행하려는지
  • Status Code → 요청 처리 결과가 성공인지 실패인지
  • Header → 요청·응답에 대한 메타 정보
  • Media-Type → 메시지 바디의 형식과 해석 방법

이 요소들만 보고도 요청의 의도와 서버의 처리 결과를 짐작할 수 있어야 합니다.

만약 HTTP 메시지만으로 의미를 파악할 수 없고, 별도의 규칙이나 내부 약속이 필요하다면
그 통신은 REST라기보다는 커스텀 프로토콜에 가깝게 됩니다.

4. 상태 전이는 링크로 안내한다 (HATEOAS)

클라이언트가 다음 행동을 하드코딩 하지않고 서버가 가능한 다음 행동을 링크로 제공을 합니다.

{
  "status": "PAID",
  "links": {
    "cancel": "/orders/1/cancel",
    "refund": "/orders/1/refund"
  }
}

하지만 웹 개발에서는 link를 통해 다음 행동을 제공해주지는 않습니다. 그렇다면 무엇일까요?

웹 개발에서는 HATEOAS의 링크를 사용하지 않고, API 문서(OpenAPI/Swagger)와 프런트엔드 코드가
다음 행동을 미리 정의합니다. 즉, 서버가 런타임에 가능한 다음 행동을 링크로 안내하는 대신, 웹 개발에서는 설계 시점에 API 문서를 통해 어떤 상태에서 어떤 API를 호출할 수 있는지를 클라이언트와 사전에 합의하게 되는 것이죠.

캐시 가능

REST에서 말하는 캐시 가능(Cacheable) 이란,
서버의 응답이 캐시 가능한지 여부를 HTTP 메시지를 통해 명확하게 표현해야 한다는 제약입니다.

즉, 이 응답을 어디까지 신뢰할 수 있는지, 얼마 동안 재사용해도 되는지를

클라이언트나 중간 계층이 스스로 판단할 수 있어야 한다는 뜻입니다.

캐시는 서버만 사용하는 개념이 아닙니다. 브라우저 캐시, 프록시 서버, CDN, API Gateway 등
여러 계층에서 함께 활용됩니다.

즉, REST는 이러한 중간 계층들의 존재를 전제로 설계된 아키텍처 스타일입니다.

그렇다면 REST에서는 캐시를 어떻게 표현할까요?
캐시 가능 여부는 HTTP Header를 통해 명시적으로 전달해야 합니다.

대표적인 헤더로는 다음과 같은 것들이 있습니다.

  • Cache-Control
  • Expires
  • ETag
  • Last-Modified

이러한 헤더들을 통해 클라이언트와 중간 계층은 응답을 캐시할 수 있는지, 언제까지 유효한지를 판단할 수 있습니다.

계층 형 시스템

REST에서 말하는 계층형 시스템(Layered System) 이란,
클라이언트가 요청을 보낼 때 그 요청이 실제로 어디까지 전달되는지 알 필요가 없도록
시스템을 여러 계층으로 나눌 수 있어야 한다는 제약입니다.

즉, 클라이언트는 하나의 서버와 통신한다고 생각하지만, 실제로는 그 사이에 로드 밸런서, API Gateway, 인증 서버, 프락시, CDN 같은
여러 중간 계층이 존재할 수 있습니다.

중요한 점은, 이러한 중간 계층들이 요청을 처리하거나 개입하더라도 클라이언트는 이를 인식하지 않아야 한다는 것입니다.

REST는 처음부터 이런 중간 계층들의 존재를 전제로 설계되었고, 이를 통해 성능 최적화, 보안 처리, 트래픽 분산 같은 문제를
애플리케이션 로직과 분리해서 해결할 수 있게 됩니다.

즉, 계층형 시스템이란 클라이언트와 서버 사이에 여러 계층을 자유롭게 둘 수 있도록 허용하는 구조라고 볼 수 있습니다.

코드온 디멘드

REST의 코드 온 디맨드(Code on Demand) 는 서버가 클라이언트의 기능을 확장하기 위해
실행 가능한 코드를 내려줄 수 있다는 제약입니다.

예를 들어, 서버가 JavaScript 같은 코드를 클라이언트로 전달하고, 클라이언트는 그 코드를 실행함으로써
서버가 미리 정의하지 않았던 동작을 수행할 수 있습니다.

다만, 이 제약은 REST의 다른 제약들과 달리 선택 사항입니다. 코드 온 디맨드를 사용하지 않더라도
REST의 핵심 제약들이 깨지는 것은 아닙니다.

실제로도 보안 문제나 복잡도 때문에 API 설계에서는 잘 사용되지 않는 편이고,
웹 환경에서 JavaScript를 내려주는 경우 정도가 대표적인 예라고 볼 수 있습니다.

즉, 코드 온 디맨드는 서버가 클라이언트의 동작을 동적으로 확장할 수 있도록 허용하는 옵션적인 제약입니다.

여러분 차례입니다. 실제 API에서 가장 자주 간과되는 REST 제약 조건은 무엇이라고 생각하시나요?

마무리

제가 생각할때 REST는 API를 개발하기위한 하나의 설계 방침이라고 생각합니다. REST어긴다고 해서 HTTP요청이 실패하거나 응답이 실패하지는 않습니다. 그렇다면, REST를 왜 중요하고 학습을 해야 할까요? REST는 클라이언트와 서버간의 약속 규약입니다. 그렇기때문에 클라이언트와 서버는 어떻게 하면 잘 통신할 수 있을지 의사소통을 해야 한다고 생각합니다. 하지만 현대개발에서는 REST를 의도적으로 어기는 경우가 종종있습니다. 예를들어 상태 전이는 링크로 전달한다,  행위는 HTTP Method로 표현한다 등.. 그렇다고 해서 그렇게 개발된 API가 엄밀하게 REST를 지키지 않았기 때문에 안 좋은 API는 아닐겁니다. 좋은 API란 클라이언트와 서버간의 소통을 얼마나 잘 해결해주는거에 있다고 생각합니다.

'개발' 카테고리의 다른 글

filter vs interceptor vs AOP  (1) 2026.01.13
새로운 인증 전략 PASETO  (1) 2026.01.11
캐시를 이용하는 방법들  (0) 2026.01.09
Lint는 무엇인가?  (1) 2026.01.08
MDC란 무엇인가 그리고 어떻게 설정할 수 있을까?  (1) 2026.01.06

댓글

Designed by JB FACTORY