본문 바로가기
개발 관련/http

REST (1)

by lazysnack 2022. 7. 14.

요즘 API 를 보면 흔히 REST 하게 API 를 작성한다고들 합니다. 실제 보면 대부분 url 을 명사로 쓰고, HTTP Method 를 잘 배분한다는 것으로 알고 있습니다. 실제로 이렇게 설명하는 곳도 많고, 저 또한 뭐 대수인가 싶은 느낌으로 저정도만 알고 있었습니다. 최근 책을 보다가 REST 에 대한 내용이 나와 이를 토대로 알고 있는 부분에 대해서는 견고하게, 몰랐던 부분은 플러스(+) 해보려고 합니다.

1. REST 란?

REST (REpresentational State Transfer - 표현적인 상태 전송) 란 쉽게 말하면, 애플리케이션의 리소스(데이터) 를 표현하는 URI 양식입니다.

REST 라는 단어 자체는 2000년 로이 필딩(Roy Fielding) 의 논문에서 처음 나온 단어라고 합니다. 로이 필딩은 REST를 상호 지연을 줄이고 보안을 강화하여 레거시 시스템을 캡슐화하기 위해 컴포넌트 상호작용, 인터페이스의 일반성, 컴포넌트 독립 배포, 중간 컴포넌트의 확장성을 강조한다고 했습니다.

우리가 쉬이 알고 있는 것으로, 명사 + HTTP 메소드 형태로 나타내는 것입니다. 가령 계정 정보들을 가져오고 싶다면, /accounts 에 HTTP GET 메소드를 쓰는 것이죠. 결국 URI 는 원격 서버에 있는 리소스와 이 리소스에 어떤 일을 요청할 것인지를 명시하는 것으로 볼 수 있습니다.


하지만, 이러면 HTTP 메소드를 생성, 조회, 수정, 삭제(CRUD) 작업과 연관지어 생각하기 쉬운데 (GET - 조회, POST - 생성) 이는 REST 취지와 맞지 않을 뿐더러, 리소스 표현형을 이해하는데에도 도움이 되지 않습니다. 오히려 이런 발상은 리처드슨 성숙도 모델의 레벨 0 (원격 프로시저 호출 - Remote Procedure Call, RPC) 과 가깝습니다.


REST 형 API 는 동작이 아닌 명사를 대상으로 하며, 명사는 리소스를 나타냅니다.


리소스는 URI로 식별하며, 리소스는 여러 가지 방법으로 참조할 수 있기 때문에 어디부터 시작하더라도 같은 리소스에 접근해야 합니다. 가령 사용자 리소스의 경우 GET /users/:id 를 통해 특정 사용자의 리소스를 얻거나, 이 사용자를 팔로우 하는 다른 사용자 목록을 GET /users/:id/followers/:id 하여 조회할 수 있습니다. 리소스 표현형은 리소스 그 자체가 아닌 리소스를 표현하는 수단이므로 같은 리소스를 여러 가지 형태로 나타내도 전혀 문제가 없습니다.


클라이언트-서버는 리소스 표현형을 끊임없이 서로 주고받으며 그 과정에서 서버의 리소스를 생성, 수정, 삭제할 때 필요한 데이터를 실어 보냅니다.


리소스 표현형은 주로 JSON, XML 의 포멧을 사용하지만, 어떤 형식이나 임의 표현도 가능합니다.

2. REST 의 6대 제약

로이 필딩은 아키텍쳐적인 결합도를 낮추기 위해 REST 에서 6가지 제약 조건을 말하는데요. 이러한 제약 조건을 잘 지킨다면 RESTful 한 시스템이라고 할 수 있습니다.

1. 클라이언트 - 서버

  • 서버와 클라이언트의 역할을 명확히 구분하는 것입니다. 클라이언트는 요청을 전송하고, 서버는 응답을 합니다.

2. 일관된 인터페이스

  • 리소스를 어떤 명사로 관리하는지 등, 인터페이스를 일관하게 가져가 클라이언트와 서버의 결합도를 낮추는 것입니다.
  • HTTP 프로토콜을 써서 구현하라는 규정은 없지만, 사실상 HTTP 가 대부분이며, HTTP 명세에 따르면, URI = 리소스 명사 + HTTP 동사 입니다.

3. 무상태

  • 서버가 클라이언트로부터 받은 요청에는 그 요청을 처리하는데, 필요한 모든 정보가 포함되어 있어야 합니다. (서버에서는 클라이언트의 상태를 알 필요가 없음) 만약, 상태가 필요하면 클라이언트가 가지고 있어야 합니다.
  • 확장성, 가시성, 신뢰성을 확보할 수 있지만, 요청이 커지는 단점이 있을 수 있습니다.

4. 캐시 기능

  • 서버의 응답은 캐시에 보관해야 합니다.
  • 요청 별로 캐시 가능/불가를 명시해야 하며, 캐시할 수 있다면, 동일 요청이 왔을 경우 응답데이터를 재사용 할 수 있어야 합니다.

5. 계층화 시스템

  • 클라이언트는 서버에 직접 접근하여 데이터를 가져올 수 없습니다.
  • 클라이언트-서버 사이에 갖가지 소프트웨어/하드웨어가 올 수 있으므로 계층을 통해 접근을 못하게 해야 확장성이 좋아집니다.

6. 코드 온 디맨드 (Optional)

  • 계층적 구조로 자신과 인접한 레이어하고만 소통해야 컴포넌트들은 삭제/대체 하기가 수월해져 확장성이 높아집니다.
  • 클라이언트는 서버로부터 정적인 데이터(json, xml)를 받아서 가공하는 것이 아닌, 실행 가능한 코드를 넘겨받아 클라이언트에서 실행하는 것입니다.

위의 6가지 중 6. 코드 온 디멘드는 선택 사항입니다.

3. REST API 의 리처드슨 성숙도

위에서 REST 를 설명하면서 리처드슨 성숙도에 대해서 잠깐 언급 했었는데요.

리처드슨 성숙도는 레오나르드 리처드슨(Leonard Richardson) 이 개발한 것으로 REST 제약에 부합하는 정도를 API 등급으로 메긴 것입니다.

0레벨부터 3레벨까지 있으며, 레벨이 높을 수록 REST 를 잘 준수했다고 할 수 있습니다.

1. 레벨 0 : POX (Plain Old XML) 범벅

  • HTTP 를 원격지와 데이터를 주고받는 전송 프로토콜로 사용할 뿐 애플리케이션 상태를 나타내는 용도로 사용하지 않습니다.
  • HTTP 메소드 한 개로 /getUser 같은 단일 URI 에 요청/응답을 실어 나릅니다.
  • REST 보다는 RPC 모델의 전형적인 예라고 할 수 있습니다.

2. 레벨 1 : 리소스

  • 서로 다른 리소스를 분간할 능력을 갖추기 시작한 단계
  • POST user/1234/posts 같이 리소스 기반으로 통신을 하지만, HTTP 메소드는 하나만 씁니다.

3. 레벨 2 : HTTP 동사

  • HTTP 동사를 리소스 명사와 고루 결합해서 사용하는 단계
  • HTTP 사용법에 최대한 가깝에 HTTP 메소드 (GET, POST, PUT, DELETE 등) 를 사용한다.

4. 레벨 3 : 하이퍼미디어 제어

  • HATEOAS(Hypertext As The Engine Of Application State) 로 애플리케이션의 상태를 관리하는 단계
  • 클라이언트가 다음에 할 수 있는 일이 무엇인지 알려주고, 그 일을 하는 데 필요한 URI 를 건네주는 단계입니다.

4. 정리

REST 에 대해서 막연히 알고 있던 걸 좀 풀어봤습니다.

생각과는 다르게, 내용도 많고해서 이해하는데 오래 걸렸네요.

REST 를 사용함에 있어 제약이 있는지도 몰랐고, 이번에 정리하면서 평소 REST 라고 만든 것들이 어떤 제약을 지키고 있는가 생각해보는 시간이 된 것 같습니다. (대략 6개 중에 3,4개는 알게모르게 지키는 것 같네요.)

'개발 관련 > http' 카테고리의 다른 글

HTTP 메시지  (0) 2022.07.14
1. HTTP 개관  (0) 2022.07.14
REST (2)  (0) 2022.07.14