Chat 상우

[REST API] Roy Fielding이 말하는 6가지 제약 조건 본문

HTTP

[REST API] Roy Fielding이 말하는 6가지 제약 조건

chat-rilla 2023. 8. 17. 17:58

REST(Representational State Transfer)는 월드 와이드 웹(World Wide Web)과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식으로 해당 용어는 Roy Fielding의 박사학위 논문에서 소새가 되었으며 로이 필딩은 HTTP의 주요 저자 중 한 사람으로 이후 REST의 개념은 네트워킹 문화에 많은 영향을 주게 된다.

REST는 네트워크 아키텍처 원리의 모음으로 네트워크 아키텍처 원리라는 것은 자원의 대한 주소를 지정하는 방법 전반을 이야기하며 웹 상의 자료는 HTTP를 위해서 SOAP이나 쿠키 세션 트랙킹과 같이 별도의 전송 계층을 필요로 하는 것이 아닌 간단한 인터페이스를 말하는 것인데 로이 필딩이 발표한 REST의 원리를 철저하게 따르는 시스템을 RESTful이라는 용어로 지칭하게 된다. 

 

이제 우리는 로이필딩이 말하는 REST의 제약조건의 대하여 알아보고자 한다.

 

 

REST API 6가지 제한 조건

REST API는 다음과 같은 제약조건을 갖고 있으며 이를 준수하는 경우 개별 컴포넌트를 자유롭게 구현할 수 있다.

1. 인터페이스 일관성

  • 인터페이스 일관성이란 클라이언트가 API를 사용함에 있어서 통합하는 과정에서 일관된 방식으로 상호작용할 수 있는 능력을 의미하며 REST API의 인터페이스 일관성을 유지하게 되며 개발자들이 API를 이해하고 사용하는데 불편함이 감소하며 클라이언트와 서버 간의 효율적인 통신을 보장하게 된다.
    인터페이스 일관성을 위해서는 다음의 고려할 사항이 존재한다.
    • URL 설계 : 리소스의 URL(Uniform Resource Identifiler)는 명확하고 일관된 패턴을 따라야하는데 REST ful API에서 리소스의 계층 구조와 관련된 URL 구조를 일관성 있게 설계를 해야 한다.
    • Status Code(응답 상태코드) : HTTP 응답에 포함되는 상태 코드는 일관된 기준으로 사용되어야 하며 성공(200 ~ 2xx), 클라이언트 오류(400~4xx), 서버 오류(500~5xx)등의 상태 코드로 응답을 하여 클라이언트가 API의 결과를 쉽고 명확하게 이해할 수 있도록 해야 한다.
    • 데이터 형식 및 구조 : 요청과 응답의 데이터 형식과 구조도 일관성 있게 유지를해야 하는데 대표적으로 JSON 또는 XML과 같은 표준 데이터 형식을 사용하여 필요한 데이터와 필드 구조를 일관성 있게 설계를 한다.
    • 에러 처리 : 오류가 및 예외 상황에 대한 처리도 일관성 있게 처리를 해야 하는데 에러의 응답 형식과 상세 정보, 상태 코드 등을 일관성 있게 정의를 하여 클라이언트가 해당 오류를 처리하고 디버깅이 가능하도록 제공을 해야 한다.
    • 버전관리 : API의 버전 관리를 통해 이전 버전과 새 버전 간의 호환성을 유지해야 하며 변경 사항의 대한 관리가 가능해야 한다.
    • HTTP 메서드 활용 : HTTP 메서드는 다음과 같이 GET, POST, PUT, DELETE, PATC가 존재하며 이를 사용하여 일관된 방식으로 명확한 의미에 맞게 사용해야 한다. 

HTTP Method

2. 무상태(Stateless)

  • REST의 아키텍처의 한 가지 중요한 특징으로 클라이언트와 서버간의 요청이 서버에 저장하고 있는 어떠한 상태도 포함하지 않는 원칙으로 클라이언트를 기억하지 않고 각 요청을 독립적으로 처리하는 특징으로 서버의 자원을 아낄 수 있다는 특징이 있다.
    • 확장성 : 서버가 클라이언트의 상태를 기억하지 않다보니 이로 인해 새로운 서버의 인스턴스를 추가하지 않고 서버를 확장하여도 클라이언트의 요청 처리에 영향을 주지 않는다는 특징을 갖게 된다.
      해당 내용이 이해가 안된다면 로그인된 사용자의 정보를 저장하지 않는다고 생각을 하면 좋으며 이를 위해 JWT 토큰과 같은 것을 이용하여 사용자를 식별하게 된다.
    • 성능개선 : 클라이언트의 상태 정보를 유지하지 않기 때문에 상태 관리에 따른 오버헤드를 감소시키고 더 빠르게 응답을 하는 것이 가능하다.
    • 클라이언트의 자유 : 클라이언트는 각각의 요청에서 필요한 정보를 제공하면 되기 때문에 클라이언트 간에 다양한 상태 정보를 공유할 필요가 없으며 이는 클라이언트의 구현과 업데이트를 자유롭게 하는 것이 가능하다.
    • 캐싱 가능 : 무상태성은 캐시를 활용하여 응답을 저장하고 재사용할 수 있는 가능성을 제공하는데 동일한 요청에 대한 응답은 항상 동일하기 때문에 캐시를 이용하여 서버의 리소스를 효과적으로 활용할 수 있다.
    • 간결한 디자인 : 무상태성은 API의 디자인과 구현을 단순화 시키며 서버는 단순히 클라이언트의 요청을 처리하고 응답만 하면 되기 때문에 실행이 원활하다.

3. 캐시 처리 가능(Cacheable)

  •  클라이언트와 서버 간의 효율적인 통신을 위해서 사용되는 중요한 매커니즘으로 캐싱은 이전에 요청한 데이터나 응답을 저장하여 동일한 요청이나 유사한 요청이 발생되는 경우 서버로부터 데이터를 다시 가져오지 않고 캐시 된 데이터를 사용할 수 있도록 해주어 네트워크의 부하를 줄이고 응답 시간을 개선하는 것이 가능하다.
    • Cashe-Control 헤더 : Http 응답의 cache-control 헤더는 캐싱 제어 정보를 제공하며 여기는 캐시를 얼마동안 유지할 것 인지, 캐시를 어떻게 사용할 것인지에 대한 정보를 포함하게 된다.
    • ETag 헤더 : ETag는 리소스의 버전을 나타내는 태그로, 서버가 리소르를 업데이트할 때마다 변경되며 클라이언트는 이를 사용하여 서버에게 리소스의 새 버전을 요청하거나 캐시 된 리소스가 유효한지를 확인할 수 있다.
    • 조건부 요청 : 클라이언트는 If-Non-Match 헤더와 같은 조건부 요청을 사용하여 서버에게 리소스의 ETag를 보내게되며 서버는 ETag와 비교하여 변경되지 않았다면 304 Not Modified 응답을 반환하여 실제 데이터를 전송하지 않도록 하는 것이 가능하다.
    • 캐시 유형 : 캐시는 클라이언트 측, 서버 측, 중간 캐시 서버 등 다양한 위치에서 이루어질 수 있으며 캐시 유형에 따라서 캐시를 어떻게 관리하고 사용할 것인지를 결정하게 된다.
// 1. 요청의 대한 ETage를 추가하는 filter를 추가한다. 
@Configuration
public class EtagConfig{

	@Bean
    public ShallowEtagHeaderFilter getEtagHeaderFilter(){
    	// 해당 필터는 요청 마지막에 동작한다.
    	return new ShallowEtagHeaderFilter();
    }
}

4. 계층화(Layered System)

  • 계층화는 소프트웨어 설계 원칙 중의 하나로 서버 측에서 API의 다양한 기능을 논리적으로 분리하여 구성하는 방식을 말하는데 이를 통해서 코드의 모듈화, 유지보수성, 확장성등을 향상하는 것이 가능하다.
  • 아래의 각 레이어는 특정한 역할 및 책임을 가지게 되는데 서로 간의 의존성을 최소화하는 것이 중요하다. 
    의존성의 최소화는 유지보수성을 높히는 것에 용이하며 의존성의 최소화의 핵심은 비즈니스 로직을 보호하는 것이다.
    • 프레젠테이션 레이어 : 클라이언트와 상호작용을 다루는 레이어로써 클라이언트의 요청을 받아들이고 응답을 생성하게 되며 클라이언트의 요청에 대한 유효성 검사, 인증, 인가 등의 작업을 수행한다.
    • 애플리케이션 레이어 : 비즈니스 로직을 다루는 레이어로, 클라이언트의 요청을 해석하고 필요한 작업을 수행하는며 데이터 조작, 비즈니스 규칙 적용 등이 이루어진다.
    • 도메인 레이어 : 도메인 모델과 핵심 비즈니스 로직을 포함하는 레이어로 어플리케이션을 주요 도메인 개념과 관련된 엔티티, 값, 객체, 레포지토이 등이 이곳에 위치하게 된다.
    • 데이터 액세스 레이어 : 데이터베이스와 상호작용을 다루는 레이어로 데이터 저장, 조회, 갱신 등을 처리하는 역할을 담당하며 데이터 액세스 객체(DAO)등이 해당된다.

5. Code on Demand(optional)

  • 클라이언트가 서버로부터 실행 가능한 코드를 전송받아서 실행하도록 허용하는 것을 의미하는데 이로써 클라이언트는 서버로부터 추가 기능을 동적으로 가져와 실행하는 것이 가능하게 된다.
    이는 주로 웹 브라우저에서 사용되는 경우가 많으며 서버로부터 javaScript 코드를 전송받아 실행하여 동적인 기능을 추가하는 것이 code on demand의 예시이다.
    일반적으로 REST API에서 Dode on Demand를 적용하지 않는 것이 일반적으로 대부분 REST API는 클라이언트 측에서 실행 가능한 코드를 전송하지 않고 데이터를 주고받는 형식으로 사용을 하게 된다.

6. 클라이언트/서버 구조

  • 시스템을 논리적으로 분리하고 독립적으로 발전시키는 중요한 원칙 중 하나로 구조는 서버와 클라이언트 간의 역할과 책임을 명확하게 정의하며, 각각의 부분이 독립적으로 변화할 수 있도록 지원을 하게 되며 다음과 같은 특징이 있다.
    • 클라이언트 : 인터페이스를 제공하고 사용자의 요청을 생성하는 역할로 사용자가 시스템과 상호작용하는 환경으로, ui 컴포넌트, 입력 유효성 검사, 데이터 변환 등을 담당한다.
    • 서버 : 서버는 클라이언트의 요청을 수신하고 처리하며 응답을 생성하게 된다. 비즈니스 로직, 데이터 저장 및 조작, 보안, 인증, 인가 등의 작업을 수행하며, 클라이언트에게 데이터나 상태를 제공하게 된다.
    • 독립성 : 클라이언트와 서버는 독립적으로 발전할 수 있어야 합니다. 이는 서로의 변경에 영향을 주지 않으면서 개별적으로 업데이트하거나 확장할 수 있도록 한다.
    • 확장성: 서버 측에서의 변경이 클라이언트에 영향을 주지 않아야 하므로, 서버를 효율적으로 확장하거나 교체할 수 있다.
    • 이식성: 독립성과 확장성을 통해 클라이언트와 서버 간의 경계를 명확하게 유지하면서, 서로 다른 플랫폼 또는 기술을 사용하더라도 시스템을 쉽게 이식할 수 있다.
용어 정리 
  • World Wide Web : 일반적으로 웹 이라고도 불리는 것은 정보 및 문서를 인터넷을 통해 연결된 컴퓨터 네트워크에서 공유하고 검색할 수 있는 하이퍼텍스트 시스템이다.
  • HTTP : 인터넷에서 데이터를 주고받기 위한 프로토콜 중 하나로, 웹 브라우징을 비롯한 다양한 웹 기반의 작업에서 사용된다.
  • SOAP : 네트워크 상에서 구조화된 데이터를 교환하기 위한 프로토콜로, 주로 웹 서비스 통신에 사용됩니다. SOAP는 XML 기반의 메시지 포맷을 사용하여 서버와 클라이언트 간의 상호작용을 정의하고 이루어진다.
  • 세션 트래킹 : 웹 애플리케이션에서 사용자의 상태를 유지하고 관리하기 위한 기술로 웹은 기본적으로 상태 없는(Stateless) 프로토콜인데, 이로 인해 각각의 요청이 독립적으로 처리되어 사용자의 상태 정보를 계속 유지하기 어렵기 때문에 세션 트래킹은 이런 한계를 극복하기 위해 사용자의 상태 정보를 추적하고 관리하는 방법을 제공한다.
  • 오버헤드 : 어떤 작업이나 프로세스를 수행하는데 추가적으로 필요한 비용, 시간, 자원 등을 의미한다. 오버헤드는 다양한 컨텍스트에서 발생될 수 있으며 네트워크 통신 과정에서 데이터를 전송하고 수신하는 과정에서 발생하는 패킷 처리, 프로토콜 변환등의 작업은 네트워크 통신의 오버헤드로 볼 수 있다.