- APIリソースの命名やモデリングの決定は、API設計で最も難しく重要な部分である。リソースは、ユーザーが製品の動作や機能をどう捉えるかというメンタルモデルを形作る。
- Increaseチームは、API設計を支えるために「抽象化なし」という原則を使っている。
StripeのAPI設計アプローチ
- Stripeチームのかなりの人数は以前Stripeで働いており、Stripeの成功したAPI設計の価値観を重視している。
- Stripeは、複雑なドメインの中核機能を、ユーザーが簡単に理解して使える抽象化として取り出すことに優れている。(例: VisaとMastercardの違いを抽象化したPaymentIntent)
- Stripeのユーザーの大半は、決済とは無関係の製品を開発する初期段階のスタートアップであり、クレジットカードの細かな仕組みを知る必要がない。彼らはStripeを素早く統合し、製品開発に集中したいと考えている。
IncreaseのユーザーとAPI設計原則
- 一方でIncreaseのユーザーは決済ネットワークに関する深い知識を持っており、Increaseを選ぶ理由も、ネットワークへの直接接続と統合の深さにある。
- 彼らはFedACHの窓口がいつ閉まるのか、送金がいつ行われるのかを正確に知りたがっており、ACH送金では異なるSECコードの設定が返却タイミングに影響し得ることも理解している。
- こうしたネットワークの根本的な複雑さを隠そうとする試みは、ユーザーの生活を単純化するどころか、ただ苛立たせるだけである。
- 初期ユーザーとの対話を通じて、「抽象化なし」という原則を導き出し、API設計に適用した。
「抽象化なし」原則がAPI設計に与えた影響
- 実際に使われている用語を使う: APIリソースや属性に独自の名前を作るのではなく、基盤となるネットワークの語彙を使う。(例: ACH送金パラメータにはNacha仕様のフィールド名を使う)
- 不変性: 実際のイベントをモデルとして使うことで、より多くのAPIリソースを不変にしている。不変リソースのクラスターを、状態機械の「ライフサイクルオブジェクト」としてグループ化するのが効果的である。(例: ach_transferオブジェクトの
statusフィールドと、送金ライフサイクルに応じて生成されるいくつかの不変な子オブジェクト)
- ユースケース別のリソース分離: リソースインスタンスによってユーザーが取れる操作の集合が大きく異なる場合、複数のリソースに分割する。(例: 送信ACH送金と受信ACH送金は別々のリソースに分ける)
エンジニアリングチームによるアプローチの順守
- エンジニアリングチームは、このアプローチを守ることを約束している。
- 複雑なAPIを何年にもわたって設計する際には、常に小さな増分的判断を下し続ける必要があるが、あらかじめ基本原則を守ると決めておけば、そうした判断にかかる認知負荷を減らせる。
- 例えば、連邦準備制度へ送金する際に必要なInput Message Accountability Dataフィールドについて、抽象化の多いAPIであればこのフィールドにどう「ユーザーフレンドリー」な名前を付けるか悩むことになるが、Increaseではエンジニアがフィールド名を
input_message_accountability_dataにしてそのまま進められる。
GN⁺の意見
- APIの抽象化レベルは、その製品ドメインに対する開発者の経験レベルや、統合に投入できるエネルギーによって変わり得る。したがってAPIを設計する際には、統合する開発者にとって適切な抽象化レベルを考えることが重要である。
- 抽象化レベルの高いAPIを構築するなら、新機能を追加する前に慎重に考える必要がある。反対に、抽象化レベルの低いAPIを構築するなら、その方針を守り、抽象化を加えたくなる誘惑に抵抗しなければならない。
- 基盤となるネットワークやプロトコルの用語をそのまま使うことは、開発者がunderlying systemを理解する助けになる一方で、初めて触れる開発者にとっては参入障壁にもなり得る。したがって、注釈やドキュメントをしっかり整備することが重要だと思われる。
- API設計でimmutableオブジェクトを活用することは、データの整合性維持やside-effect防止に効果的であり得る。ただし、逆にデータ更新が必要な場合には不便になることもあるため、trade-offを十分に考慮する必要がある。
- ユースケースごとにリソースを分離することはAPIの複雑さを高める可能性があるが、長期的には予測可能性を高められる。ただし、細分化しすぎると使い勝手が落ちる可能性もあるため、適切な水準を見極めることが重要である.
1件のコメント
Hacker Newsのコメント
低レベルの抽象化を適用したAPIと高レベルの抽象化を適用したAPIの両方を提供するのがよい
Increaseが別のアプローチを選んだ理由を説明している部分が気に入った
Stripeの本当の能力は、顧客を理解し、顧客が望むシンプルさを提供することにある
Domain-Driven Designの「ユビキタス言語(Ubiquitous Language)」という設計パターンに似ている。これは、ドメイン専門家が使う実際の用語と同じ用語を実装でも使うというもの
ドメイン専門家が理解できる言語を使うべき
POSIXのような抽象化がなければ、アプリケーションはサポートするすべてのファイルシステム向けにアダプターを書かなければならない
外部で管理される仕様に基づいて、API構造の一部が1:1で構築されているという
支払いAPIでうまくモデル化しにくいものの1つは、支払いスキームが支払いの返金時に支払人と受取人の役割を異なる形で表現することだ