- Increase는 API 리소스가 사용자의 제품 이해를 좌우한다고 보고, 결제 네트워크의 복잡성을 숨기기보다 드러내는 No Abstractions 원칙을 채택함
- Stripe식 추상화는 빠른 통합에 강하지만, Increase 사용자는 payment network 지식을 바탕으로 직접 연결과 깊은 통합을 원함
- API는 Nacha specification 같은 기저 네트워크 용어를 그대로 쓰고, ACH transfer의 진행 과정을 불변 하위 객체로 모델링함
- 사용자가 할 수 있는 액션이 크게 다르면
ach_transfer와inbound_ach_transfer처럼 리소스를 분리해 처음에는 장황해도 장기적으로 예측 가능성을 높임 - 추상화 수준은 통합 개발자의 도메인 경험과 투입 의지에 맞춰 정해야 하며, 낮은 추상화를 택했다면 이후에도 그 원칙을 유지해야 함
API 리소스는 사용자의 멘탈 모델을 만든다
- API resource는 API의 명사이며, 이름과 모델을 정하는 일은 API 설계에서 가장 어렵고 중요한 부분에 속함
- 어떤 리소스를 노출하느냐가 사용자가 제품의 동작 방식과 가능한 작업을 이해하는 멘탈 모델을 구성함
- Increase는 이 판단을 돕기 위해 “No Abstractions”라는 설계 원칙을 사용함
-
Stripe식 추상화와 Increase의 차이
- Stripe는 복잡한 결제 도메인을 사용자가 쉽게 다룰 수 있는 API로 추출하는 추상화에 강점이 있음
- 여러 결제 네트워크를
PaymentIntent라는 API resource로 모델링하고, Visa와 Mastercard의 chargeback reason code 차이를 하나의 enum으로 합쳐 사용자가 두 네트워크를 따로 고려하지 않아도 되게 함 - Stripe 사용자 상당수는 결제 자체가 아닌 제품을 만드는 초기 스타트업이며, 신용카드 세부 사항을 깊이 알기보다 빠르게 통합한 뒤 본래 제품 개발로 돌아가려 함
- Increase 사용자는 payment network에 대한 기존 지식이 깊고, 금융 기술을 계속 다루며, 직접 네트워크 연결과 깊은 통합을 위해 Increase를 사용함
- 이들은 FedACH window가 언제 닫히고 transfer가 언제 도착하는지 정확히 알고 싶어 하며, ACH transfer의 Standard Entry Class code가 달라지면 return timing도 달라질 수 있음을 이해함
- ACH transfer와 wire transfer를 하나의 API resource로 묶어 기저 네트워크 복잡성을 숨기면, Increase 사용자에게는 단순화가 아니라 불편함이 됨
No Abstractions가 API에 드러나는 방식
-
실제 네트워크 용어 사용
- Increase는 API resource와 attribute 이름을 새로 만들기보다 기저 네트워크의 어휘를 사용하는 편임
- ACH transfer를 API로 만들 때 노출하는 parameter는 Nacha specification의 field 이름을 따름
-
불변 리소스와 lifecycle object
- 리소스도 실제 세계의 이벤트나 메시지에 맞춰 모델링하며, 이 접근은 더 많은 API resource를 불변으로 만들게 됨
- ACH transfer lifecycle에서 보낼 수 있는 네트워크 메시지들의 묶음처럼, 불변 리소스들을 state machine 형태의 lifecycle object 아래에 그룹화함
ach_transferobject는 시간이 지나며 바뀌는statusfield와, lifecycle 진행에 따라 생성되는 여러 불변 sub-object를 가짐- 새
ach_transfer는status가pending_approval이고approval,submission,acknowledgement가null일 수 있음 - FedACH에 제출된 뒤에는
status가submitted가 되며,approval,submission,acknowledgement가 각각 승인·제출·확인 시점의 불변 정보로 채워짐 submission에는trace_number와submitted_at같은 값이 포함됨
-
사용 사례별 리소스 분리
- 같은 API resource라도 instance별로 가능한 액션 집합이 크게 다르면 Increase는 이를 여러 리소스로 나누는 편임
- originated ACH transfer와 received ACH transfer에서 가능한 액션은 사실상 정반대라서,
ach_transfer와inbound_ach_transfer로 분리함 - 이 방식은 API 문서 왼쪽에 많은 리소스가 보일 만큼 처음에는 더 장황하고 위압적으로 보일 수 있음
- 대신 장기적으로는 리소스와 액션의 관계가 더 예측 가능해짐
원칙은 작은 설계 결정을 줄인다
- 복잡한 API를 여러 해에 걸쳐 설계하다 보면 작은 결정이 계속 발생하며, 초기에 세운 기반 원칙이 이런 결정의 인지 부하를 줄임
- wire transfer를 Federal Reserve로 보낼 때 필요한
Input Message Accountability Data는 해당 transfer의 전역 고유 ID 역할을 함 - 추상화가 많은 API라면 엔지니어가 이를 더 “사용자 친화적”으로
trace_number,reference_number,id중 무엇이라 부를지 고민할 수 있음 - Increase에서는 field 이름을
input_message_accountability_data로 정하고 넘어감 - 사용자가 이 field를 처음 볼 때 즉시 알아보기 쉬운 이름은 아닐 수 있지만, 기저 시스템과 어떻게 매핑되는지 바로 이해하는 데 도움이 됨
추상화 수준을 정할 때의 기준
- No Abstractions는 모든 API에 맞는 원칙이 아님
- 적절한 추상화 수준은 통합 개발자의 도메인 경험, 제품 영역에 대한 이해, 통합에 투입할 에너지에 따라 달라짐
- 추상화가 많은 API를 만들면 새 기능을 추가하기 전에 깊이 고민해야 함
- 추상화가 적은 API를 만들면 그 방향에 커밋하고, 추상화를 추가하려는 유혹을 견뎌야 함