Rest API란

REST는 HTTP/1.1 스펙과 동시에 만들어졌는데, HTTP 프로토콜을 정확히 의도에 맞게 활용하여 디자인하게 유도하고 있기 때문에 디자인 기준이 명확해지며, 의미적인 범용성을 지니므로 중간 계층의 컴포넌트들이 서비스를 최적화하는 데 도움이 된다. REST의 기본 원칙을 성실히 지킨 서비스 디자인은 “RESTful 하다.” 라고 흔히 표현.

무엇보다 이렇게 잘 디자인된 API는 서비스가 여러 플랫폼을 지원해야 할 때, 혹은 API로서 공개되어야 할 때, 설명을 간결하게 해주며 여러 가지 문제 상황을 지혜롭게 해결하기 때문에 (버전, 포맷/언어 선택과 같은) REST는 최근의 모바일, 웹 서비스 아키텍처로서 아주 중요한 역할을 하고 있다.

웹 아키텍처

  1.  클라이언트/서버 (Client/Server)
  2. 균일한 인터페이스 (Uniform Interface)
  3. 계층 시스템 (Layered System)
  4. 캐시 (Cache)
  5. 상태 없음 (Stateless)
  6. 주문형 코드 (Code-on-demand)

클라이언트/서버

균일한 인터페이스

웹을 구성하는 클라이언트, 서버, 네트워크 등의 인터페이스 (웹 컴포넌트들) 중 하나라도 표준에서 벗어나면, 웹 커뮤니케이션 체계는 붕괴된다. 웹 컴포넌트들은 다음 제약에 따라 서로 일관성 있게 상호 운영된다.

  1. 리소스 식별
  2. 표현을 통한 리소스 처리
  3. 자기-서술적 메시지 (Self-descriptive messages)
  4. 애플리케이션 상태 엔진으로서의 하이퍼미디어(HATEOAS07)

리소스 식별

리소스는 웹 상에서 서로 구별할 수 있는 URI와 같은 개념으로 볼 수 있다.

표현을 통한 리소스 처리

클라이언트는 리소스 표현을 처리한다. 같은 리소스라도 표현방식은 달라질 수 있다. 예로 문서가 웹에서 HTML로 표현되지만 타 프로그램에서는 JSON으로 표현될 수 있다. 이러한 표현이 다양하다고 해서 리소스, 식별자 자체가 변하지는 않는다.

자기-서술적 메시지

자기-서술적 메시지는 메타데이터를 포함하는데, 메타데이터에는 리소스의 상태, 표현 형식과 크기, 메세지, 자신에 대한 추가 정보등 이 포함되어 있다. HTTP 메세지는 일정한 형태로 여러 종류의 메타데이터 정보를 넣을 수 있는 헤더를 제공한다.

애플리케이션 상태 엔진으로서의 하이퍼미디어

계층 시스템

계층 시스템이라는 제약조건은 프락시 또는 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다. 웹의 일관된 인터페이스를 사용하면 중간매체를 클라이언트와 서버 사이에 마치 없는 것처럼 배치할 수 있다. 일반적으로 네트워크 기반의 중간매체는 특별한 목적을 위해 클라이언트와 서버간 통신을 가로챌 수 있다. 네트워크 기반의 중간매체는 보통 보안을 강화하거나,응답을 캐싱하거나, 부하를 분산하는 용도로 사용한다.

캐시

캐시는 웹 구조의 중요 제약조건 중 하나다. 캐시라는 제약조건에 의해 웹 서버가 응답 데이터마다 캐시 여부를 선언한다. 캐싱 응답 데이터는 클라이언트가 느끼는 지연을 감소시키고 애플리케이션의 전체적인 이용 가능성과 안정성을 향상시키며, 웹 서버의 부하를 제어한다. 다시 말해, 캐싱08은 웹의 전체적인 비용을 낮출 수 있는 중요한 방법이다. 캐시는 클라이언트와 서버 사이의 네트워크 경로라면 어디에라도 위치할 수 있다. 웹 서버단, 콘텐츠 전송망CDN단, 또는 클라이언트 내에도 가능하다.

상태 없음

상태 없음 제약조건은 웹 서버가 클라이언트의 상태를 관리할 필요가 없다는 의미다. 따라서 각 클라이언트는 웹 서버와 상호작용하는 관련 상황 정보를 직접 관리해야 한다. 웹 서버는 웹 애플리케이션과의 복잡한 커뮤니케이션을 위해 필요한 상태 관리를 클라이언트에 맡김으로써 더 많은 클라이언트에 서비스할 수 있다. 이러

한 트레이드오프는 웹 구조적인 스타일의 확장성에 이바지하는 주요 요소다.

주문형 코드

웹은 주문형 코드Code-On-Demand를 아주 많이 사용한다. 이 제약조건은 스크립트나 플러그인 같은 실행 가능한 프로그램을 일시적으로 클라이언트에 전송하여, 클라이언트가 실행할 수 있도록 한다. 주문형 코드는 웹 서버와 클라이언트 사이에 기술적 결합을 만들어내기도 하는데, 클라이언트는 필요할 때마다 서버에서 내려받은 실행 코드를 이해해야 하기 때문이다. 이러한 이유로 주문형 코드는 웹의 구조적 스타일에서 유일한 선택사항이다. 주문형 코드 제약사항의 예로 자바 애플릿, 자바스크립트, 플래시 같은 웹 브라우저 기반의 기술들이 있다.

URI 규칙

  • 슬래시 (/)는 계층관계를 나타내는데 사용

  • 마지막 문자로 슬래시를 포함하지 않음
  • 하이픈(-)은 URI 가독성을 높이는데 사용
  • 밑줄(_)은 URI에 사용하지 않음
  • URI 경로에는 소문자가 적합
  • 파일확장자는 URI에 포함시키지 않음
  • API에 있어 서브 도메인은 일관성 있게 사용

리소스 원형

도큐먼트 (단수명사, 명사의 조합)

도큐먼트리소스는 객체 인스턴스나 데이터베이스 레코드와 유사한 단일개념이다. 도큐먼트는 값을 가지고 있는 필드와 다른 관련 리소스와의 링크 둘 다를 가진다.

컬렉션 (복수명사)

컬렉션 리소스는 서버에서 관리하는 디렉터리 리소스이다. 클라이언트는 새로운 리소스를 제안해서 컬렉션에 포함할 수 있다. 

스토어

스토어는 클라이언트에서 관리하는 리소스 저장소이다. 스토어 리소스는 API 클라이언트가 리소스를 넣거나 지우고, 업데이트 하는 것을 말한다. 스토어는 스스로 새로운 리소스를 생성하지 못하기 때문에 새로운 URI를 만들지는 못한다.

컨트롤러(동사)

기본으로 GET, PUT, POST, DELETE 요청에 1:1매치 되는 개념인 CRUD가 존재하며 CRUD의 앞글자들을 풀어보면 Create, Read, Update, Delete가 될 텐데, 각각 POST, GET, PUT, DELETE에 대응되는 개념이다. 그런데 사실 URI를 디자인 하다 보면 이러한 방식으로 나타내기 참 어려운 경우를 많이 만나게 된다. 그 중 가장 많은 경우가 어떤 특정한 행위를 요청하는 경우이다. 많은 분이 이럴 때 동사를 쓰는데, 앞선 포스팅에서 밝혔듯이 동사를 써서 URI를 디자인하는 것은 대체로 옳지 않은 방식으로 여겨진다.

이럴 때 컨트롤러 리소스를 정의하여 이 문제를 해결할 수 있다. 컨트롤러 리소스는 URI 경로의 제일 마지막 부분에 동사의 형태로 표시되어 해당 URI를 통해 접근했을 때 일어날 행위를 생성한다. (개념적으로는 이렇게 이해하면 됨) 생성과 관련된 요청이 POST이기 때문에 컨트롤러 리소스에 접근하려면 POST 요청을 보내야 함.

http://api.college.restapi.org/students/morgan/register
리소스 morgan을 등록

http://api.ognom.restapi.org/dbs/reindex
리소스 dbs를 재색인

http://api.build.restapi.org/qa/nightly/runTestSuite
리소스 nightly에 테스트를 수행

그리고 마치 프로그램의 함수처럼 컨트롤러 리소스에는 입력값을 전달할 수 있음. 그것은 POST 요청의 엔티티 바디에 포함되어야 함. 그리고 역시 함수에서 반환값을 돌려주듯이 컨트롤러 리소스에서는 해당 입력 값에 대한 응답 값을 돌려주어야 함.

규칙

  • 도큐먼트 이름은 단수 명사로 사용
  • 컬렉션 이름은 복수명사로 사용
  • 스토어 이름은 복수명사
  • 경로 부분 중 변하는 부분은 유일한 값(고유 값)으로 대체
  • Crud기능을 나타내는 것은 URI에 사용하지 않음
  • URI 쿼리 부분으로 컬렉션이나 스토어를 필터링 할 수 있음
    • GET/users?role=admin     - 응답 메시지의 상태표현은 컬렉션에 있는 사용자 중 'role'의 값이 'admin'인 사용자의 리스트
  • URI 쿼리는 컬렉션이나 스토어의 결과를 페이지로 구분하여 나타내는데 사용

컬렉션과 도큐먼트

도큐먼트는 우리말로 문서로 이해해도 되고, 정보라고 이해해도 무관. 도큐먼트는 엘리먼트(element)라고도 불림 컬렉션은 정보(문서)들의 집합. 컬렉션과 도큐먼트는 모두 리소스라고 표현할 수 있으며 URI에 표기가 됨

http://www.remotty.com/sports/soccer
http://www.remotty.com/sports/soccer/players
http://www.remotty.com/sports/soccer/players/13/skills

http://www.remotty.com/sports는 컬렉션임. sports컬렉션에 soccer도큐먼트가 존재하고 soccer도큐먼트에 player이라는 컬렉션이 존재함. players컬렉션에 등번호가 13번인 선수가 존재한다고 가정하면 여기서 13은 도큐먼트이다. soccer 도큐먼트와 동일한 수준의 다른 도큐먼트는 baseballmarathon 등이 있다고 볼 수 있다. 그 하위의 players의 컬렉션과 동일한 수준의 컬렉션은 뭐가있을지 생각해보면  rulesleagues 등이 존재할 것이다.

HTTP Method에 맞는 역할

HTTP Method는 여러가지가 있지만 REST API에서는 4개 혹은 5개의 Method만 사용됨. POSTGETPUTDELETE 이 4가지의 Method를 가지고 CRUD를 할 수 있음. 그러나 REST API에서 사용되는 개수는 4개 혹은 5개라고 한 이유는 PATCH를 포함하면 5개가 되기 때문.

각 Method마다 올바른 역할이 존재

URI
POSTGETPUTDELETE
http://www.remotty.com/sports
12

 http://www.remotty.com/sports/soccer

345

번호를 이용하여 설명하겠습니다.

  1. 현재 리소스 보다 한단계 아래에 리소스를 생성. POST Method를 통해 해당 URI를 요청하면 sports 컬렉션에 알맞은 soccer 또는 baseball과 같은 도큐먼트 리소스를 생성.
  2. 현재 리소스를 조회. 보통 컬렉션 리소스를 조회하게되면 하위의 도큐먼트들의 목록과 아주 간단한 정보들을 가져옴.
  3. 현재 리소스를 조회. 도큐먼트 리소스를 조회하게되면 해당 도큐먼트에 대한 자세한 정보들을 가져옴.
  4. 현재 리소스를 수정. soccer에 대한 정보를 수정하게 됨.
  5. 현재 리소스를 삭제. DELETE Method를 이용하여 현재 URI를 호출하면 sports 컬렉션에서 soccer 도큐먼트가 삭제.

추가로 주목해볼 만한 Method는 PATCH인데 기존에 REST에 익숙하신분들은 수정(update)을 위한 Method는 PUT가 익숙하지만 앞으로는 PUT대신 PATCH를 자주 써야할꺼 같음.

자세한 설명은 Edge Rails: PATCH is the new primary HTTP method for updates

요청 메소드

규칙

  • GET 메서드나 POST 메서드를 사용해 다른 요청 메서드 처리를 하면 안됨
    • 터널링tunneling은 메시지의 원래 의도를 감추거나 잘못 표현하는 것, 프로토콜의 투명성을 훼손하는 것 등의 HTTP 오용을 의미한다.

  • GET 메서드는 리소스의 상태표현을 얻는 데 사용
  • 응답헤더를 가져올 때 반드시 HEAD 메서드를 사용
    • GET 메서드와 동일하지만 바디가 존재하지 않음
  • POST 메서드는 컨트롤러를 실행하는 데 사용
    • HTTP 표준에서는 POST 메서드에 의미상 제한을 두지 않음
  • PUT메서드는 리소스를 삽입하거나 저장된 리소스를 갱신하는데 사용
  • PUT 메서드는 변경 가능한 리소스를 갱신하는데 사용
  • POST 메서드는 컬렉션에 새로운 리소스를 만드는 데 사용
  • DELETE 메서드는 그 부모의 리소스를 삭제하는데 사용
  • OPTIONS 메서드는 리소스의 사용가능한 인터낵션을 기술한 메타데이터를 가져오는 데 사용
    • OPTIONS 메서드를 사용하여 Allow 헤더에 포함된 리소스 메타데이터를 가져옴. (다음처럼 사용가능한 메서드를 가져옴 : Allow: GET, PUT, DELETE

응답상태코드

응답코드

코드이름의미
200OK

성공

201Created

새로운 리소스가 추가되었음을 알리기 위해 컬렉션이나 스토어에서 보내는 상태다. 어떤 경우에는 컨트롤러에서 보낼 수도 있다 

202Accepted

비동기 액션이 시작되었음을 알리기 위해 컨트롤러에서 보낸다. 

204No Content

바디 부분이 의도적으로 비어 있는 상태임을 나타낸다. 

301Moved Permanently

클라이언트가 요청한 리소스에 새로운 영구 URI가 할당되었음을 가리 

303See Other

컨트롤러에서 옵션인 결과를 돌려줄 때 보낸다. 

304Not Modified

조건 GET에 대해 대역폭을 보호하기 위해 보낸다. 

307Temporary Redirect

클라이언트가 요청한 리소스에 새로운 임시 URI가 할당되었음을 가리 킨다. 

400Bad Request

특별한 일이 없는 클라이언트의 에러 상태를 가리키는 오류 코드다. 

401Unauthorized

클라이언트에서 유효하지 않은 자격 증명을 보내거나 자격 증명을 보내지 않은 경우 보내는 오류 코드다. 

402Forbidden

보호된 리소스의 접근을 거부할 때 보내는 오류 코드다. 

404not Found

클라이언트가 URI에 대해 상호작용하고자 하였으나, REST API에서 URI 를 특정 리소스로 대응할 수 없을 때 보내는 오류 코드다. 

405Method Not Allowed

클라이언트에서 지원하지 않는 HTTP 메서드를 사용하여 상호작용하고자 할 때 보내는 상태 코드다. 

406Not Acceptable

클라이언트에서 지원하지 않는 미디어 타입 형식의 데이터를 요청할 때 보 내는 오류 코드다. 

409Conflict

클라이언트에서 리소스 상태를 위반하는 시도를 하고 있음을 나타내는 오 류 코드다. 

412Precondition Failed

선행 조건 중 하나가 만족되지 않았음을 클라이언트에게 알리는 오류 코 드다. 

415Unsupported Media Type

지원하지 않는 미디어 타입 형식으로 클라이언트에서 데이터를 제출하였음 을 알리는 오류 코드다. 

500Internal Server Error

API가 내부에서 문제가 생겼음을 클라이언트에게 알리는 오류 코드다. 

HTTP 헤더

규칙

  • Content-Type을 사용해야함.
    • (Content-Type 헤더는 요청이나 응답 메시지 바디에 있는 데이터 타입을 나타내기때문에 메시지 바디에 있는 바이트열 처리방법을 결정할 수 있음)
  • Content-Length를 사용해야함.
    • (Content-Length 헤더는 바이트 단위로 바디의 크기를 나타냄. 클라이언트는 이 값을 사용해 바이트의 크기가 올바르게 읽혔는지 알수 있고 HEAD요청으로 데이터의 크기를 확인할 수 있음)
  • Last-Modified는 응답에 사용.
    • (이 응답 헤더의 값은 타임스탬프로 리소스의 표현 상태값이 바뀐 마지막 시간을 나타냄. 클라이언트와 캐시 중간자는 이 헤더를 사용해 갱신여부를 결정)
  • ETag는 응답에 사용. 
    • (응답 엔티티에 포함된 표현 상태의 특정버전을 나타내는 일련의 문자열)
  • 스토어는 조건부 PUT요청을 지원해야함.
    • (PUT메서드를 사용해 스토어에 리소스를 추가하거나 갱신할 수 있어서 REST API는 클라이언트의 If-Unmodified-Since와 If-Match 요청 헤더를 통해 클라이언트의 의도를 파악할 수 있음)
  • Location은 새로 생성된 리소스의 URI를 나타내는데 사용.
    • (Location 응답 헤더의 값은 클라이언트의 관심 범위에 있는 리소스를 식별하는 URI)
  • Cache-Control, Expires, Date 응답헤더는 캐시 사용을 권장하는데 사용해야 함.
    • (캐시는 클라이언트의 대기시간을 줄일 수 있고 신뢰성 향상, api 서버의 부하감소 등 장점이 있음)
  • Cache-Control, Expires, Pragma 응답헤더는 캐시 사용을 중지하는데 사용해야 함.
  • 캐시 기능은 사용해야함.
    • (no-cache 지시자는 캐시 응답이 제공되는 것을 막음. REST API는 꼭 필요한 경우가 아니면 캐시를 사용하지 않는다. no-cache 보다 값이 작은 max-age를 사용하면 클라이언트는 갱신에 관계없이 짧은 시간 내 캐시에 저장된 복사본을 가져올 수 있음)
  • 만기 캐싱 헤더는 200응답에 사용.
    • (만기 캐싱 헤더는 성공적인 GET메서드와 HEAD 메서드의 요청에 대한 응답으로 설정)
  • 만기 캐싱 헤더는 3xx와 4xx 응답에 선택적으로 사용될 수 있음
    • (200 응답코드를 보낸 성공적인 응답에 추가로 3xx와 4xx 응답에 대한 캐싱 헤더를 추가하는 것을 네거티브캐싱 이라 하는데 리다이렉트 횟수와 REST API에 오류에 따른 부하를 감소시킴

메시지 바디 포맷

규칙

  • JSON 리소스 표현을 지원해야함 
    • (JSON은 가볍고 간단한 상호 연동을 지원.)
  • JSON은 문법에 잘 맞아야 함
    • (key-value 로 구성되며 순서와 무관. JSON은 숫자를 지원하기 때문에 문자열로 처리할 필요 없고 시간과 날짜는 지원하지 않음.)
    • JSON에 이름을 붙일 때 소문자,대문자를 섞어쓰고 특수 문자는 피해야 함.
  • XML과 다른 표현 형식은 선택적으로 지원할 수 있음

오류표현

규칙

  • 오류는 일관성 있게 표현

지원적 문제

  • 서버 구현 모델과 리소스 모델 간 자연스러운 분리
  • 일관된 크로스 포맷 하이퍼미디어 구조
  • 부분적이면서 동적으로 구성되는 응답 바디
  • 클라이언트 식별과 자격 권한의 통합


'' 카테고리의 다른 글

CORS  (0) 2017.03.17
세션 클러스터링  (0) 2016.11.09
HTML5  (0) 2016.07.28
웹서버와 WAS  (0) 2016.06.28
RestFul API  (0) 2016.06.20
세션, 쿠키, 캐시  (0) 2016.05.21

+ Random Posts