티스토리 뷰

뉴비의 시선

REST? REST API?

˙ᵕ˙ 2020. 12. 16. 17:03

REST 너란놈.. 대체 무엇인가?

간단요약

  • REpresentational State Transfer 의 약자로 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다.( ex. 웹)

    ->  REST란 어떤 기술이나 프로그램을 의미하는 것이 아니다. 꼭 지켜야 하는 것도 아니다. 데이터를 잘~ 전달하기 위해 쓰이는 형식이다.

  • URI(자원의 식별자)을 통한 데이터(자원의 상태 : State)를 전달하는 것을 의미한다.

  • REST의 아키텍처 스타일을 따르는 API를 REST API라고 한다.

  • Web에서의 REST API 는 HTTP를 통하여 데이터를 전달하는 것이고 일반적으로 JSON, XML 형식으로 데이터를 주고받는다.

REST의 제약조건

아키텍쳐스타일란 제약조건의 집합이다. 아래의 제약 조건들을 지켜야 REST 라고 부를 수 있다.

  • 인터페이스 일관성(Uniform interface) : 일관적인 인터페이스로 분리되어야 한다

    • identification of resources : 자원이 URI로 식별되어야 한다.

    • manipulation of resources through representations : 자원을 생성, 수정 등을 수행할 때 표현을 통해 해야한다. (HTTP메소드 : GET, POST, PUT, DELETE, ... )

    • self-descriptive messages : 메시지는 스스로를 설명해야 한다.
      -> 메시지만 보고 그 내용을 완전히 해석할 수 있어야 한다.

    • hypermedia as the engine of application state(HATEOAS) : 
      애플리케이션의 상태는 Hyperlink를 이용해 정의되어야 한다.

  • 무상태(Stateless): 각 요청 간 클라이언트의 콘텍스트가 서버에 저장되어서는 안 된다. 

  • 캐시 처리 가능(Cacheable)

    : WWW에서와 같이 클라이언트는 응답을 캐싱할 수 있어야 한다.

    • 잘 관리되는 캐싱은 클라이언트-서버 간 상호작용을 부분적으로 또는 완전하게 제거하여 scalability와 성능을 향상시킨다.

  • 계층화(Layered System): 클라이언트는 보통 대상 서버에 직접 연결되었는지, 또는 중간 서버를 통해 연결되었는지를 알 수 없다. 중간 서버는 로드 밸런싱 기능이나 공유 캐시 기능을 제공함으로써 시스템 규모 확장성을 향상시키는 데 유용하다.

  • Code on demand (optional) - 자바 애플릿이나 자바스크립트의 제공을 통해 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다. 서버에서 코드를 클라이언트로 보내 실행시킬 수 있는 것

  • 클라이언트/서버 구조 : 아키텍처를 단순화시키고 작은 단위로 분리(decouple)함으로써 클라이언트-서버의 각 파트가 독립적으로 개선될 수 있도록 해준다.

     

REST 구성 요소

  1. 자원(Resource): URI 
    모든 자원에 식별자가 존재하고, 이 자원은 Server에 존재한다. 
    자원을 구별하는 식별자는 ‘/groups/:group_id’와 같은 HTTP URI 다. 
    Client는 URI를 이용해서 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 Server에 요청한다.
  2. 행위(Verb): HTTP Method 
    HTTP Method를 사용한다. ( GET, POST, PUT, DELETE , .. )
  3. 표현(Representation of Resource) 
    Client가 자원의 상태(정보)에 대한 조작을 요청하면 Server는 이에 적절한 응답(Representation)을 보낸다. 
    REST에서 하나의 자원은 JSON, XML, TEXT, RSS 등 여러 형태의 Representation으로 나타내어 질 수 있다. 
    JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적이다.

 

REST API? 

REST 아키텍쳐 스타일을 따르는 API를 말한다. 

 

1. URI에 자원의 상태를 표현한다. 

  • 동사보다는 명사를, 대문자보다는 소문자를 사용한다.
  • 마지막 문자는 '/' 를 포함하지 않는다.
  • '_' 보다는 '-'를 사용하며 가독성을 위해 사용한다.
  • 특정 자원을 호출하기 위해서는 ID값을 사용한다.
  • 파일의 확장자를 포함하지 않는다.
  • 연관 관계 표현을 할 때는 /리소스/ID/연관된 리소스로 표현한다.

예를들어 간단하게 이러한 user의 자원이 있다 라고 한다면

{
    "Users" : [
        {   
            "id" : 1, 
            "name" : "홍길동",
            "grades": [ 
                    { "id" : 1, "수학" : 100},
                    { "id" : 2, "영어": 80}
            ]
        },
        {   
            "id" : 2,
            "name" : "이순신",
            "grades": [
                    { "id" : 1, "수학" : 88},
                    { "id" : 2, "영어": 99}
            ]
        }
    ],
    ...
}
// user 자원에 접근 -> users 전체 
http://도메인/users 

// user 자원의 id가 1인 값에 접근 -> 홍길동
http://도메인/users/1 

// user 자원의 id가 1인 값의 grade에 접근 -> 홍길동의 점수
http://도메인/users/1/grades  

// user 자원의 id가 1인 값의 grade의 id가 2인값에 접근 -> 홍길동의 영어점수
http://도메인/users/1/grades/2

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

 

  • 데이터를 조작하는 행위는 CRUD가 있다. Create(생성), Read(조회), Update(수정), Delete(삭제) 각각에 맞는 HTTP메소드를 사용한다.
  • POST, PUT, PATCH 메소드는 정보를 Body에 담아 보내기 때문에 GET, DELETE 메소드 보다 비교적 안전하게 데이터를 전송할 수 있다.
HTTP METHOD 역할
POST Create (생성)
GET Read(조회)
PUT ( PATCH ) Update (전체 수정/일부 수정)
DELETE Delete(삭제)
  • 같은 URI를 사용하더라도 메소드에 따라 행위를 구분할 수 있다. 
GET /users    // 조회
POST /users   // 생성

GET /users/1    // 조회
PUT /users/1    // 수정
DELETE /user/1  // 삭제
  • HTTP 메소드를 사용할 때 이런 목적으로만 사용해야 하는 것은 아니다. POST메소드 만으로도 CRUD를 수행할 수도 있다. 하지만 CRUD를 구분하려면 URI에 그 정보도 포함해야 할 것이다.
/createUser 혹은 /create/user  // 유저 생성 
/deleteUser 혹은 /delete/user  // 유저 삭제 
  • 이런식으로 표현해야 할 것이다. URI는 길어지고 가독성도 떨어지게 된다.

참고 : 응답상태 코드

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

 

 

REST 파헤치기

REST의 탄생

WEB (1991) 의 등장

  • 인터넷에서 정보공유를 어떻게 할 것인가?

    • 정보들을 하이퍼텍스트로 연결한다.

    • 표현형식 : HTML

    • 식별자 : URI

    • 전송방법 : HTTP

HTTP/1.0 (1994-1996)

  • HTTP/1.0가 나오기 전 이미 HTTP는 웹의 전송 프로토콜로 사용이 되고 있었고 웹은 급속도로 성장중이었다. 이 시점에 기능을 더하고 기존의 기능을 고쳐야 하는 상황에서 기존의 구축된 웹과의 호환성의 문제가 발생하였다.
  • 당시 대학원생 이었던 로이필딩은 어떻게 하면 기존의 웹을 바꾸지 않고 HTTP를 진보 시킬 수 있을까? 를 고민하였고 HTTP Object Model 을 만들었다.
  • 이것을 1998년 Microsoft Research에서 REST라는 이름으로 발표했고, 2000년 박사 논문으로 발표 했다. -> 현재의 REST를 정의하는 내용의 논문이다.

 

현재 REST API의 상황

HTTP만 잘 따라도 대부분의 REST스타일을 잘 지킬 수 있다.

하지만 Uniform interface의 제약조건 중 일부를 잘 따르기 힘들다.

 

  • self-descriptive messages : 메시지는 스스로를 설명해야 한다.
    -> 메시지만 보고 그 내용을 완전히 해석할 수 있어야 한다.

어떤 문법으로 작성한건지 알 수 없다.   Content-type을 json으로 지정 함으로써 해석할 수 있게 되었지만 여전히 op가 무엇인지, path가 무엇인지 알 수 없다.

 

json-patch+json 이라는 미디어 타입으로 정의된 메시지 이므로 명세를 보고 해석 가능하다.
  • hypermedia as the engine of application state(HATEOAS) : 
    애플리케이션의 상태는 Hyperlink를 이용해 정의되어야 한다.

HTML의 a태그에 링크로 다음 상태의 정보를 알 수 있다. Link에 이전과 다음 상태의 URI 정보를 알 수 있다.

 

Uniform interface가 왜 필요한가?

독립적 진화

  • 서버와 클라이언트가 각각 독립적으로 진화한다.
  • 서버의 기능이 변경되어도 클라이언트를 업데이트 할 필요가 없다.
    • 웹 페이지를 변경했다고 웹 브라우저를 업데이트 할 필요는 없다.
    • 웹 브라우저를 업데이트 했다고 웹 페이지를 변경할 필요도 없다.
    • HTTP 명세가 변경되어도 웹은 잘 동작한다.
    • HTML 명세가 변경되어도 웹은 잘 동작한다.

왜 API는 REST가 잘 안될까?

  • 현재 REST API 라고 하는 API들은 대부분 REST 아키텍쳐 스타일을 모두 따르고 있지 못하다.

< 웹 페이지 VS HTTP API >

문법 해석은 가능하지만, 의미를 해석하려면 별도로 문서(API문서 등)가 필요하다.

예시를 통해 알아보자.

 

< WEB >

Self-descriptive 한가? -> 만족

  1. 응답 메시지의 Content-Type을 보고 media type이 text/html 임을 확인한다.

  2. HTTP 명세에 media type은 IANA에 등록되어 있다고 하므로, IANA에서 text/html의 설명을 찾는다

  3. IANA에 따르면 text/html의명세는 http://www.w3.org/TR/html 이므로 링크를 찾아가 명세를 해석한다.

  4. 명세에 모든 태그의 해석방법이 구체적으로 나와있으므로 이를 해석할 수 있다.

HATEOAS ? -> 만족

  • a태그를 이용해 표현된 링크를 통해 다음 상태로 전의될 수 있으므로 만족

 

< API >

Self-descriptive 한가? -> 실패

  1. 응답 메시지의 Content-Type을 보고 media type이 application/json 임을 확인한다.

  2. HTTP 명세에 media type은 IANA에 등록되어 있다고 하므로, IANA에서application/json의 설명을 찾는다.

  3. IANA에 따르면 application/json의 명세는 draft-ietf-jsonbis-rfc7159bis-04 이므로 링크를 찾아가 명세를 해석한다.

  4. 명세에 json문서를 파싱하는 방법이 명시되어 있으므로 성공적으로 파싱에 성공한다. 그러나 id와 title이 무엇을 의미하는지는 알 수없다

HATEOAS ? -> 실패

  • 다음 상태로 전이할 링크가 없다.

 

self-descriptive 와 HATEOAS가 독립적 진화에 도움이 될까?

  • self-descriptive는 확장 가능한 커뮤니케이션을 가능하게 한다.
  • 서버나 클라이언트가 변경되더라도 오고가는 메시지는 언제나 self-descriptive 하므로 언제나 해석이 가능하다.
  • HATEOAS 는 애플리케이션 상태 전이의 late binding을 가능하게 한다.
  • 어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다. 쉽게 말해서 링크는 동적으로 변경이 가능하다는 것이다.

 

REST API를 제대로 작성해 보자.

 

  • self-description 

 

  • hateos

 

정리

  • 오늘날 대부분의 "REST API"는 사실 REST를 완벽하게 따르고 있지 않다.
  • REST의 제약조건 중에서 특히 Self-descriptive와 HATEOAS를 잘 만족하지 못한다.
  • REST는 긴 시간에 걸쳐(수십년) 진화하는 웹 애플리케이션을 위한 것이다.
  • REST를 따를 것인지는 API를 설계하는 이들이 스스로 판단하여 결정해야 한다.
  • REST를 따르겠다면, Self-descriptive와 HATEOAS를 만족시켜야 한다
    • Self-descriptive는 custom media type이나 profile link relation 등으로 만족시킬 수 있다.
    • HATEOAS는 HTTP헤더나 본문에 링크를 담아 만족시킬 수 있다.
  • REST를 따르지 않겠다면, "REST를 만족하지 않는 REST API"를 뭐라고 부를지 결정해야 한다.
    • HTTP API 라고 부른다.
    • 혹은 그냥 이대로 REST API라고 부른다. 

 

 

더 자세한 내용들 참고

'뉴비의 시선' 카테고리의 다른 글

추상클래스 vs 인터페이스  (0) 2020.12.22
RSA 암호시스템  (0) 2020.12.17
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함