HTTP API의 설계

API

먼저 API가 무엇인지에 대해서부터 간단하게 짚어보자. API(Application Programming Interface)는 간단하게 말하자면 애플리케이션 간의 통신을 담당하는 인터페이스이다. 프로그램의 MSA 구조, 객체지향 등 모듈화된 소프트웨어들이 자주 쓰이게 되면서 각 서비스 간의 통신이 중요해졌는데 이를 담당하는 것이 API이다.
API는 클라이언트를 포함한 서비스와 서비스 사이에서 응답과 호출을 관리하는 역할을 한다. 이를 통해 소프트웨어 간의 데이터 교환, 기능 실행 등이 가능해진다.
예를 들어 클라이언트가 응용 프로그램에서 A라는 데이터를 요청했다고 가정해보자. 이 때 API는 요청을 받고 해당 사용자가 필요한 인증키가 있는지 등을 확인한 후 데이터베이스에서 A 데이터를 찾아서 응답해준다.
이러한 API의 장점은 모든 접속을 표준화 한다는 것이다. 디바이스, 운영체제에 관계 없이 모두가 동일한 액세스를 하게 된다. 또한 미리 만들어 놓은 API로 타 서비스에서도 인증, 보안처리 등의 절차를 생략할 수 있고, 타 사에 API를 제공함으로써 기업의 서비스 생태계를 확장시키고 데이터와 수익을 얻을 수 있는 등 많은 장점돌이 있다.

HTTP API의 설계

그렇다면 이러한 API를 간단하게 설계해보자. HTTP를 사용하는 회원 정보 관리 API를 만들어 볼 것이다. 회원 정보 관리에는 이러한 기능들이 필요하다.

  1. 회원 목록 조회
  2. 회원 조회
  3. 회원 등록
  4. 회원 수정
  5. 회원 삭제
    해당 기능들에 대응하는 직관적인 이름의 URI를 설계하면, URI를 전부 따로따로 5개를 만들어야 한다. 예를 들면 /read-member-list, /read-member-by-id와 같다.
    URI 설계에서 중요한 것은 리소스를 파악하는 것이다. 위의 행동들은 모두 ‘회원’이라는 리소스를 대상으로 이루어지는 것을 알 수 있다. 따라서 우리는 ‘회원’ 리소스를 URI에 맵핑하여 ‘회원 목록 조회’는 ‘/members’, 이외 나머지 행동들은 ‘/members/{id}’ 와 같이 설계할 수 있다. HTTP에서 행위는 HTTP method로, 리소스는 URI로 표현하기에 이렇게 하나로 통일할 수 있는 것이다.

HTTP method

그렇다면 HTTP method의 종류엔 어떤 것이 있는지 알아보자. HTTP method의 주요한 메서드들은 다음과 같다.

  1. GET
  2. POST
  3. PUT
  4. PATCH
  5. DELETE

GET

GET은 리소스의 조회에 사용된다. 위의 회원 조회를 GET을 통해 실행해보자.
먼저 이전 포스팅에서 배웠던 것과 같이 start-line에 ‘GET memeber/100 HTTP/1.1’ 과 같이 요청 메세지를 작성하여 서버에 전달한다. 그것을 받은 서버는 메세지를 해석하여 DB에서 member/100을 조회하여 JSON 메시지를 만든다. 이후 status-line에 ‘200 OK’, header에 콘텐츠 정보 등을 입력하고 메시지 바디에 JSON을 담아 다시 클라이언트로 보내게 된다.

POST

POST는 요청 데이터의 처리, 그 중에서도 등록에 자주 사용된다. POST를 이용하여 회원 정보 등록을 진행해보자.
위에서 했던것과 같이 start-line에 ‘POST /members HTTP/1.1’을 작성하고 메시지 바디에 유저 데이터를 담아 서버에 전송한다. 이 때 /member에 대한 POST는 데이터의 저장이라는 점이 서버와 약속되어있어야 한다.
해당 메세지를 받은 서버는 DB에 데이터를 등록하고 새로운 리소스 식별자, 예를 들면 100을 생성한다. 그리고 서버는 status-line에 ‘201 Created’ header에 생성된 리소스의 URI정보, 메세지 바디에 등록된 리소스를 저장하여 응답 메세지를 보낸다.
POST는 위와 같은 데이터의 등록에 주로 사용되지만, 서버와의 약속에 따라 데이터의 등록, 수정 뿐 아니라 프로세스의 처리까지도 가능하다. 이 때 리소스만으로 URI를 설계하는 것이 불가능하다면 불가피하게 URI에 동사를 넣어(ex : ‘start-delivery’) 컨트롤 URI를 설계하여 프로세스를 처리한다.

PUT

PUT은 리소스의 대체에 사용된다. 리소스가 있다면 덮어써 대체하고, 없다면 새로 생성한다. POST와 기능이 비슷하지만 POST는 클라이언트가 리소스의 위치를 지정하지 않고, PUT은 클라이언트가 리소스의 위치까지 URI로 지정한다는 차이가 있다.
HTTP 메시지를 보내는 과정은 충분히 서술하였으니 생략하고, PUT은 리소스를 대체할 때 해당 리소스를 완전히 덮어써 대체한다. username, age가 있는 데이터를 age만 입력하여 대체하면 username을 삭제하고 age만 있는 데이터로 대체된다.

PATCH

리소스의 부분 변경에 사용된다. 위의 PUT과 달리 username, age가 있는 데이터를 지정하여 age만 있는 데이터를 메시지 바디에 담아 보내면, 리소스의 부분 변경이기 때문에 해당 데이터의 age 파트만 해당 데이터로 변경된다.

DELETE

리소스의 제거에 사용된다. 리소스의 URI를 식별자까지 담아 서버에 보내면, 해당 리소스를 삭제해준다.

HTTP method의 속성

HTTP method들은 몇 가지 중요한 속성의 유무로 사용처를 구별할 수 있다.

안전(Safe)

안전은 호출해도 리소스를 변경하지 않음을 의미한다. 안전한 메서드로는 GET, HEAD가 있고, 안전하지 않은 메서드로는 POST, PUT, PATCH, DELETE가 있다.

멱등(Idempotent)

처음 들어보는 단어인데, 멱등은 여러 번 호출하더라도 결과가 같음을 의미한다.
멱등한 메서드로는 GET,PUT,DELETE가 있는데, GET은 해당 리소스를 조회하는 것이므로 몇 번을 호출하더라도 같은 결과가 나온다. PUT은 리소스를 대체하므로 첫 번째의 호출에 리소스가 대체되고 이후 호출엔 모두 같은 결과가 나온다. DELETE는 리소스를 삭제하므로 첫 호출에 리소스를 삭제하고 이후 호출에도 삭제된 결과는 같다.
멱등하지 않은 메서드로는 POST가 있는데, 매 호출마다 새로 식별자를 붙여 리소스를 생성하기 때문에 결과가 모두 다르다.
이러한 멱등은 TIMEOUT 되거나 중간에 오류가 발생하였을 때 해당 메서드를 다시 실행해도 되는지에 대한 판단 근거가 된다.

캐시가능(Cacheable)

응답의 결과인 리소스를 캐시할 수 있다는 의미이다. 이미지와 같은 큰 리소스의 경우엔 로컬 pc에 캐시하면 다시 서버에 요청하지 않아도 되므로 자원을 절약할 수 있다. 캐시 가능한 메서드로는 GET, HEAD, POST, PATCH가 있다. 주로 GET, HEAD정도만 캐시로 사용하는데 일단 첫째로 URL을 키로 사용하면 캐시하기가 쉽고, 둘째로 캐시를 사용할 때엔 원본 데이터를 유지하는 것이 중요한데, POST, PATCH 등은 원본 데이터를 변경할 가능성이 있기 때문이다.

번외) REST API

REST(Representational State Transfer), RESTful API란 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 것을 뜻한다. 위에서 배운 HTTP URI를 통해 자원을 정의하고, HTTP method를 통해 해당 자원에 대한 CRUD를 실행한다. CRUD는 Create, Read, Update, Delete의 약자이다.
REST란 기본적으로 HTTP의 사용에 대한 가이드라인, 제약조건 정도로 생각하면 된다. 제작자부터가 HTTP의 설계의 우수성에 비해 제대로 사용되지 않아서 REST 아키텍쳐를 발표했다.
위에서 공부한 것과 별개로 REST API에 대해 알아봤는데, 위의 내용이 벌써 처음부터 REST를 염두에 두고 설계한 내용이었다. 커리큘럼이 좋다는 증거일까?
REST의 특징은 다음과 같다.

  • Uniform : URI로 지정한 리소스에 대한 조작이 통일되고, 한정적인 인터페이스로 수행되어야 한다는 뜻이다.
  • Stateless : 이전에 배웠듯 서버에서 상태를 저장하지 않는다는 뜻이다.
  • Cacheable : 위에서 배운 것이다. HTTP가 가진 캐싱 기능이 사용가능하다는 뜻이다.
  • Self-descriptiveness : JSON 포맷 등을 이용하여 메시지만 보고 직관적으로 역할을 이해할 수 있다는 뜻이다.
  • Client-Server : 서버는 API의 제공, 클라이언트는 인증과 Context 등을 관리함으로써 각각의 역할을 구분하고 서로에 대한 의존성이 감소한다.
  • Layered System : REST 서버는 다중 계층으로 구성되어 보안, 로드 밸런싱 등을 추가해 구성상의 유연성을 둘 수 있고, 중간에 프록시 서버, 게이트웨이 등의 중간 매체를 활용할 수 있어 자유도가 높다.
    이러한 REST API의 설계는 URI를 통한 자원의 표시, HTTP method를 통한 CRUD를 중심으로 이루어 지는데 위에서 배웠던 것들이 모두 사실은 REST API의 설계였다.

지금까지 HTTP API와 여러 부가 정보에 대해 알아보았다. 다음 포스팅에선 클라이언트와 서버간의 데이터 전송에 대해 알아보겠다.