Search
Duplicate
🌗

RESTful API

REST란?

REST란 Representational State Transfer의 약자로 웹 서비스를 만들 때 사용하는 제약조건을 정의하는 소프트웨어 아키텍처 스타일이다.
소프트웨어 아키텍처에 제약조건을 추가함으로써 웹의 설계를 잘 활용할 수 있는 구조를 만들기 위해 제안되었다.
일반적으로 REST는 URI를 통해 자원을 지정하고 HTTP 메소드를 사용해 해당 자원에 대한 행위를 표현한다는게 퍼져있으나 HTTP 메소드는 사실 행위의 수단중 하나일 뿐이다.
구현의 관점에 너무 매몰되지 않고 전체적인 설계 구조를 생각했을때, 소프트웨어가 웹을 어떻게 활용하면 더 생산성이 높은 설계를 가질 수 있을지 고민해보는 게 좋을 것 같다.
웹이란 뭘까. 하나의 거대한 인터페이스라고 생각한다. 웹을 통해 우리는 많은 것을 분리할 수 있었다.
즉 REST API란 분리인 것 같다. 웹이라는 효과적인 분리 구현체를 이용해 소프트웨어 아키텍처를 잘 분리시켜 생산성을 높이는 방법론인 의미인 것 같다.
로이 필딩은 REST 소프트웨어 아키텍처를 정의할 때, Null Style부터 시작했다. 즉 어떠한 제약조건없이 구성요소 간 경계가 없는 시스템 전반에서 시작하여 점진적으로 제약조건을 추가해가며 완성시켰다.

제약조건

Client-Server Architecture
크게 봤을 때는 관심사의 분리로 보는 것이 좋다. 구체적으로는 클라이언트와 서버 구조로 표현했다.
웹 설계 구조 상 주고 받을 수 있는 데이터를 충분히 활용한다면 클라이언트와 서버는 각각의 역할에만 집중하고 이것을 연결하는 것만 잘 해주면 된다.
클라이언트는 사용자 인터페이스에 집중하고 서버는 데이터 저장, 처리에 집중한다. 즉 둘 사이의 결합도를 약화시켜 클라이언트, 서버 각각이 얼마든 다른 플랫폼으로 대체될 수 있도록 한다.
기존의 구조는 웹을 사용하지 않고 다른 통신을 사용했을 것이다. 이로 인해 클라이언트와 서버가 서로를 의존하는 이슈도 있었을 것이다.
이러한 관심사의 분리로 얻을 수 있는 것은 하나 더 있다. 바로 독립적으로 개선, 확장이 가능해진다는 것이다.
Statelessness
아직 클라이언트와 서버가 완전히 분리된 것은 아니다. 해당 제약 조건을 통해서 완전히 클라이언트와 분리시켜야 한다.
서버는 무상태성을 유지해야 한다. 그리고 클라이언트는 가지고 있는 상태와 요청하려는 정보를 최대한 잘 정리해서 서버가 요청한 작업을 수행하는데 내부의 자원만 사용하도록 요청을 보내야 한다.
이를 통해 가시성, 안정성, 확장성의 속성들을 확보할 수 있다.
클라이언트는 서버가 요청에 대한 판단을 내리기에 충분한 데이터를 보내주므로 이를 위한 추가적인 정보 확인이 필요없으니 가시성이 향상된다.
상태가 존재하지 않으니 오류로부터 작업의 복구 범위가 제한되므로 신뢰성이 향상된다.
서버에 장애가 발생했을때, 서버만 고치면 된다. 마찬가지로 클라이언트에 문제가 있으면 클라이언트만 고치면 된다.
요청들의 상태를 지속적으로 유지하지 않아도 되므로 서버 구성 요소가 리소스를 빠르게 해제할 수 있으므로 확장성이 향상된다.
⇒ 하나의 서버에서만 연결을 담당하지 않아도 되므로
해당 제약조건은 상충관계를 가지는데, 가시성, 안정성, 확장성의 장점을 얻었으나 다음과 같은 단점도 존재함을 알고 있어야 한다.
무상태성을 보장해야하므로 같은 요청이 여러번 들어오더라도 똑같이 수행해주어야 한다. 때문에 네트워크 성능이 저하된다.
프로그램의 상태를 클라이언트 측에서 관리하기 때문에 서버의 일관된 제어를 받을 수 없다.
Cache
앞서 무상태성의 제약조건으로 인한 상충관계에 있는 네트워크 성능 저하를 어느정도 해결해줄 수 있는 제약조건이다.
캐시 제약 조건에서는 요청에 대한 응답의 헤더로 캐시 가능, 캐시 불가능으로 지정되어야 한다.
응답을 캐시할 수 있는 경우, 클라이언트 캐시에는 나중에 같은 요청에 대한 응답 데이터를 재사용할 수 있는 권한이 부여된다.
캐시 제약 조건을 추가하면 일부 반복되는 상호 작용을 제거할 수 있는 가능성이 생기므로 지연 시간을 줄여 효율성, 확장성, 성능을 향상시킬 수 있다는 장점이 있다.
이 제약조건도 상충관계를 가진다.
적절하지 못한 캐시 데이터로 요청을 서버에 보낸다면 캐시의 안정성이 떨어지므로 문제가 발생할 수 있으므로 신뢰성이 저하된다.
Uniform Interface
REST 스타일이 다른 아키텍처와 구분되는 핵심적인 특징은 소프트웨어를 이루는 구성요소 간의 Uniform Interface다.
구성요소 간의 인터페이스에 소프트웨어 공학의 원칙인 일반성을 적용하여 전체적인 아키텍처의 추상화를 높여 시스템 구조가 단순해지고 상호작용의 가시성도 높아졌다.
각 구성요소와 그 구현체들은 그들이 제공하는 서비스로부터 분리되고 이로 인해 각 구성요소들은 독립적으로 발전할 수 있는 진화가능성을 가지게 되었다.
구현이 서비스를 주는 쪽과 분리되면서 독립적인 발전이 가능해졌다.
이 제약조건의 상충관계는 효율성 저하다.
각 구성요소 간 교환되는 정보, 데이터가 일반성을 가지려면 표준화된 형태로 변환되어야 하기 때문이다.
분리에 초점을 맞추기 때문이다. 효율성, 즉 성능이 더 중요하다면 다른 아키텍처를 선택하면 된다.
Uniform Interface 제약조건을 위해 각 구성요소들의 동작에 대해서 제약조건들이 더 요구된다.
identification of resources
manipulation of resources through representations
self-descriptive messages
hypermedia as the engine of application state
각 연결점에 대해 표준화를 제공함으로써 독립적으로 동작될 수 있게하는 느낌이다. 그 연결점들을 인터페이스로 두는 것 같다.
객체 지향 원칙들이 공통적으로 바라보고 있는 결합도 감소, 응집도 증가를 달성하여 유지보수성을 향상시키고자 하는 것 같다.
사실 확장성, 가시성, 안정성 이런 구체적인 용어들을 사용해 각각의 장점들을 얻는 것처럼 보이지만 결국 생산성을 향상시키기 위한 것이라고 생각한다.
Layered System
각 구성요소에 있어서 연결점 외의 다른 계층의 구성요소들에 의존할 수 없도록 제한함으로써 아키텍처가 계층적인 구조를 구성하도록 한다.
이는 어떤 시스템이 알아야할 정보를 제한함으로써 전체적인 시스템의 복잡도를 감소시켜 흐름을 어렵지 않게 파악할 수 있게 해준다.
계층 구조를 이용함으로써 기존의 레거시 서비스를 캡슐화하고 새로운 서비스를 기존의 클라이언트로부터 보호한다.
결국, 정보의 제한이다. 나는 이를 분리의 다른 말로 생각하는데, 결국 또 결합도를 감소시키고 응집도를 높여서 생산성을 확보할 수 있게 해준다.
계층형 시스템의 주요한 단점으로는 데이터의 처리에 대한 오버헤드와 지연이 심화되어 사용자가 느끼는 성능이 감소된다는 것이다.
단 캐시를 지원하는 네트워크 기반 시스템에서 공유 캐시를 사용한다면 상쇄될 수 있다.
Code-On-Demand
사실 지금은 잘 사용되지 않는 제약조건이다. 동시에 선택조건이기도 하다.
당시 로이 필딩이 논문을 내던 시절의 웹은 대부분 정적 문서들이었고 웹 클라이언트도 브라우저 그 자체였던 시절이다.
아마 이때는 클라이언트 단에서 필요한 로직을 구현하기 까다로운 상황이었기 때문에 이런 조건이 생기지 않았나 싶다.
클라이언트는 서버에서 코드를 다운받아 클라이언트 기능을 일시적으로 확장할 수 있게 한다는 뜻이다.
이로써 클라이언트는 수 많은 속성들을 구현할 필요가 없어져 클라이언트를 단순화시킬 수 있다.

REST의 구성요소(작성중)

REST는 분산 하이퍼미디어 시스템을 위해 만들어진 아키텍처 스타일이다. 이를 위해 다음 세 요소에 대해 집중하고 각각의 요소에 대해 자세히 설명한다.
Data
모든 데이터가 해당 데이터를 처리하는 구성요소 내에 숨겨지고 캡슐화되는 분산 객체 스타일과 달리 REST에서의 데이터 요소는 특성과 상태를 가지는데, 이것이 REST의 핵심이다.
어떤 작업이 처리되어야할 때, 해당 작업에 필요한 정보는 저장되어 있는 위치에서 해당 정보가 사용될 위치로 이동해야 한다.
이는 데이터 자체를 프로세서로 이동시키는 것이 아닌