본문 바로가기
강의 정리

그런 REST API로 괜찮은가

by iOS 개린이 2023. 3. 19.

REST가 나오기까지 

WEB(1991)

질문 : "인터넷에서 어떻게 정보를 공유할 것인가?"

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

1. HTML이란 형식으로 정보들을 표현하고

2. 정보들에 대한 식별자로 URI를 만들고

3. 그 정보들을 전송하는 방식으로 HTTP라는 프로토콜을 만들었다.

 

이렇게 WEB이 만들어짐.

 

 

HTTP/1.0 (1994-1996)

 

Roy T.Fielding이 HTTP 프로토콜 작업에 참여하면서 고민이 생긴다.

HTTP/1.0이 나오기전부터 이미 HTTP는 웹의 전송 프로토콜로 이용되고 있었고, 이미 웹은 급속도로 성장하고 있는 상황이었다.

여기서 새로운 HTTP를 적용하면 기존 웹과의 호환성에 문제가 생기지 않을까? 하는 고민이 생긴 것이다.

 

"어떻게 하면 웹에 문제없이 HTTP를 진보시킬 수 있을까"

그래서 나온 해결책이 HTTP Object Model이다. 이것은 4년 후에 REST라는 이름으로 발표된다.

 

 

XML-RPC (1998)

by Microsoft -> SOAP

 

98년에 마이크로소프트에서 원격으로 다른 시스템의 메소드를 호출할 수 있는 프로토콜인 XML-RPC를 만든다.

이게 나중에 SOAP이란 이름으로 변경된다.

 

하지만 SOAP은 복잡하고, 규칙이 많다는 단점이 있었고, REST는 그에 비해 단순하고, 규칙이 적었기 때문에

SOAP은 갈수록 인기가 추락하고, REST는 갈수록 인기가 상승했다.

 

 

REST API

REST 아키텍쳐 스타일을 따르는 API 

먼저 REST란 무엇인지에 대해서 알아보자.

 

 

REST

-분산 하이퍼미디어 시스템(웹)을 위한 아키텍쳐 스타일

아키텍쳐 스타일이라는 것은 제약조건의 집합이라고 볼 수 있다.

이 제약조건을 모두 따를 때 REST를 따르는 것.

 

 

REST를 구성하는 스타일

1. client-server

2. stateless

3. cache

4. uniform interface

5. layered system

6. code-on-demand(optional) - 서버에서 코드를 클라이언트로 보내서 실행할 수 있어야 한다. ex) 자바스크립트

 

오늘 날 REST API라고 불리는 것들은 대체로 위 스타일들을 잘 지키고 있다.

왜냐하면 HTTP만 잘 따라도 위 조건의 대부분을 지키는 것이기 때문이다.

대부분 잘 지키지만, 지키지 못하는 것이 한 가지 있는데 그것이 uniform interface 다.

 

 

uniform interface의 제약조건

1. identification of resources - 자원을 URI로 식별하면 된다.

2. manipulation of resources through representations - representations 전송을 통해서 자원을 조작해야 한다.

3. self-descriptive messages

4. hypermedia as the engine of application state(HATEOAS)

 

오늘 날 REST API라고 불리는 것들 중 대부분 1번과 2번은 지키고 있지만, 3번 4번을 지키지 못하고 잇다.

하나씩 살펴보자.

 

 

self-descriptive messages 

-메시지는 스스로를 설명해야 한다.

HTTP/1.1 200 OK
Content-Type : application/json-patch+json
[{"op" : "remove", "path" : "/a/b/c"}]

 

메시지 내용 중에서 한 가지라도 빠진다면, 클라이언트는 메시지를 보고 해석하는 것이 어렵겠죠?

따라서 메시지의 내용을 보고 해석이 가능해야 self-descriptive messages 조건을 만족하는 것이다.

하지만 오늘 날 REST API는 만족하지 못하고 있다.

왜냐하면 대부분 미디어 타입을 보면 json이라고만 되어 있고, 어떻게 해석해야 하는지는 메시지만 보고 알 수 없기 때문이다.

 

 

HATEOAS

-애플리케이션의 상태가 Hyperlink를 이용해 전이되어야 한다.

대충 상태를 전이할 때마다 해당 페이지에 있던 Hyperlink를 통해 전달되어야 한다 조건 같음..

 

 

 

uniform interface이 필요한 이유

"독립적 진화"를 위해서 uniform interface가 필요함.

 

독립적 진화란?

1. 서버와 클라이언트가 각각 독립적으로 진화한다.

 

2. 서버의 기능이 변경되어도 클라이언트를 업데이트 할 필요가 없다. 

새로운 API가 생기거나 변경, 삭제 되어도 클라이언트가 업데이트 할 필요가 없는 것

 

3. REST를 만들게 된 계기 "How do i improve HTTP without braking th WEB"

처음에 새로운 HTTP를 만들 때 기존 웹과 호환성 문제로 고민하다가 REST가 만들어졌다고 했죠?

 

독립적 진화가 이 REST 탄생의 계기인 것이고, 이를 지키지 못한다면 REST라고 볼 수 없는 것.

 

 

-REST를 잘 지키는 웹

 

REST를 잘 지키는 웹의 특성

1. 웹 페이지를 변경했다고 웹 브라우저를 업데이트 할 필요가 없다.

2. 웹 브라우저를 업데이트했다고 웹 페이지를 변경 할 필요도 없다.

3. HTTP 명세가 변경되어도 웹은 잘 동작한다.

4. HTML 명세가 변경되어도 웹은 잘 동작한다.

 

 

모바일 앱의 리뷰들을 보면 "업데이트 좀 그만해줘", "업데이트 좀 해줘" 등의 피드백을 볼 수 있다.

웹에서는 업데이트를 한다고 다른 이용자들에게 업데이트 버전을 사용하라는 말을 하지 않죠?

근데 앱에서는 이런 일들이 자주 생긴다.

이 이유는 엄밀히 말하면 앱의 클라이언트와 서버가 REST하게 통신하고 있지 않다 라고 말할 수 있다.

앱이 REST하다면 상호운용성이 훌륭하기 때문에 업데이트를 해도 이용자들에게는 별 문제가 생기지 않을 것이다.

 

웹이 이러한 문제가 발생하지 않는 이유는?

웹에서는 상호운용성을 깨지 않기 위해서 엄청난 노력을 함.

 

 

REST가 웹의 독립적 진화에 도움

-HTTP에 지속적으로 영향을 줌

-Host 헤더 추가

-길이 제한을 다루는 방법이 명시

-URI에서 리소스의 정의가 추상적으로 변경됨. "식별하고자 하는 무언가"

-기타 HTTp와 URI에 많은 영향을 줌.

-HTTP/1.1 명세 최신판에서 REST에 대한 언급이 들어감.

 

 

REST는 성공적?

REST는 웹의 독립적 진화를 위해 만들어 졌고, 웹은 독립적으로 진화하고 있기 때문에 성공했다고 봄.

 

 

REST API

Q : REST API는 REST 제약 조건들을 모두 지켜야 하는가? 

예스, 왜냐면 REST를 만든 로이 필딩이 제약 조건들을 모두 지키라고 말했음.

 

그럼 우리는 원격 API를 만들 때 꼭 REST API로 만들어야 하는가?

노노, 로이필딩은 "시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면, REST에 대해 따지느라 시간을 낭비하지마라" 라고 말함.

 

 

왜 API는 REST가 잘 안되나?

일반적인 웹과 비교를 해보자.

  흔한 웹 페이지 HTTP API
Protocol HTTP HTTP
커뮤니케이션 사람-기계 기계-기계
Media Type HTML JSON

 

위 표에서 HTML과 JSON이 이 문제의 원인이구나 알 수 있다. (난 몰라..)

 

HTML과 JSON을 비교해보자.

  HTML JSON
Hyperlink 됨 (a 태그 등) 정의되어있지 않음.
Self-descriptive 됨 (HTML 명세) 불완전.

 

JSON은 문법 해석은 가능하지만, 의미를 해석하려면 별도의 문서(API 문서)가 있어야 함.

 

이번엔 코드를 통해 각각 조건을 만족하는지 비교해보자.

 

HTML (투두 리스트)

GET /todos HTTP/1.1
Host : example.org

HTTP/1.1 200 OK
Content-Type : text/html

<html>
<body>
<a href="https://todos/1">회사 가기</a>
<a href="https://todos/2">집에 가기</a>
</body>
</html>

 

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. 명세에 모든 태그의 해석방법이 구체적으로 나와있으므로 이를 해석하여 문서 저자가 사용자에게 알려줌.

 

HTML은 이 메세지 들어있는 힌트만을 단서로 메시지를 해석할 수 있기 때문에  Self-descriptive 하다.

 

HATEOAS의 관점에서 보면

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

 

HTML은 둘 다 만족함.

 

 

 

JSON (투두 리스트)

GET /todos HTTP/1.1
Host : example.org

HTTP/1.1 200 OK
Content-Type : application/json

[
  {"id" : 1, "title" : "회사 가기"},
  {"id" : 2, "title" : "집에 가기"}
]

 

Self-descriptive의 관점에서 보면

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

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

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

4. 명세에 json 문서를 파싱하는 방법이 명시되어있으므로 파싱에 성공함. 하지만 "id"가 무엇을 의미하고, "title"이 무엇을 의미하는지 알 방법이 없다.

 

HATEOAS의 관점에서 보면

1. 다음 상태로 전이할 링크가 없기 때문에 만족하지 못함.

 

JSON은 둘 다 만족 못함.

 

 

Self-descriptive가 독립적 진화에 어떻게  도움이 될까?

-확장 가능한 커뮤니케이션

서버나 클라이언트가 변경되더라도 오고가는 메세지는 언제나 self-desvriptive 하기 때문에 언제나 해석이 가능하다.

 

 

HATEOAS가 독립적 진화에 어떻게  도움이 될까?

-애플리케이션 상태 전이의 late binding

어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다.

쉽게 말하면 링크는 동적으로 변경될 수 있다.

링크가 맘대로 변경될 수 있으니 링크가 변경되어도 클라이언트는 동적으로 변경된 링크를 따라가면 됨.

 

 

JSON을 Self-descriptive하게 만들어보기.

 

Media type을 변경하는 방법. 

 

1. 미디어 타입을 하나 정의한다.

2. 미디어 타입 문서를 작석한다. 문서에는 "id"와 "title" 무엇인지 정의해둔다.

3. IANA에 미디어 타입을 등록. 이 때 만든 문서를 미디어 타입의 명세로 등록한다.

4. 이제 이 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 메시지의 의미를 온전히 해석할 수 있음.

 

ex) Content-Type : application/vnd.todos+json

GET /todos HTTP/1.1
Host : example.org

HTTP/1.1 200 OK
Content-Type : application/vnd.todos+json

[
  {"id" : 1, "title" : "회사 가기"},
  {"id" : 2, "title" : "집에 가기"}
]

 

단점은 매번 미디어 타입을 정의해야 하기 때문에 번거로움.

 

 

Profile을 이용하는 방법.

 

1. id와 title이 무엇인지 의미를 정의한 명세를 작성한다.

2. Link 헤더에 profile relation으로 해당 명세를 링크한다.

3. 이제 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 온전히 해석할 수 있음.

 

ex) Link: <https://example.org/docs/todos>; rel="profile" 추가

GET /todos HTTP/1.1
Host : example.org

HTTP/1.1 200 OK
Content-Type : application/vnd.todos+json
Link: <https://example.org/docs/todos>; rel="profile"

[
  {"id" : 1, "title" : "회사 가기"},
  {"id" : 2, "title" : "집에 가기"}
]

 

단점

1. 클라이언트가 Link 헤더와 profile을 이해해야 한다.

2. Content negotiation을 할 수 없다.

 

 

 

JSON을 HATEOAS하게 만들어보기.

 

data 사용

 

1. data에 다양한 방법으로 하이퍼링크를 표현한다.

 

ex) 

GET /todos HTTP/1.1
Host : example.org

HTTP/1.1 200 OK
Content-Type : application/vnd.todos+json
Link: <https://example.org/docs/todos>; rel="profile"

[
  {
    "link": "http://example.org/todos/1", 
    "title": "회사 가기"
  },
  {
    "link": "http://example.org/todos/2", 
    "title": "집에 가기"
  }
]

 

단점은 링크를 표현하는 방법을 정의해야함.

 

 

 

정리

-오늘날 대부분의 REST API라고 불리는 것들은 실제로 REST를 따르지 않고 있음.

-REST의 제약조건 중에서 특히 Self-descriptive와 HATEOAS를 만족하지 못함.

-REST는 긴 시간에 진화하는 웹 애플리케이션을 위한 것이다.

-REST를 따르는 API를 만들 것인지는 설계하는 이들이 스스로 판단해서 결정해라.

-Self-descriptive은 custom media type이나 profile link relation 등으로 만족시킬 수 있고,

HATEOAS는 HTTP 헤더나 본문에 링크를 담아 만족 시킬 수 있다.

 

 

 

 

iOS 개발자가 REST API를 이해해야 하는 이유는 무엇일까?

 

REST API는 모바일 애플리케이션이 서버와 통신하고 데이터베이스, 웹 서비스 또는 클라우드 스토리지와 같은 리소스에 접근하는 일반적인 방법이다.

따라서 웹 서비스와 상호작용하고 다른 소프트웨어 시스템과 데이터를 교환 할 수 있는 애플리케이션을 구축하기 위해서 iOS개발자에게 중요하다.

 

iOS 앱에서 REST API를 사용하려면 개발자가 HTTP 메서드, JSON 및 XML과 같은 데이터 형식, 토큰 또는 OAuth와 같은 인증 메커니즘을 잘 이해해야 한다.

또한 API 엔드포인트에 요청하고 서버에서 반환된 응답을 처리할 수 있어야 한다.

 

*엔드포인트란?

-API는 두 시스템이 상호작용할 수 있게 하는 프로토콜의 총 집합이라고 한다면

EndPoint란 API가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL.

GET, POST 등의 메소드는 같은 URL들에 대해서도 다른 요청을 하게끔 구별하게 해주는 항목이 바로 EndPoint다.

 

 

iOS 개발에서 REST API를 이용한 일반적인 작업's

 

1. 서버에서 데이터 검색

API 엔드포인트에 대한 HTTP의 GET 메서드를 수행하고 반환된 데이터를 앱에서 적합하게 사용하는 작업.

 

2. 서버에 데이터 보내기

API 엔드포인트에 HTTP의 POST 메서드 또는 PUT 메서드를 수행하고 JSON 또는 XML 형식으로 데이터를 보내는 작업이 포함될 수 있다.

 

3. 사용자 인증

인증 토큰 또는 OAuth를 사용하여 REST API를 통해 사용자를 인증하고 보호된 리소스에 접근하는 작업 등.

 

4. 에러 처리

서버에서 반환된 HTTP 에러 코드를 처리하거나 네트워크 통신 중 발생하는 에러를 처리하는 작업 등.

 

 

iOS 개발자는 REST API를 이해함으로써 다양한 백엔드 시스템과 효율적이고 효과적으로 통신하는 앱을 만들 수 있다.

 

 

 

 

 

 

 

Reference

-https://www.youtube.com/watch?v=RP_f5dMoHFc

'강의 정리' 카테고리의 다른 글

앱으로 문제 해결하는 순서와 방법(강의 정리)  (0) 2023.05.27
HTTP에 관하여  (0) 2023.03.30
IOS 개발자 로드맵 정리  (0) 2022.10.03
TCP/IP (Transmission Control Protocol/Internet Protocol)  (0) 2022.09.29
OSI 7 Layer  (0) 2022.09.29