[ 기술 스터디 ] REST API

김민석·2021년 6월 20일
0

기술 스터디

목록 보기
4/18

채용 사이트를 돌아다니다보면 Rest API 기반의 개발 경험을 요구하는 곳을 많이 볼 수 있다.

분명 많이 들어보기도 했고, 배우기도 했지만 확실히 정리하고 넘어가보자.

참고


REST란?

REST 정의

  • RESTREpresentational State Tranfer의 줄임말이다.
  • 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다.

다른 말로 해보자면

자원을 정의하고 자원에 대한 주소를 지정하는 방법 전반에 대한 규칙

이라 할 수 있겠다.

REST의 필요성

그렇다면 왜 이런 규칙이 필요해졌을까?

1. 시스템 분산

큰 규모의 애플리케이션을 구조적으로 분리할 수 있게 되었다. RESTfull API를 지켜주기만 하면 상호간 통신이 가능해졌다.

2. 댜앙한 클라이언트에 대응

RESTfull API를 통해 데이터만 주고 받기 때문에 전송되는 데이터가 가벼워졌다. 따라서 다양한 종류의 클라이언트에 대응이 가능하다.
(예컨데 iOS나 android의 어플리케이션 그리고 데스크탑 브라우저)



RESTfull 하기위한 6가지 조건

  • Client-Server :

    클라이언트와 서버가 분리되어 설계되어야 함

    자원을 요청하는 부분 (Client)와 자원을 갖고 있는 부분(Server)간에 의존성이 낮아야 한다. (각 부분, 즉 클라이언트/서버는 다른 클라이언트/서버로 대체해도 작동할 수 있어야한다.)

    낮은 의존도를 위해서는 역할을 확실하게 구분하여 개발할 필요가 있다.

  • Stateless(무상태성) :

    Server는 Client로부터의 각 요청을 완전히 분리하여 인식/처리한다.

    따라서 Server의 요청 처리 방식이 일관되게 된다.
    같은 스터디원 분의 Stateless에 대한 설명

  • Cacheable :

    캐시 처리가 가능하다.

    HTTP 프로토콜을 그대로 사용하기 때문에 웹에서 제공하는 인프라를 그대로 사용할 수 있다. 즉, 캐싱 기능을 사용할 수 있다.
    (같은 URI에 대한 요청이 여러번 있다면, 클라이언트의 HTTP 캐시에서 미리 가져온 정보를 반환하여 서버 부담을 줄인다.)

  • Layered system

    Client와 소통하는 API Server 이외에 다양한 계층의 Server를 둘 수 있다.

    가장 단순한 형태로 순수 비즈니스 로직을 수행하는 API Server와 데이터를 관리하는 DB Server로 Server를 계층화 할 수 있다.

  • [optional (필수 아님)] Code on demand

    Client로 보내는 데이터를 바로 실행 가능한 코드로 보낸다.

  • Uniform interface(인터페이스 일관성) :

    URI를 지정한 자원을 조작하기 위한 통일되고 정형화된 인터페이스를 제공한다.

    예를 들어, 이미지, 텍스트 등 자원의 종류에 상관없이 일관된 형태로 요청하면 된다.

    아래에서 더 자세하게 설명한다.



Uniform interface(인터페이스 일관성)을 지켜주기 위해 지켜야할 것

서버에서 관리하는 자원을 표현하는 방식조작하는 방식을 통일하여 정형화 시키기 위해 지켜야 할 것들이다.


4가지 규칙

1. Identification of resources

자원 각각을 식별할 수 있어야 함.
즉, 자원은 하나 이상의 URI(Uniform Resource Identifier)를 갖고, 이를 통해 접근 가능해야 한다.

2. manipulation of resources thorough representations

표현에 의해 자원을 조작할 수 있어야 한다. (여기서 representations는 자원의 이름을 의미한다. 예를 들어 학생 정보는 'students'로 이름을 붙이면 'students'가 자원의 표현이다.)

3. self-descriptive message

자원을 조작하기 위한 메시지에는 자원 조작에 필요한 모든 정보를 다 담고 있어야한다. 예시

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

다음 리소스를 사용하는 방법이 링크로 제공된다.

코드 출처 및 예시

계좌와 관련된 자원을 서버로 요청했다고 가정해보자.

GET /accounts/12345 HTTP/1.1
Host: bank.example.com
Accept: application/vnd.acme.account+json
...
HTTP/1.1 200 OK
Content-Type: application/vnd.acme.account+json
Content-Length: ...

{
    "account": {
        "account_number": 12345,
        "balance": {
            "currency": "usd",
            "value": 100.00
        },
        "links": {
            "deposit": "/accounts/12345/deposit",
            "withdraw": "/accounts/12345/withdraw",
            "transfer": "/accounts/12345/transfer",
            "close": "/accounts/12345/close"
        }
    }
}

만약, 인출 가능한 돈이 없다면 다음과 같아질 것이다.

HTTP/1.1 200 OK
Content-Type: application/vnd.acme.account+json
Content-Length: ...

{
    "account": {
        "account_number": 12345,
        "balance": {
            "currency": "usd",
            "value": -25.00
        },
        "links": {
            "deposit": "/accounts/12345/deposit"
        }
    }
}

4가지 규칙의 Best Practices

1. 자원을 나타내는 데 명사를 사용하라

자원은 크게 4가지로 분류 할 수 있다.

1) document : database에서 record에 대응하는 단일 정보 => 단수 형태로 네이밍

http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/{id}
http://api.example.com/user-management/users/admin

2) collection : document의 집합 중, Server에서 관리되는 개념 => 복수 형태로 네이밍

http://api.example.com/device-management/managed-devices
http://api.example.com/user-management/users
http://api.example.com/user-management/users/{id}/accounts

3) store : document의 집합 중, Client에서 관리되는 개념 collection vs store (깔끔하게 이해하지 못했다. 일localstorage 같이 일시적인 저장소란 느낌이 있다.) => 복수 형태로 네이밍

http://api.example.com/song-management/users/{id}/playlists

4) controller : 매개변수가 있고, 리턴되는 값이 있는 실행가능 함수와 비슷한 자원들이다. 즉, input과 output이 있는 것들이다. => 동사 형태로 네이밍

http://api.example.com/cart-management/users/{id}/cart/checkout
http://api.example.com/song-management/users/{id}/playlist/play

2. 일관성이 핵심이다.

예시는 위의 1번의 코드들을 보면 된다.

  • 계층구조를 나태낼 때는 / 를 사용하라
  • URI 끝에 / 를 붙이지 마라
  • URI의 가독성을 높이기 위해 -를 사용하라
  • _를 사용하지 마라
  • URI에 소문자를 사용하라
  • 파일 확장자를 사용하지 마라

3. CRUD 기능 이름은 URI에 직접 사용하지 마라

create, read, update, delete 같은 동작 자체나 GET, PUT, DELTE 같은 메소드 자체를 URI에 사용하지 말라는 뜻이다.

👎👍
GET /members/delete/1DELETE /members/1
GET /members/show/1GET /members/1
GET /members/insert/2POST /members/2

4. Filter가 필요하면 query component를 사용하라

이것은 좋은 사례다.

/managed-devices
/managed-devices?region=USA
/managed-devices?region=USA&brand=XYZ
/managed-devices?region=USA&brand=XYZ&sort=installation-date

아래처럼 새로운 엔드포인트를 만들지 말라는 뜻이다.

/managed-devices/USA 👎

0개의 댓글