RESTful API データモデリング

RESTful APIでビジネス操作を表現するデータモデリング:アクションとイベントの設計

Tags: RESTful API, データモデリング, API設計, ビジネスロジック, アクション

はじめに:なぜビジネス操作のモデリングが重要なのか

RESTful APIの基本的な考え方は「リソース指向」です。URIでリソースを特定し、HTTPメソッド(GET, POST, PUT, PATCH, DELETE)でリソースに対する標準的な操作(CRUD: Create, Read, Update, Delete)を行うというシンプルなモデルは、多くの場面で有効です。

しかし、現実のビジネスシステムでは、単なるリソースのCRUD操作だけでは表現しきれない複雑な「操作」や「イベント」が多く存在します。例えば、「注文をキャンセルする」「記事を公開する」「ユーザーを承認する」「メールを送信する」といった操作は、特定のリソース(注文、記事、ユーザーなど)の状態変化を伴いますが、その操作自体が単なるPUTやPATCHでは表現しきれない場合や、複数のリソースに影響を及ぼす場合があります。

こうしたビジネス固有の複雑な操作をAPIとしてどのように設計するかは、多くのエンジニアが直面する課題です。特に、リソース指向の原則を守りつつ、APIの表現力、保守性、使いやすさを両立させるためには、操作そのものに対するデータモデリングの考え方が不可欠になります。

本記事では、RESTful APIにおいて、CRUDの枠を超えたビジネス操作やイベントをどのようにデータモデリングし、APIとして設計するかについて解説します。

CRUDだけでは表現しきれない操作とは?

RESTful APIは、システムをリソースの集合として捉え、各リソースに対して標準的な操作を適用するという強力なパラダイムを提供します。しかし、以下のようなケースでは、単にリソースの状態をPUTやPATCHで更新するだけでは不十分な場合があります。

これらの操作は、単にリソースの属性値を変更するのではなく、システム全体の状態に影響を与えたり、特定のビジネスイベントをトリガーしたりする性質を持っています。

操作をRESTful APIでモデリングするアプローチ

これらのCRUDでは表現しにくいビジネス操作を、RESTfulの原則に則ってAPIとして表現するにはいくつかのアプローチがあります。重要なのは、これらの操作をシステム内の「何か」に対する「作用」として捉え、それをAPIリソースやエンドポイント設計に反映させることです。

主なアプローチとしては、以下のパターンが考えられます。

  1. 操作をリソースのサブリソースとして表現する: 特定の親リソースに対して行われる操作を、そのリソースのサブリソースとして表現するパターンです。操作の種類ごとにURIを設計し、通常はPOSTメソッドを使用します。

    • 例:注文キャンセル操作 POST /orders/{orderId}/cancel
    • 例:記事公開操作 POST /articles/{articleId}/publish
    • 例:ユーザー承認操作 POST /users/{userId}/approve

    このアプローチのメリットは、操作の対象となるリソースが明確であること、URIの構造が直感的になりやすいことです。デメリットとしては、操作の種類が増えるとURIが長くなりがちであること、リソースに対する操作というよりは、操作そのものをリソースとして捉える(コントローラーリソースの考え方)に近い側面があることです。

  2. 操作を独立した「コマンド」や「アクション」リソースとして表現する(コントローラーリソース): 特定の種類の操作を集約するコントローラーリソースを設け、そのリソースに対してPOSTメソッドで操作の詳細をリクエストボディとして送信するパターンです。リソース指向の厳密な解釈からは外れるとする向きもありますが、特定のビジネス操作を表現する際には非常に実用的です。

    • 例:汎用的な操作エンドポイント POST /actions (リクエストボディで操作の種類とパラメータを指定)
    • 例:特定の操作タイプに特化したエンドポイント POST /commands/order-cancel POST /commands/article-publish

    このアプローチのメリットは、URIの構造が比較的シンプルになる可能性があること、多様な操作を柔軟に扱えることです。デメリットとしては、URIだけでは操作対象が分かりにくい場合がある(リクエストボディを見る必要がある)、汎用的な POST /actions のような設計はAPIの discoverability を損ないやすいこと、APIドキュメントが重要になることです。一般的には、POST /commands/{action-type} のように、ある程度操作の種類でエンドポイントを分ける方が分かりやすくなります。

  3. リソースのPUT/PATCHによる状態変更として表現する: 操作の結果としてリソースの状態が変化する場合、その状態をリソースの属性として持ち、PUTまたはPATCHでその属性を更新することで操作を表現するアプローチです。

    • 例:注文ステータス変更 PATCH /orders/{orderId} (リクエストボディ: { "status": "cancelled" })
    • 例:記事ステータス変更 PATCH /articles/{articleId} (リクエストボディ: { "status": "published" })

    このアプローチは、操作がリソースの特定の属性への単純な状態遷移である場合に最もRESTfulな方法と言えます。しかし、状態遷移の裏側に複雑なビジネスロジックがある場合(例: "cancelled" にする際に在庫を戻す、返金処理を行うなど)、クライアントはその裏側の副作用を知らずにリクエストすることになり、APIの意図が不明確になる可能性があります。また、同じステータスでも異なるビジネスロジックが実行される場合(例: 管理者によるキャンセルとユーザー自身によるキャンセル)、この方法では区別が難しくなります。

これらのアプローチの中から、操作の性質、複雑さ、対象リソースとの関連性を考慮して最適な方法を選択することが重要です。多くの場合、操作をサブリソースとして表現する (POST /resource/{id}/operation) 方法が、リソース指向とのバランスを取りやすく、推奨されることが多いです。

リクエスト・レスポンスのデータ構造設計

操作を表現するAPIエンドポイントでは、リクエストボディで操作に必要な情報を伝え、レスポンスボディで操作結果や関連情報、状態などを返す必要があります。このデータ構造設計が、APIの使いやすさや保守性に大きく影響します。

リクエストボディの設計

操作の種類に応じて、クライアントから送信されるべき情報をリクエストボディに含めます。

リクエストボディの設計では、以下の点を考慮すると良いでしょう。

レスポンスボディの設計

操作を実行した結果をレスポンスボディで返します。これは操作が成功したかどうかの情報、操作によって変更されたリソースの最新状態、あるいは操作の結果生成された新しいリソースなどを含みます。

レスポンスボディの設計では、以下の点を考慮すると良いでしょう。

操作モデリングにおける考慮事項

ビジネス操作をAPIとしてモデリングする際には、データ構造だけでなく、API全体の設計思想や特性も考慮する必要があります。

アンチパターン

ビジネス操作のモデリングで陥りがちなアンチパターンを避けることも重要です。

まとめ

RESTful APIにおいて、CRUD操作では表現しきれない複雑なビジネス操作やイベントをデータモデリングすることは、APIの表現力と実用性を高める上で不可欠です。

これらの考え方を取り入れることで、単なるデータストアへのインターフェースではなく、ビジネスロジックを適切にカプセル化し、クライアントにとって使いやすく、サーバーサイドで保守しやすいAPIを実現できるでしょう。API設計は常に進化するものであり、完璧な設計は難しいかもしれませんが、これらの原則を理解し、チーム内で議論を重ねながら、より良いデータモデリングを目指していくことが大切です。