/ POSTS

[WEB] RESTful API에 대해서 알아보자. 💡

Note : 이 글은 지극히 주관적인 생각을 토대로 작성된 글입니다. 혹시나 잘못된 부분이 있다면 메일 또는 코멘트를 통해 알려주시면 감사하겠습니다. 😄 제 메일은 About 탭에서 확인하실 수 있습니다. 📧

Intro

정말 오랜만에 포스팅을 작성하게 되었다. 이번 포스팅에서는 Restful API에 대한 내용을 정리하고자 한다. 이전부터 정리하고 싶었던 내용이기도 하고, 포스팅을 작성해야지 생각만 계속 하다가 그게 지금까지 미뤄왔던것 같아서 이번 포스팅에서 그 내용을 다루고자 한다. 서론이 길었다. 바로 본론으로 들어가보자.

RESTful API란 무엇인가?

  • 먼저 RESTful이란 용어는 REST 아키텍쳐를 구현한 웹 서비스 또는 REST의 원리와 제약을 따르는 시스템을 지칭하는 용어로 정리할 수 있다.

  • APIApplication Programing Interface의 약자로써, 어떠한 응용프로그램에서 데이터를 주고 받기 위한 명세라고 정리할 수 있다.

    • API를 이용해서 어플리케이션에서 필요한 데이터를 요청하거나, 변경하거나 생성할 수 있다. 즉, API는 응용 프로그램에서 데이터를 요청하거나, 변경하거나, 생성하기 위한 인터페이스(명세)라고 이해하면 쉬울 것이다.

    • 어플리케이션에서 어떤 방식으로 정보를 요청할지, 정보를 변경하거나 생성할지에 대한 한 기능에 대한 규격이라고도 정리할 수 있다.

    • 우리는 어떠한 기능에 대한 내부 구현을 알 필요 없이 정리되어 있는 API 문서만 있다면 API 문서를 통해 해당 기능을 어떤식으로 사용할 수 있을지 활용할 수 있을지에 대한 판단을 내릴 수 있다.

  • REST라는 용어에 -ful이라는 형용사형 어미를 붙여 -한 API라는 표현이 사용된 용어가 RESTful API이다. 즉, REST의 기본 원칙을 성실히 지킨 서비스 디자인은 RESTful 하다라고 표현한 것이다.

  • 정리하면, RESTful API 또는 REST APIREST 아키텍쳐를 기반으로 서비스 API를 설계 및 디자인한 것을 의미한다.

REST란 무엇인가?

  • RESTful APIREST 아키텍쳐를 기반으로 설계된 API라는 것을 위에서 언급하였다. 그럼 위에서 언급한 REST가 무엇인지 알아보자.

  • REST 아키텍쳐의 정의는 다음과 같다.

      REST는 웹과 같은 분산 하이퍼 미디어 시스템에서 사용하는 통신 네트워크 아키텍쳐로, 
      네트워크 아키텍쳐의 원리 모음을 의미한다.
    
  • 단순히 정의만 보아서는 이해가 쉽게 안될 수 있다. 정의와는 별개로 내용을 풀어서 정리해보자.

  • 웹은 전송 방식으로 HTTP를 식별 방법으로 URI를 사용한다.

    • HTTP는 웹에서 GET, POST, PUT, DELETE 등의 메서드를 사용하여 정보를 주고 받는 프로토콜이다.
  • RESTHTTPURI의 단순하고 간결한 장점을 계승한 네트워크 아키텍쳐를 의미한다.

  • 따라서 다양한 요구사항에 대응하여 때로는 단순하게, 때로는 서버와 클라이언트가 서로 통신하는 리소스에 대해 복잡한 방식으로 상호 작용할 수 있다.

  • REST가 디자인 패턴이다. 아키텍쳐다 같은 많은 이야기가 존재하는데, 하나의 아키텍쳐로 볼 수 있다. 좀 더 정확한 표현으로 말하자면, RESTResource Oriented Architecture이다.

    • API 설계의 중심에 자원(Resource)이 있고 HTTP Method를 통해 자원을 처리하도록 설계하는 것이다.

RESTful 제약조건

  • 위에서 RESTful APIREST의 기본 원칙을 성실히 지킨 서비스 디자인이라고 설명하였다. 그럼 REST의 기본 원칙을 성실히 지킨다는 것은 무엇을 의미할까?

  • REST 아키텍쳐에는 제약조건이 존재한다. 이 제약 조건을 만족할 때 위에서 언급한 REST의 기본 원칙을 성실히 지켰다라고 얘기할 수 있다. REST의 특징이라고 할 수 있는 제약조건들에 대해 알아보자.

  • Client-Server Architecture

    • 이 제약조건의 기본 원칙은 괌심사의 명확한 분리다. 관심사의 명확한 분리가 선행되면 서버의 구성 요소가 단순화되고 확장성이 향상되어 여러 플랫폼을 지원할 수 있다.
  • Statelessness

    • 서버에 클라이언트의 상태 정보를 저장하지 않는 것을 말한다. 단순히 들어오는 요청만 처리하여 구현을 더 단순화한다.

    • 단, 클라이언트의 모든 요청은 서버가 요청을 이해하는 데 필요한 모든 정보를 담고 있어야 한다.

    • 서버는 작업을 위한 상태 정보를 따로 저장하고 관리하지 않는다. 세션 정보나 쿠키 정보를 별도로 저장하고 관리하지 않기 때문에 API 서버는 들어오는 요청만을 단순히 처리하면 된다.

      • 덕분에 서비스의 자유도는 높아지고 서버에서 불필요한 정보를 관리하지 않음으로써 구현이 단순해진다.
  • Cache Ability

    • 클라이언트의 응답을 캐시할 수 있어야 한다. HTTP의 장점을 그대로 계승한 아키텍쳐가 REST라고 얘기했다. 따라서, HTTP의 캐시 기능도 적용할 수 있다.
  • Layered System

    • 서버는 중개 서버(게이트 웨이, 프록시)나 로드 밸런싱, 공유 캐시 등의 기능을 사용하여 확장성 있는 시스템을 구성할 수 있다.
  • Code On Demand(Optional)

    • 클라이언트는 서버에서 자바 애플릿, 자바 스크립트 실행 코드를 전송받아 기능을 일시적으로 확장할 수 있다.

    • 이 제약 조건은 선택 가능하다. 즉, 필수 조건이 아니다.

  • Uniform Interface

    • URI로 지정된 리소스에 균일하고 통일된 인터페이스를 제공한다. 아키텍쳐를 단순하게 분리하여 독립적으로 만들 수 있다.

    • HTTP 표준만 맞는다면, 어떤 기술도 가능한 Interface 스타일을 나타낼 수 있다.

      • REST API 정의를 HTTP + JSON으로 하였다면 C, Java, Python 등 특정 언어나 기술에 종속받지 않고, 모든 플랫폼에 사용이 가능한 Loosely Coupling 구조를 가진다.
    • Uniform Interface은 다른 제약 사항과 달리 세부 원칙을 갖고 있다. Uniform Interface에는 세부 원칙으로 다음 4가지 프로퍼티가 존재한다.

      • Resource Identification In Requests

      • Resource Manipulation Through Representations

      • Self-Descriptive Messages

      • HATEOAS(Hypermedia As The Engine Of Application State)

    • Resource Identification In Requests

      • 요청에 의한 자원 식별은 웹 기반의 REST에서 자원 접근은 주로 URI를 사용한다는 것을 나타낸다.

      • 즉, 각각의 리소스는 요청에서 식별이 가능해야 한다는 내용을 담고 있다. 예를 들어 아래의 URI에서 정보는 product, 유일한 구분자는 1로 시벽할 수 있다.

      http://localhost:8080/product/1
    
    • Resource Manipulation Through Representations

      • 표현을 통한 자원 조작에 대해 알아보자.

      • 클라이언트가 특정 메세지나 메타 데이터를 갖고 있으면 자원을 수정, 삭제하는 충분한 정보를 갖고 있는 것으로 볼 수 있다.

      • 예를 들어 코드에서 content-type은 리소스가 어떤 형식인지 지정한다. 리소스는 HTML, XML, JSON등 다양한 포맷으로 전송된다. 다음 예제에선 포맷을 JSON으로 지정했다.

      http://localhost:8080/product/1
      content-type: aplication/json
    
    • Self-Descriptive Messages

      • 각 메세지는 자신을 어떻게 처리해야 하는지 충분히 정보를 포함해야 한다.

      • 즉, API 메세지만 보고, API를 이해할 수 있는 구조를 갖춰야 한다는 것을 의미한다.

        • Resource, Method를 이용해 무슨 행위를 하는지 직관적으로 이해할 수 있어야 한다.
      • 웹 기반 REST에서는 HTTP MethodHeader를 활용한다. 다음 예제에서는 GET 메서드를 활용하여 /product/1의 정보를 조회해 온다는 것을 표현했다.

      GET http://localhost:8080/product/1
      content-type: aplication/json
    
    • HATEOAS(Hypermedia As The Engine Of Application State)

      • 클라이언트에 응답할 때 단순히 결과 데이터만 제공해주기 보다는 URI를 함께 제공해야 한다는 원칙이다.

      • 어플리케이션의 상태는 다른 하이퍼링크를 통해 전이되어야 한다는 원칙으로 서버는 현재 이용 가능한 다른 작업에 대한 하이퍼링크를 포함해서 응답해야 한다.

      • 다음 예제의 JSON에서 _links 프로퍼티가 HATEOAS 원칙의 역할을 수행하고 있음을 알 수 있다.

      {
          "projectIdx": 204,
          "leader": "개설자",
          "leaderIdx": 45,
              "profileImage": "https://deploy.donghun.dev:8083/api/image/USER_DEFAULT_PROFILE_IMG.png",
          "title": "해커톤 팀원 구하기 서비스",
          "summary": "해커톤 팀원을 구하는 웹서비스 만들 팀원 구합니다.",
          "location": "부산",
          "createdDate": "2019-09-30T14:11:05",
          "status": "진행중",
          "_links": {
              "self": {
                  "href": "https://deploy.donghun.dev:8083/api/project/204"
              },
              "Leader Profile": {
                  "href": "https://deploy.donghun.dev:8083/api/profile/45"
              }
          }
      }
    

REST API의 구성 요소

  • 위에서 REST가 무엇인지, REST의 제약조건이 무엇인지을 간단하게 알아보았다. 이번에는 REST API를 구성하기 위한 요소에 대해서 알아보자.

  • REST API는 다음과 같이 구성을 해야 한다.

    • 자원(Resource) : URI

    • 행위(Verb) : HTTP 메소드

    • 표현(Respresentations) : 리소스에 대한 표현 (HTTP Message Body)

  • Reosurce

    • 자원을 식별하고 표현하기 위해서는 http://myweb/boards와 같은 URI를 사용해야 한다.

    • URI는 명사를 사용해야 하며, 가급적 동사를 피해야 한다.

      • 동사를 표현할 때는 HTTP 메서드인 GET, POST, PUT, DELETE 등으로 대체해서 사용해야 한다.

      • 물론 모든 경우에 동사를 HTTP 메서드로 대체할 수는 없다.

      • 어디까지나 불필요한 동사를 URI에 포함하는 것을 지양해야 한다는 것이다. 어쩔 수 없는 경우에는 동사가 URI에 포함되어야 할 경우도 있다.

    • URI에서 명사를 사용할 때 단수형 보다는 복수형을 사용하는 것이 좋다.

      • /board도 명사로써 사용 가능하지만 복수형인 /boards로 표현하면 컬렉션으로 명확하게 표현할 수 있어서 확장성 측면에서 더 좋다.
  • Verb - HTTP Method

    • 행위는 HTTP 메서드를 통해서 표현할 수 있다. 위에서 언급했듯이 HTTP 메서드를 통해 동사 부분을 표현할 수 있는데, HTTP 메서드를 통해서 boards의 동사 부분을 표현해보면 다음과 같다.

      • Idempotent : 한 번 수행하나, 여러 번 수행했을 때 결과가 같은지에 대한 여부.
Method 의미 API Note Idempotent
POST Create /boards board 추가 생성. NO
GET Select /boards board 목록 조회. YES
PUT Update /boards/1 ID가 1인 board 수정. YES
DELETE Delete /boards/1 ID가 1인 board 삭제. YES
  • Respresentations

    • 리소스에 대한 표현은 HTTP Message Body를 통해서 리소스를 메세지로 표현할 수 있다.

    • 메세지를 표현할 때 다양한 포맷들이 존재 하는데, 대체로 JSON, XML등의 포맷이 존재한다.

    • 이들 중 어떠한 포맷을 사용해도 상관이 없으나, 최근에는 JSON을 주로 사용하고 있다.

      HTTP POST, http://myweb/boards/
      {
          "boards" : {
              "title" : "test-board-1"
          }
      }
    

RESTful하게 API를 디자인 했을 때의 장단점은 무엇인가?

  • 앞에서는 REST가 무엇이고, REST API는 어떻게 구성되는지를 살펴보았다. 이번에는 앞에 내용을 정리하는 차원에서 APIRESTful하게 디자인 했을 때의 장단점이 무엇인지 알아보자.

  • RESTful하게 API를 디자인했을 때 다음과 같은 이점이 있다.

    • APIOpen API로 제공하기가 쉽다.

    • 멀티 플랫폼 지원 및 연동이 용이하다.

    • 원하는 타입으로 데이터를 주고 받을 수 있다.

    • 기존의 웹 인프라(HTTP 기반의 웹)를 그대로 사용할 수 있다.

  • 하지만 RESTful하게 디자인된 API가 이점만 존재하는 것이 아니다. 다음과 같은 단점도 가지고 있다.

    • 사용할 수 있는 HTTP 메서드가 4가지 밖에 되지 않는다.

    • 분산 환경에는 부적합하다.

    • HTTP 통신 모델에 대해서만 지원한다.

마치며

이번 포스팅에서는 REST API에 대해서 알아보았다. REST API는 현재 가장 많이 쓰이고 있는 API 설계 방식이며 그 근간이 되는 REST 아키텍쳐에 대한 내용도 방대하기 때문에 쉽사리 헷갈리기도 하고 이해하기 쉽지 않은 부분도 꽤 있는 내용이다. 본인도 이 부분에 대해서 완벽하게 이해했다고 자신할 수 없기 때문에 그 동안 공부를 통해 알고 있던 내용을 정리하는 차원에서 포스팅을 작성하게 되었다.

개인적으로 RESTRESTful API에 조금 더 제대로 이해하고 싶다면 그런 REST API로 괜찮은가를 추천한다. 사실 알만한 분들은 아시겠지만 굉장히 유명한 발표 영상이다. 본인도 이 영상을 통해서 처음에 REST API에 대해서 이해하기 시작했었기에 처음에 개념을 잡고 이해하는데 꽤 도움이 될 것이라 생각한다. 이번 포스팅은 여기서 마무리하고 다음에 또 새로운 포스팅을 작성해보도록 하겠다.

Reference