Web

REST API

oagree0123 2021. 8. 31. 14:53

이번에는 HTTP 메서드를 사용하여 자원을 주고받는 방식인 REST API에 대해 알아보겠습니다. 

아래 글을 읽으시면 조금 더 쉽게 이해하실 수 있습니다. :>

 

HTTP 프로토콜

url의 앞에 http나 https가 붙어있는 경우를 본 적이 있을 것입니다. 이번 글에서는 HTTP가 무엇인지 알아보도록 하겠습니다. 그리고 HTTP와 HTTPS의 차이점을 간단하게 확인해 보겠습니다. 프로토콜 프

oagree0123.tistory.com

 


1. REST (Representational State Transfer)

REST는 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 모든 것을 의미합니다. 자원은 데이터베이스 안에 있는 이미지나 데이터 등 소프트웨어가 관리하는 모든 것을 의미하고, 상태의 전달은 데이터를 요청할 때 요청받은 데이터의 상태(정보)를 전달하는 것을 의미합니다. 가장 많이 사용하는 방식은 JSON 또는 XML 형식으로 주고받습니다.

 

예를 간단하게 들어보자면, 요청한 자원의 이름이 'STUDENT'일 경우에 학생의 정보를 JSON 또는 XML 형태로 제공해 주는 것입니다. 

 

REST의 구체적인 개념은 HTTP URI을 통해 자원을 명시하고, HTTP Method(GET, POST, PUT, DELETE)를 사용하여 해당 자원에 대한 CRUD(CREATE, READ, UPDATE, DELETE) Operation을 적용하는 것입니다.

 

2. REST 구성 요소

위에서 REST에 대해 풀어서 설명했습니다. 이에 대해 구성 요소에 대해서 조금 더 자세하게 설명하겠습니다.

  • 자원(Resource) : URI
    모든 자원은 서버에 저장되어 있으며, 고유의 ID가 있음

  • 행위(Verb) : HTTP Method
    - HTTP 프로토콜 메서드를 사용 (GET, POST, PUT, DELETE)

  • 표현(Representation) 
    - 클라이언트가 자원의 상태에 대한 요청을 하면 서버는 적절한 응답을 보냄
    - 자원은 보통 JSON, XML 형태로 주고받음

 

3. REST 특징

REST의 6가지 특징에 대해 알아보겠습니다.

 

1) Uniform Interface (일관된 인터페이스)

Uniform Interface는 리소스(URI)에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 것을 말합니다. 이렇게 설명하니 어떤 의미인지 이해하기 힘드실 것이라고 생각합니다. 이에 대해 예시를 들어보도록 하겠습니다.

 

URI https://oagree0123.tistory.com?auth=admin
한정적 인터페이스 URI https://oagree0123.tistory.com/admin

 

위의 URI는 param을 사용하여 관리자 모드로 들어갈 수 있었습니다. 이처럼 하나의 param이라면 문제가 없겠지만, 여러 개의 param이 필요할 경우 URI가 너무 길어지는 경우가 발생합니다. 반면에, 한정적 인터페이스 URI는 주소를 길게 적을 필요 없이 간단하게 표현할 수 있는 장점을 가집니다.

 

2) Stateless (상태가 없는, 무상태성)

상태가 없다는 의미는 각각의 요청에 대해 별도의 것으로 인식하고 서로 연관이 없다는 것을 의미합니다. 따라서, REST는 세션이나 쿠키를 활용하여 상태 정보를 저장 및 관리하지 않습니다. 이러한 특징은 요청을 단순히 처리하기만 하면 되기 때문에 서비스의 자유도가 높고, 불필요한 정보를 관리하지 않기 때문에 구현이 단순해집니다. 

이전 글인 HTTP 프로토콜을 읽으셨다면, 이미 이해하셨을 것입니다. :)

 

3) Cacheable (캐시 가능)

REST는 HTTP라는 기존의 웹 표준을 그대로 사용하고 있기 때문에, 웹에서 사용하는 기존 인프라를 그대로 사용할 수 있습니다. HTTP의 캐싱 기능도 사용할 수 있는데, Last-Modified 태그나 E-Tag를 이용하면 캐싱 구현이 가능합니다. 이러한 특징은 대량의 요청을 효율적으로 처리할 수 있습니다.

 

4) Client-Server Architecture (서버-클라리언트 구조)

REST 서버는 자원을 가지고 있고, 클라이언트는 자원을 요청하는 역할을 합니다. REST 서버는 API를 제공하고 비즈니스 로직 처리 저장을 담당하며, 클라이언트는 사용자 인증, Context(세션, 로그인 정보) 등을 직접 관리합니다. 이러한 특징은 서버와 클라이언트의 역할이 구분되어 서로 간의 의존성이 줄어들게 됩니다.

 

5) Self-Descriptiveness (자체 표현)

Self-Descriptiveness는 REST API 요청 메세지만 보고도 쉽게 이해할 수 있는 자체 표현 구조를 말합니다. 아래의 JSON 형태의 REST 메세지를 보고 영화의 제목과 내용을 전달하는 것과 GET 요청을 하고 있는 것을 한눈에 쉽게 파악할 수 있습니다. 

 

HTTP GET , http://localhost:8080/movie

{

    "movie" : {

          "title" : "제목",

          "content" : "내용",

    }

}

 

6) Layerd System (계층 구조)

REST 서버는 다중 계층 구조로 구성될 수 있습니다. 보안, 로드 밸런싱, 암호화 계층 등을 추가하여 구조의 유연성을 가질 수 있고, PORXY나 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있습니다.

 

4. REST API 디자인 가이드

REST API는 위에서 설명한 REST를 기반으로 서비스 API를 구현한 것을 말합니다. 지금부터는 REST API를 설계하기 위한 규칙에 대해 공부해 보겠습니다.

 

REST API 설계할 때 가장 중요한 2가지가 있습니다.

  1.  URI는 정보의 자원을 표현해야 한다.
  2. 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현한다.

위의 두 가지는 절대로 잊지 않도록 합시다!

 

REST API 중심 규칙

1) URI는 정보의 자원을 표현해야 합니다.

GET /members/delete/1

위의 URI는 REST를 적용하지 않은 상태입니다. URI는 정보의 자원을 표현해야 하는데 delet와 같은 표현이 들어가서는 안됩니다. 이는 리소스 명이 동사보다는 명사를 사용하는 것이 좋다는 것을 의미합니다.

 

2) 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현합니다.

위의 URI를 HTTP Method를 통해 수정하자면 다음과 같습니다.

DELET /members/1

멤버의 정보를 가져오거나 추가하는 방법은 다음과 같습니다.

GET /members/show/1      (x)
GET /members/1           (o)


GET /members/insert/2    (x)
POST /members/2          (o)

 

REST API 설계 규칙

1) 슬래시 구분자(/)는 계층 관계를 나타냅니다.

http://localhost:8080/members/oagree

2) URI의 마지막 문자는 슬래시(/)를 포함하지 않습니다.

http://localhost:8080/members/oagree/  (x)
http://localhost:8080/members/oagree   (o)

3) 하이픈(-)은 URI 가독성을 높이는데 사용합니다.

불가피하게 긴 URI경로를 사용하게 된다면 하이픈을 사용해 가독성을 높일 수 있습니다.

 

4) 밑줄 ( _ )는 URI에 사용하지 않습니다.

글꼴에 따라 밑줄은 문자에 가려지거나 보기 어려운 경우가 있습니다. 이러한 문제를 피하기위해 하이픈을 사용합니다.

 

5) URI 경로에는 소문자가 적합합니다.

URI경로에 대문자를 사용할 경우에 대소문자에 따라 다른 리소스로 인식할 수 있습니다. RFC 3986(URI 문법 형식)은 URI 스키마와 호스트를 제외하고는 대소문자를 구별하도록 규정하기 때문에 대문자 사용은 피하는 것이 좋습니다.

 

6) 파일 확장자는 URI에 포함시키지 않습니다.

REST API에서는 메세지 바디 내용의 포맷을 나타내기 위해 파일 확장자를 사용하지 않고, Accept header를 사용합니다.

GET / members/soccer/345/photo HTTP/1.1 Host: restapi.example.com Accept: image/jpg

 

리소스 간의 관계를 표한하는 방법

REST 리소스 간에는 연관 관계가 있을 수 있습니다. 이런 경우 아래와 같이 표현합니다.

/리소스명/리소스 ID/관계가 있는 리소스명
GET : /users/{userid}/devices

만약, 관계명이 복잡하다면 서브 리소스에 명시적으로 표현하는 방법이 있습니다. 사용자가 '좋아하는' 디바이스 목록을 표현하는 방법은 아래와 같습니다.

GET : /users/{userid}/likes/devices

 

자원을 표현하는 Collection과 Document

Collection과 Document는 리소스이며 URL에 표시됩니다. Document는 객체 하나 정도로 이해할 수 있고, Collection은 객체의 집합으로 이해하면 됩니다.

/creatores/1/products/2

위의 URI는 creatores, products인 Collection과 ID가 1인 creator, ID가 3인 product Document로 구성됩니다.

여기서 중요한 점은 Collection은 복수로 사용했다는 것입니다.