좋은 API란?
API는 application programming "interface"의 약자로, 응용 프로그램에서 사용할 수 있도록, 운영체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.
이번 미션에선 HTTP API, JAVA API 정도를 사용했다. HTTP API를 이용해 웹브라우저(응용프로그램)와 저희 서버 간에 데이터를 주고받을 수 있었다. JAVA API를 이용해서 저희의 자바애플리케이션을 쉽게 구현할 수 있었다.
API도 결국엔 인터페이스이기에 API가 왜 만들어졌고 왜 쓰는지를 고민해보는건 인터페이스를 만들고 쓰는 이유를 고민해보는것과 비슷한 맥락으로 바라볼 수 있다고 생각한다. 우리는 인터페이스를 만듦으로써 구현과 사용을 분리하고 기능을 추상화하여 사용을 쉽게 만들 수 있었다. 마찬가지로 우리는 API를 만들고 사용함으로써 서로 다른 프로그램 간 추상화된 기능을 쉽게 사용하게 만들 수 있다.
결국 레벨 1에서 배웠던 좋은 코드를 짜는 법이 좋은 API를 만드는 법에도 적용된다. 의도가 분명하고 적절한 역할과 책임을 가지는 객체들에서 객체 대신 API를 대입해보면 된다.
REST API란?
REST API에 대해선 워낙 잘 정리해둔 글들이 많아서 크게 논할 건 없고, 앞서 언급한 HTTP API에 여러 가지 제약 조건이 추가된 친구 정도라고 말하고 싶다. 제약 조건을 완벽히 지키기엔 실질적으로 어렵기에, 디자인 가이드를 어느 정도 따라갔다면 보통 REST API라 부른다. REST API 디자인 가이드론 자원의 식별, 메시지를 통한 리소스의 조작, 자기서술적 메시지, 애플리케이션의 상태에 대한 엔진으로서의 하이퍼미디어 가 있다.
“중첩 리소스에 대한 REST API 디자인 가이드”와 “좋은 API”
위에 언급한 디자인 가이드 중 자원의 식별에 초점을 맞춰 글을 서술하겠다. 우테코 미션인 방탈출 예약 프로그램을 구현하던 중, 예약 가능한 시간이라는 자원을 API에서 어떻게 표현할지 고민이 됐다. 현재 서버의 자원을 간략히 소개하자면 예약 과 예약 시간이란 자원이 존재하고, 예약이 예약 시간을 사용하는 구조였다.
class Reservation { Long id; LocalDate date; Time time; }
class Time { Long id; LocalTime startAt; }
Java
복사
위 구조에서 나올 수 있는 시나리오는 아래와 같았다.
1.
관리자가 10시 타임과 11시 타임을 생성한다 (Time)
2.
유저가 5월 15일 10시 타임에 예약을 잡는다 (Reservation)
3.
현재 5월 15일자에 예약이 가능한 타임은 11시만 남았다 (Time)
이때 필요한 API 목록은 아래와 같았다.
•
예약 시간 생성 → POST /times vs POST /reservations/times
•
예약 생성 → POST /reservations
•
예약 가능한 시간 목록 조회 → GET /times/available vs GET /reservable-times vs GET reservations/times/available
자원 별로 endpoint를 구성해봤을 때 예약은 쉽게 구성가능하지만, 예약 시간의 경우 여러 후보가 나왔다. 그 이유는 예약 시간이 중첩 리소스로 판단 가능한 여지가 있었기 때문이다.
이에 대해 내 나름대로 결론을 내려봤다. 물론 정답은 없고 지극히 개인적인 내 취향이다.
1.
예약 시간이 예약과 항상 함께 움직인다면, /reservations/times 로 표현할 것이다. 이를 통해 시간이 예약에 종속적임을 나타내며, 특정 예약에 대한 시간 정보를 조회하거나 수정할 때 사용할 수 있을 것이다.
2.
예약 시간이 예약과 독립적으로 움직일 수 있다면, /times 를 단독으로 사용할 것이다. 이를 통해 특정 시간에 대한 정보를 조회하거나 수정할 때 사용할 수 있을 것이다.
중첩 리소스 관점에서 바라봤을 때 현재는 2번 상황이라 생각했다. 따라서 예약 가능한 시간 목록 조회 api를 /times/available 과 같이 표현하는 방식을 택했다.
더 나아가서 내 개인적인 생각엔 애초에 /times보단 /reservation-times가 더 적절하지 않을까 싶다. 단순한 시간이 아닌 예약 시간이기 때문이다. 예약 시간이란 자원이 예약이 가능/불가능하다란 특성을 가진다고 바라보아 아래와 같이 짜는 게 최선일 거 같다.
•
특정 예약의 시간 조회 → /reservations/{id}/times
•
예약 시간 목록 조회 -> /reservation-times
•
예약 가능한 시간 목록 조회 -> /reservation-times/available (예약시간이란 자원이 예약 가능/불가능 특성을 가짐)
이를 다른 케이스로도 확장해본다면 아래와 같은 예시를 들어볼 수 있다.
•
특정 사용자의 프로필을 조회 -> /users/{id}/profile
•
프로필 목록 조회 -> /profile
•
공개 프로필 목록 조회 -> /profile/public (프로필이란 자원이 공개/비공개 특성을 가짐)