CS

RESTful 하다. (REST API와 RESTful 정리)

Unagi_zoso 2023. 7. 13. 15:58

 

API 란

개인적인 정의입니다.

Interface의 정의:

  • 복잡한 로직을 사용(접근)하기 편하게 구현한 것

API(application programming interface)의 정의:

  • 앱 서비스에서 존재하는 사용자에게 제공될만한 기능들을 사용하기 편하게 구현한 것

ex )

  • TV 리모컨 : TV 채널을 돌리기 위해서 일어나야할 리모컨 안에서의 복잡한 작업을 사용자는 알 필요도 없이 사용하기 편하게 버튼 하나 누름으로 채널을 바꿀 수 있게 구현하였다.

REST API 란

REST는 Representational State Transfer의 약자이며 해석하자면 상태(행동, 정보)을 나타낼 수 있는 전송이라 할 수 있습니다.
REST는 아키텍처 스타일이고 프로토콜이나 표준이 아닙니다. 그저 정보를 가진 쪽(server) 요청을 보내거나 받을 시의 통신과정에서
다음과 같은 구조적 형태(스타일)를 갖추고자 하는 것 입니다.

배경

HTTP 프로토콜이 사용되고 이 프로토콜을 버전업을 시키려하는데 기존 버전과 상호운용하게 할 순 없을까? 그리고 Server와 Client를 독립적으로 진화시킬 순 없을까? 에서 시작 됩니다.
그리고 로이 필딩이라는 학자가 REST 란 개념을 떠올렸고 이후 자신의 박사논문으로 확립시켰습니다.
당시엔 SOAP(Simple Object Access Protocol)이란 XML 전송 방식의 프로토콜이 있었지만 복잡함이 있어 REST에게 밀렸습니다.

형태

  • 자원(Resource) : HTTP URI
    • server에 있는 자원 인식자 ex) '/cats/1'
  • 자원에 대한 행위: HTTP Method
    • HTTP Method의 POST, GET, PUT, DELETE가 CRUD 동작에 매핑되어져 표현됩니다.
  • 추가적인 표현(정보) (Representatioins): HTTP Message Pay Load
    • Client가 자원에 대한 조작 요청 시 이를 보고 반응합니다. JSON, XML을 주로 선택합니다.

이 세 정보로 전송 시 그 전송이 어떠한 의도를 가지고 있는지 추측할 수 있습니다.
JSON 혹은 XML로 데이터를 주고 받습니다.

특성

  1. Server - Client 구조
    • 한 쪽이 자원을 요청하고 다른 한 쪽이 자원을 제공하는 Server - Client 구조입니다. 필요한 정보들을 스스로 가질 수 있어 복잡함이 줄어듭니다.
  2. Stateless(무상태성)
    • HTTP 프로토콜을 바꾸지 않고 내부 스타일을 정한 것이 기에 HTTP 프로토콜이 Stateless(무상태성)을 가집니다. 통신하는데 있어서 서로에 대한 정보를 저장하지 않습니다. 즉 각 요청을 완전히 별개의 것으로 인식하고 처리하게 됩니다. 처리방식에 복잡함이 줄어듭니다.
  3. Cacheable(캐시 가능)
    • HTTP 프로토콜을 따르기에 Last-Modified, E-Tag 태그를 사용하여 캐싱이 가능합니다.
  4. Layered System(계층화)
    • 계층화를 하여 앞단에 로드밸런서, 시큐리티, 프록시 등을 둘 수 있어서 유연합니다.
    • Client가 직접 엔드 서버에 연결할 필요가 없게되니 보안성이 높아집니다.
  5. Uniform Interface(일관적인 인터페이스)
    • Resource 조작을 일관성있게 수행한다. 다양한 환경에서 독립적으로 사용할 수 있습니다.
    • Server-Client의 결합도를 낮춥니다.
  6. Code-On-Demand(선택사항)
    • Client가 응답을 받고 처리할 때 어떻게 처리할 지에 대한 Code를 Server로부터 제공 받을 수 있습니다.

장점

HTTP 프로토콜을 그대로 사용하여 추가적인 환경변경이 없습니다.
유연한 구조, 캐싱을 통한 성능향상 기대가 가능합니다.
Server와 Client가 독립적으로 발전할 수 있습니다. (Server의 기존 API가 내부적으로 바뀌었다 하여 Client에서 반드시 바꿀 필요는 없습니다.)
(특성 부분과 비슷한 내용입니다.)

단점

표준이 존재하지 않기에 환경마다 다 다른 형태를 지닐 수 있습니다.
사용가능한 Method가 4개라 구체적인 행동을 표현하기에는 한계가 있을 수 있습니다.
point-to-point 통신모델을 기본으로 하여 Server와 Client가 연결을 맺어야하는 경우에 적합하지 않습니다.
보안에 관한 부분이 없습니다.


RESTful 이란

그래서 RESTful이란 REST한 특성을 잘 나타내는 API를 이르는 말입니다.

개인적으로는 위와 같은 특성을 가지면서도 REST API 형태만 보고도 그 행동을 짐작할 수 있게 만들어진 API라고 생각합니다.

Uniform Interface 제약조건

  1. 자원을 식별 할 수 있어야 한다.
  • URL(Uniform Resource Locator) 만으로 어떤 자원을 제어하려하는 지 알 수 있어야한다. 자원의 위치와 종류도 알아야 한다.
  • Server가 제공하는 정보는 JSON이나 XML의 형태로 HTTP body에 포함되어야 한다.
  1. 행위는 명시적이여야 한다.
  • 의미적으로 일관성 있게 HTTP Method와 URI를 정해서 만들어야한다.
  1. 자기 서술적이여야 한다.
  • 데이터에 대한 메타정보만으로 어떤 종류의 데이터인지, 데이터를 위해 어떤 애플리케이션을 실행해야 하는지 알 수 있어야 한다.
  • 정보를 얻기 위해 데이터 원본을 봐야만하게 하는 일은 일어나선 안된다.
  1. HATEOAS(Hypermedia as the Engine of Application State)
  • 클라이언트 요청에 대해 응답을 할 때, 추가적인 정보 제공의 링크를 포함해야한다. 독립적인 컴포넌트 사이에 연관관계를 주기 위함이다.
  • 서버의 링크가 바뀌어도 HATEOAS를 위해 포함된 링크를 따라 가면 되기에 Server의 진화에 Client가 유연하게 대처할 수 있다. 즉 SErver와 Client가 독립적으로 진화할 수 있게 돕는다.

REST API design guide

URI

  • 도큐먼트 : 객체 인스턴스나 데이터베이스 레코드와 유사한 개념
  • 컬렉션 : 서버에서 관리하는 디렉터리라는 리소스
  • 스토어 : 클라이언트에서 관리하는 리소스 저장소
  1. URL는 정보를 자원을 표현해야 한다.
    1. resource는 동사보다는 명사를, 대문자 보다는 소문자를 사용한다.
    2. resource의 도큐먼트 이름으로는 단수 명사를 사용해야한다.
    3. resource의 컬렉션 이름으로는 복수 명사를 사용해야한다.
    4. resource의 스토어 이름으로는 복수 명사를 사용해야한다.
    • Ex) GET /Member/1 → GET /members/1
  2. 자원에 대한 행위는 HTTP Method(GET, PUT, POST, DELETE 등)로 표현한다.
    1. URL에 HTTP Method가 들어가면 안된다.
    • Ex) GET /members/delete/1 → DELETE /members/1
    1. URL에 행위에 대한 동사 표현이 들어가면 안된다. (즉, CRUD 기능을 나타내는 것은 URL에 사용하지 않는다.)
    • Ex) GET /members/show/1 → GET /members/1
    • Ex) GET /members/insert/2 → POST /members/2
    1. 경로 부분 중 변화하는 부분은 유일한 값으로 대체한다. (즉, :id는 하나의 특정 resource를 나타내는 고유값이다.)
    • Ex) student를 생성하는 route : POST /students
    • Ex) id=12인 student를 삭제하는 route : DELETE /students/12
  3. 슬래시 구분자 ( / )는 계층 관계를 나타내는데 사용한다.
  4. URI 마지막 문자로 슬래시 ( / )를 포함하지 않는다.
    • 즉 URI에 포함되는 모든 글자는 리소스의 유일한 식별자로 사용되어야 하며 URI가 다르다는 것은 리소스가 다르다는 것
    • 역으로 리소스가 다르면 URI도 달라져야 한다.
  5. 하이픈 ( - )은 URI 가독성을 높이는데 사용한다.
  6. 밑줄 ( _ )은 URI에 사용하지 않는다.
  7. URI 경로에는 소문자가 적합하다.
    • URI 경로에 대문자 사용은 피하도록 한다.
  8. 파일확장자는 URI에 포함하지 않는다.
    • REST API 에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않는다. 대신 Accept Header 를 사용한다.
    • ex) GET: http://restapi.exam.com/orders/2/Accept: image/jpg
  9. 리소스 간에 연관 관계가 있는 경우
    • /리소스명/리소스ID/관계가 있는 다른 리소스 명
    • ex) GET: /users/2/orders (일반적으로 소유의 관계를 표현할 때 사용)

 

응답상태코드

  • 1XX : 전송 프로토콜 수준의 정보 교환
  • 2XX : 클라이언트 요청이 성공적으로 수행됨
  • 3XX : 클라이언트는 요청을 완료하기 위해 추가적인 행동을 취해야 함
  • 4XX : 클라이언트의 잘못된 요청
  • 5XX : 서버쪽 오류로 인한 상태코드

 

현실

REST는 표준이 아니기에 환경에 따라 다 다른 형태를 지닙니다. 실제 REST API라 하는 것들을 봐도 자기 서술적, HATEOAS를 지키는 API를 찾기 힘듭니다. 그러니 RESTful을 의식하면서 자신의 문제와 환경에 맞게 REST API를 잘 설계하여 일관성 있게 관리하는 것이 더 중요해 보입니다.

참고자료

더보기