コンテンツに移動
API 管理

RESTful のウェブ API 設計で避けるべき 6 つのよくあるミス

2022年12月15日
https://storage.googleapis.com/gweb-cloudblog-publish/images/api_2022.max-2500x2500.jpg
Google Cloud Japan Team

※この投稿は米国時間 2022 年 12 月 1 日に、Google Cloud blog に投稿されたものの抄訳です。

オンラインで、組み立て式のテーブルを注文したとします。ところが、パッケージを開けてみると、組立説明書が入っていません。完成品がどんなものかはわかっていても、それぞれのパーツをどう組み立てればいいのか、まるでわかりません。設計が不十分な API を使うコンシューマ開発者も、同じような経験をしているといえます。適切に設計された API なら、容易に見つけ、検索してアクセスし、使用することができます。高品質の API は、コンシューマ開発者がアイデアをひらめき、新しいユースケースを作り上げる手助けになってさえくれます。

もちろん、API 設計を改善する方法はあります。たとえば、RESTful のプラクティスに従うなどです。しかし、お客様が知らず知らずのうちに、ちょっとした不便を API にプログラムしてしまっているのを何度も見てきました。こうした落とし穴を回避するために、開発者が API を作成する際に犯しがちな 6 つのミスと、それをどう修正するかについてお話しします。

#1 インサイドアウトで考えるか?アウトサイドインで考えるか?

「すべての人に気に入られるもの」とはしばしば、誰にとってのベストでもない無難なものになりがちですが、同じことが API にとっても言えます。お客様が API に求めるものは、自身の業務をより簡単にし、生産性を上げてくれることです。こうしたニーズにさらによく応えてくれる API が他にあれば、お客様はそちらを選ぶでしょう。だからこそ、まずお客様の業務改善のために何が必要なのかを知り、そのニーズに合わせて API を構築することが重要なのです。言い換えれば、インサイドアウトではなく、アウトサイドインの考え方が大事ということです。具体的には、以下のようなことです。

  • インサイドアウトとは、公開する内部システムやサービスに基づいて API を設計することをいいます。

  • アウトサイドインとは、作り上げたいカスタマー エクスペリエンスに基づいて API を設計することをいいます。アウトサイドインの視点に関して詳しくは、API プロダクト マインドセットをご覧ください。

最初のステップは、社内のコンシューマ開発者であれ、外部のお客様であれ、詳しく話を聞き、ユースケースを知ることです。構築しているアプリや課題、どんなものが開発の合理化や簡易化に役立つかを尋ねます。最も重要なユースケースを書き留め、それぞれのケースに必要なデータのみを提供するサンプル API レスポンスを作成します。このテストでは、ペイロード間の重複を探し、共通または類似のユースケースで汎用化するように設計を適合させます。

https://storage.googleapis.com/gweb-cloudblog-publish/images/1_RESTful_web.max-1200x1200.jpg

お客様と直接やり取りできない場合(たとえば連絡先を知らない、時間がない、お客様自身も何が必要かわかっていないなど)、最善のアプローチは、API を使って何を構築するかを想像してみることです。物事を大局的に、そして創造的に考えてみましょう。誰しも、ベーパーウェアのために API を設計したくはないものです。全体像を描いておくことで、将来的に互換性を損なわない変更を簡単に構築できます。たとえば、下の画像は、Google マップが提供する API を紹介したものです。ドキュメントを詳しく読まなくても、「Autocomplete」や「Address Validation」などの名前を見ただけで、内容が把握でき、お客様のユースケースにフィットしそうなものであることが一目瞭然です。

https://storage.googleapis.com/gweb-cloudblog-publish/images/2_RESTful_web.max-1200x1200.jpg

#2 ユーザーにとって複雑すぎる API を作っている

お客様が API を利用する目的は、複雑なプログラミングの課題を回避し、得意な分野に注力できるようにすることです。ある API が、まったく知らないシステムや言語を習うようなくらい難しいものだったとしたら、おそらくお客様はその API を役に立たないと感じ、他の API を探すでしょう。お客様のニーズを満たすのに十分強力であり、そうするための機能性を有しているにもかかわらず、複雑なタスクを処理しているように見えない、一見シンプルな API を提供できるかは、チームの腕の見せどころです。たとえば、最近オープンしたレストランや評価の高いピッツェリアの情報を消費者に提供するため、お客様が API を使用している場合、以下のようなシンプルな API 呼び出しは大変役に立つでしょう。

読み込んでいます...

ご自身の API 設計がシンプルであるか確かめるには、システム全体をゼロから構築していると想定してください。また、信頼できるお客様がいる場合は、テストを依頼し、結果を報告してもらってください。何も引っかかるところがなくワークフローを完了できれば問題ありません。しかし、システムの複雑さを回避するためにコードを書くと、荒削りな部分が見えてしまう場合は、リファクタリングを続ける必要があります。API に複雑なところは何もなく、お客様のニーズを満たしている、またはニーズの変化に応じて簡単に更新できると言えるようになれば、準備は万全でしょう。

#3 呼び出しが多すぎる「手間のかかる」API を作成している

複数のネットワーク呼び出しは、処理を遅くし、接続のオーバーヘッドを増加させます。これは、オペレーション費用が増加することを意味します。API 呼び出しの数を最小限に抑えるのが重要な理由はここにあります。

そのために重要なのは、アウトサイドインの設計、つまり、シンプルにすることです。アプリケーションのワークフローにおいて、お客様が行う必要がある API 呼び出しの回数を減らす方法を探ります。たとえば、モバイル アプリケーションを構築しているお客様は、バッテリーの消耗を抑えるために、ネットワーク トラフィックを最小限にする必要があります。呼び出しを十数回から数回に抑えることが、大きな違いを生むのです。

個別のデータドリブンのマイクロサービスの構築か、API 利用の効率化か、どちらかだけを選択するのではなく、両方を提供することを検討してみてください。つまり、特定のデータタイプ用のきめ細かい API と、共通またはお客様固有のユーザー インターフェースの周辺の「Experience API」です(ユーザー エクスペリエンスを強化するために設計された API。Experience API について詳しくは、理論的ディスカッションをご参照ください)。こうした Experence API は、複数の小さなドメインを 1 つのエンドポイントにまとめ、お客様(特にユーザー インターフェース構築者)が、画面を簡単かつ迅速にレンダリングできるようにします。

もう一つのオプションは、GraphQL などを利用して、こうしたカスタマイズを可能にすることです。一般に、ありとあらゆる画面に対して単一のエンドポイントを構築することは避けるべきですが、ホームページやユーザー アカウント情報などといった一般的な画面は、API コンシューマにとって大きな違いをもたらしうると言えます。

#4 柔軟性に欠けている

上述のステップをすべて行ったとしても、美しく設計されたペイロードの下に収まりきらないエッジケースがあることに気づくかもしれません。たとえば、お客様が 1 ページあたりの検索結果に通常よりも多くのデータを求めているかもしれませんし、アプリで必要なものよりはるかに多いデータがペイロードに含まれているかもしれません。万能のソリューションを作るのは不可能ですが、制限だらけの API だという評判も避けたいところです。そこで、エンドポイントをより柔軟にするための 3 つの簡単なオプションを紹介します。

レスポンス プロパティを除外する: 並び替えやページネーションにクエリ パラメータを使用するか、これらのタイプの詳細をネイティブで提供する GraphQL を使用できます。必要なプロパティだけをリクエストできるようにすることで、お客様が不必要な大量のデータを整理する必要がなくなります。たとえば、お客様がタイトル、著者名、ベストセラーのランキングのみを必要としている場合、クエリ文字列パラメータでそのデータのみを取得する機能を提供できます。
読み込んでいます...

  • ページネーションによるソート機能: 一般に、API レスポンスにおけるオブジェクトの順序を保証したいと考える人は少ないでしょう。ロジックのちょっとした変更やデータソースの固有性により、表示順が変更される可能性が十分あるからです。しかし、場合によっては、お客様が特定の項目で並び替えたいと思うこともあるでしょう。このオプションとページネーションのオプションを組み合わせれば、上位の検索結果のみが必要な場合に、非常に効率的な API を提供できます。たとえば、Spotify API は、単純なオフセットと limit パラメータ セットを利用して、ページネーションを可能にしています。ドキュメントに示されているサンプルのエンドポイントは、次のようになります。

読み込んでいます...

  • GraphQL のような成熟したコンポジションを使用する: 顧客データのニーズはそれぞれ違うので、オンザフライのコンポジットを提供することにより、単一のデータ型やデータ フィールドのプリセットの組み合わせに制限されるのではなく、必要なデータの組み合わせに合わせて構築できます。GraphQL を使用すれば、Experence API を構築する必要性を回避することもできますが、それも不可能な場合は、「expand」などのクエリ文字列パラメータ オプションを使用して、より複雑なクエリを作成できます。以下は、プロパティを組み込んだ企業リソースのコレクションを示すレスポンス例です。

読み込んでいます...

#5 人間には読めない設計になっている

API を設計する際の鉄則は、「とにかくシンプルに」です。API 自体はパソコン同士のやりとりを想定していますが、API の最初のクライアントは常に人間であり、API コントラクトが最初のドキュメントなのです。開発者は、ドキュメントを掘り下げる前にペイロード設計を研究する傾向があります。調査結果によると、開発者がエディタとクライアントで費やす時間は 51% 以上であるのに対し、リファレンスに費やす時間は多くとも 18% 程度であることがわかっています。

 

たとえば、以下のペイロードにざっと目を通してみると、プロパティ名の代わりに「id」が含まれているため、理解するのに時間がかかります。プロパティ名「data」でさえも、JSON 設計のアーティファクトであることを除けば、何の意味もありません。ペイロードに数バイト追加するだけで、初期段階での混乱を回避し、API の導入を促進できます。コロンの左側(他の理想的な JSON の例なら、プロパティ名が入っている位置)に表示されているユーザー ID こそが、ペイロードの読み取りの際の混乱の元となっているのです。
読み込んでいます...

このような JSON の方が、学習するのは難しいでしょう。データ説明の文言のあいまいさをなくしたい場合は、ペイロードをシンプルにします。ラベルが 2 つ以上の意味に解釈できる場合は、より明確になるように調整します。以下は、Aviationstack API における、航空会社のエンドポイントからのレスポンス例です。シンプルな JSON 構造を維持しながらも、プロパティ名が期待される結果を明確に説明しています。

読み込んでいます...

#6 RESTful のルールを破るタイミングを知る

正しい HTTP 動詞、ステータス コード、ステートレス リソースをベースにしたインターフェースの使用など、RESTful の基本に忠実であれば、お客様は新しい語彙を学ぶ必要がなく、大変な思いをすることはありません。しかし、本来の目的は、お客様の業務遂行を支援することなのです。ユーザー エクスペリエンスよりも RESTful の設計を優先させると、本来の目的を果たせなくなります。

お客様ができるだけ早く、簡単に、データを使って成功する支援をすることが目標なのです。ときには、よりシンプルでエレガントなインターフェースを提供するため、REST の「ルール」を破る必要があるかもしれません。すべての API で一貫した設計を選択しましょう。特殊な部分や非標準的な部分については、ドキュメントで明確に説明してください。

まとめ

こうした一般的な落とし穴に加えて、Google Cloud の API 管理プロダクトである Apigee において驚異的なスケールで API を設計、管理した豊富な経験をパッケージ化した完全版ガイドも作成しました。

Google Cloud のネイティブ API 管理プラットフォームである Apigee は、あらゆるユースケース、規模、環境において、API の構築、管理、セキュリティ確保を支援します。ぜひ Apigee をご検討ください。詳しい情報は、こちらのドキュメントをご覧ください。

Google Cloud、プロダクト マーケティング マネージャー Varun Krovvidi

- Google Cloud、ビジネス アプリケーション プラットフォーム担当プロダクト マネージャー Geir Sjurseth
投稿先