티스토리 뷰
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 구성 요소
- 자원(Resource): URI
모든 자원에 식별자가 존재하고, 이 자원은 Server에 존재한다.
자원을 구별하는 식별자는 ‘/groups/:group_id’와 같은 HTTP URI 다.
Client는 URI를 이용해서 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 Server에 요청한다. - 행위(Verb): HTTP Method
HTTP Method를 사용한다. ( GET, POST, PUT, DELETE , .. ) - 표현(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 한가? -> 만족
-
응답 메시지의 Content-Type을 보고 media type이 text/html 임을 확인한다.
-
HTTP 명세에 media type은 IANA에 등록되어 있다고 하므로, IANA에서 text/html의 설명을 찾는다
-
IANA에 따르면 text/html의명세는 http://www.w3.org/TR/html 이므로 링크를 찾아가 명세를 해석한다.
-
명세에 모든 태그의 해석방법이 구체적으로 나와있으므로 이를 해석할 수 있다.
HATEOAS ? -> 만족
- a태그를 이용해 표현된 링크를 통해 다음 상태로 전의될 수 있으므로 만족
< API >
Self-descriptive 한가? -> 실패
-
응답 메시지의 Content-Type을 보고 media type이 application/json 임을 확인한다.
-
HTTP 명세에 media type은 IANA에 등록되어 있다고 하므로, IANA에서application/json의 설명을 찾는다.
-
IANA에 따르면 application/json의 명세는 draft-ietf-jsonbis-rfc7159bis-04 이므로 링크를 찾아가 명세를 해석한다.
-
명세에 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
- File Protection
- RAID Architecture
- 빅데이터 플랫폼
- Spring
- SQL
- 하둡
- HDFS
- JSON
- aop
- Replacement Strategies
- Variable allocation
- Disk System
- I/O Services of OS
- Disk Scheduling
- vmware
- Free space management
- Flume
- jdbc
- mapreduce
- gradle
- hadoop
- Java
- springboot
- linux
- 빅데이터
- SPARK
- Allocation methods
- maven
- I/O Mechanisms
- oracle
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |