イントロ
これは、パンフレット「Web API Design」の主要なポイントの簡単な翻訳です。 Apigee LabsのBrian Malloyによる、開発者が愛するクラフトインターフェイス。 Apigeeは、さまざまなAPIサービスとコンサルティングの開発に従事しています。 ちなみに、この会社の顧客の間では、Best Buy、Cisco、Dell、Ebayなどの大手企業が光りました。
翻訳者の解説は本文中にあり、イタリック体で表記されています 。
他の開発者が好むAPIを収集します
API呼び出しのわかりやすいURL
優れたREST設計の最初の原則は、 物事を明確かつシンプルにすることです。 API呼び出しの基本URLから開始する必要があります。
文書がなくても、電話番号は明確にする必要があります。 これを行うには、 最大2つのパラメーターを含む短く明確なベースURLを使用して、任意のエンティティーを記述するルールにします 。 ここに素晴らしい例があります:
/dogs
/dogs/12345
名詞は良く、動詞は悪い
動詞は、APIのベースエンティティURLから可能な限り離してください。 多くの開発者は動詞を使用してオブジェクトを記述します。 作業では、しばしば複雑なエンティティをモデル化する必要があることは明らかです。 そして、これらのエンティティは互いに相互作用します。 しかし、エンティティとそれらの関係をモデル化するための動詞を導入しようとすると、覚えにくい、理解できない呼び出しが多数発生する可能性が高くなります。
/getAllDogs
/getAllLeashedDogs
/getDog
/newDog
/saveDog
これらの課題をご覧ください? これは恐怖です。
動詞の代わりに-HTTP
2つの基本名詞URLを使用して犬を説明しました。 次に、作成したエンティティを操作する必要があります。 ほとんどの場合、読み取り、作成、編集、および削除の操作が必要です(CRUD-作成-読み取り-更新-削除)。 そのためには、HTTPメソッドGET 、 POST 、 PUT、およびDELETEが最適です。
POST /dogs —
GET /dogs —
PUT /dogs —
DELETE /dogs —
POST /dogs/12345 — ( 12345 )
GET /dogs/12345 —
PUT /dogs/12345 — 12345
DELETE /dogs/12345 —
ベースURLはシンプルに見え、動詞は使用されず、すべてが直感的で明確です。 美人!
複数
複数の名詞を使用してベースURLを記述するのは良いことです。 悪い-単数形で。 アドレスに単数形と複数形の名詞を混在させるのは良くありません。
/checkins Foursquare
/deals y GroupOn
/Product y Zappos
具象名は抽象よりも優れています
抽象名-これは多くの場合、APIアーキテクトによってクールと見なされます。 そして、このAPIを後で使用する人にとっては、これはまったくクールではありません。
/ブログ、/ビデオ、/ニュース、/記事 -これは明らかです。 しかし、/アイテムと/アセットはそうではありません。
コミュニケーションズ
一部のリソースは、常に他のリソースにリンクされています。 APIを介してこれらの関係を表示する明白で簡単な方法はありますか? さらに、名詞と動詞への分割を覚えていますか?
GET /owners/5678/dogs
POST /owners/5678/dogs
2つのリソースの接続を簡単な方法で示しました。 この場合のGETメソッドは所有者の犬のリスト5678を返し、POSTメソッドは犬の所有者に別の5678を追加します。
コミュニケーションは/リソース/識別子/リソースの形で表現するのに非常に便利です 。
複雑なものは、記号「?」の後ろに隠す必要があります。
ほとんどすべてのAPIには、他の方法で読み取り、更新、フィルター処理、操作が可能な一連のパラメーターがあります。 ただし、これらのパラメーターはすべてベースアドレスに表示されるべきではありません。 ベースアドレスへの呼び出し内でパラメーターを指定するのが最善です。
GET /dogs?color=red&state=running&location=park
間違いはどうですか?
優れたエラー処理メカニズムは、優れたAPIの一部です。 一般的なAPIでエラーがどのように見えるか見てみましょう。
フェイスブック
HTTP Status Code: 200
{"type" : "OauthException", "message":"(#803) Some of the
aliases you requested do not exist: foo.bar"}
リクエストがどのように実行されるかは問題ではありません-Facebookは常に200 OKというコードを返します。
Twilio
HTTP Status Code: 401
{"status" : "401", "message":"Authenticate","code": 20003, "more
info": "http://www.twilio.com/docs/errors/20003"}
Twilioは良い仕事をし、APIのエラーごとに適切なHTTPエラーコードを選択しました。 Facebookのように、連中も応答の本文にエラー情報を提供します。 そして何よりも、問題に関するドキュメントへのリンクを提供します。
Simplegeo
HTTP Status Code: 401
{"code" : 401, "message": "Authentication Required"}
SimpleGeoは、HTTPコードでエラーメッセージを提供し、応答の本文で簡単な説明を提供します。
HTTP応答コードを使用する
HTTP応答コードを自由に取得し、APIの応答と関連付けてください。 合計で、約70のコードが頻繁に使用されています。 それらのすべてを覚えている開発者はほとんどいないので、70のうち約10を取得することをお勧めします。ところで、ほとんどのAPIプロバイダーはこれを行います。
Google gdata
200 201 304 400 401 403 404 409 410 500
Netflix
200 201 304 400 401 403 404 412 500
ディグ
200 400 401 403 404 410 500 503
どのHTTPエラーコードを使用する価値がありますか?
可能なAPIレスポンスは3つのみです
- リクエストは成功しました
- 間違ったデータが入力に送信されました-クライアントエラー
- データの処理中にエラーが発生しました-サーバーエラー
したがって、3つの応答コードを基礎として使用できます。
- 200 OK
- 400悪いリクエスト
- 500内部サーバーエラー
3つのコードでは不十分な場合は、別の5つを取ります:
- 201 Created(レコード作成済み)
- 304変更なし(データは変更されていません)
- 404が見つかりません
- 401不正
- 403 Forbidden(Access Denied)
盲目的にこの慣習に従わないことが最善です。 HTTP応答コードを使用する利点を測定する
それぞれの場合。 ほとんどの場合、応答コードの使用が常に正当で適切であるとは限りません。 たとえば、小規模なWebアプリケーションのバックエンドを作成している場合、応答本文のエラーコードに簡単に制限できます。 また、標準の200 OKレスポンスでは、サーバーエラーとAPI自体のエラーの2つのエラー処理メカニズムを作成できます。 一般的に-考えて、重量を量る。 そして、決定を下します。
そして、もちろん、エラーが発生した場合、常に開発者にメッセージを添付する必要があります。 問題に関するドキュメントへのリンクをメッセージに添付するとさらに効果的です。
バージョンを指定せずにAPIをリリースしないでください
Twilio/2010-04-01/Accounts
salesforce.com/services/data/v20.0/sobjects/Account
?v=1.0
Twilioでは、APIをリクエストするたびに、開発者アプリケーションがコンパイルされた時間を渡す必要があります。 この日付に基づいて、Twilioはアプリケーションが提供する必要があるAPIのバージョンを決定します。 これはスマートで興味深いアプローチですが、複雑すぎます。 そして、あなたは簡単に日付と混同することができます。
Salesforce.comは、リクエストAPIアドレスの途中にv20.0を挿入します。 そして、これは非常に良いアプローチです。 ただし、バージョン番号にドットを使用しないでください。これにより、APIが不必要に頻繁に変更されます。 API内の作業のロジックは何度でも変更できますが、ここではインターフェース自体はできる限り変更しないでください。 だから、ポイントなしでやって、自分を誘惑しない方がいい。
Facebookはリクエストでもバージョン番号を使用しますが、リクエストパラメータではバージョン番号を隠します。 APIの新しいバージョンの次の実装後、リクエストでバージョンを渡さないすべてのアプリケーションが失敗し始めるため、このアプローチは悪いです。
APIにバージョンを実装する方法は?
vプレフィックス、整数を使用し、バージョン番号をアドレスの左側に配置します。 たとえば、 / v1 / dogs 。
少なくとも1つ前のバージョンを機能させます
サーバーの応答ヘッダーでバージョンを指定することもできます。 これにより、APIを使用するときにいくつかの追加機能が提供される場合があります。 しかし、多くの異なるバージョンを使用しており、それらを見出しで示す必要がある場合、これは大きな問題の症状です。
部分回答
部分的な応答により、開発者は必要な情報のみを要求できます。 たとえば、一部のAPIへのリクエストは、ほとんど使用されない不必要な情報の束を返すことがあります。あらゆる種類のタイムスタンプ、メタデータなどです。 追加情報を要求しないようにするために、Googleは部分的な回答を考え出しました。
/people: (id, first-name, last-name, industry)
/joe.smith/friends?fields=id,name,picture
?fields=title, media:group(media:thumbnail)
要求アドレスにコンマを使用して必須フィールドをリストすることは、非常に単純で便利なアプローチです。 サービスを開始してください。
シンプルなページネーションを行う
最初のリクエストですべてのレコードを提供するのは非常に悪い考えです。 したがって、ページネーションを確実に提供する必要があります。 一般的なAPIでレコードを50から75にプルする方法を見てみましょう。
Facebook:50 25
Twitter:3 25
Linkedin:50- 25
制限とオフセットを使用することをお勧めします。 このアプローチはより直感的です。
/dogs?limit=25&offset=50
現在のページ、利用可能なレコード数など、各回答にメタ情報を追加する価値があります。
デフォルト値を提供します。ユーザーがリクエストでページネーションパラメータを渡さなかった場合、制限を10として、オフセットを0と見なします (最初の10エントリを印刷します)。
アクションはどうですか?
すべてのAPIが読み取り、編集、削除が可能なレコードではありません。 APIアクションもあります。 翻訳、計算、変換はすべてアクションです。
このようなクエリには、名詞ではなく動詞を使用することをお勧めします。
/convert?from=EUR&to=USD&amount=100
ドキュメントの呼び出しリストを見るだけでも、エンティティとアクションを区別できることを確認してください。
複数の形式のサポート
複数の応答形式をサポートすることは素晴らしいことです。
Google ?alt=json
Foursquare /venue.json
Digg ?type=json
ちなみに、DiggではAccept HTTPヘッダーを使用して応答形式を設定できます。
Foursquareのアプローチをお勧めします。
/dogs.json
/dogs/1234.json
また、API応答をさまざまな形式で提供できるだけでなく、さまざまな種類のクライアントに回答することもできます。 たとえば、iOSアプリケーションとWebアプリケーションのフロントエンドで同時に動作できるAPIを作成できます。 /dogs.iosおよび/dogs.webのようになります。
デフォルトの形式
JSONはおそらく最良のデフォルト形式です。 XMLよりも冗長ではありません。 すべての一般的な言語でサポートされています。 Webアプリケーションのフロントエンドですぐに使用できます。
属性名
属性はさまざまな方法で呼び出すことができます。
created_at
ビングDateTime
FoursquarecreatedAt
変数の命名には多くの規則があります。 Ruby on Railsのスペシャリストとして、Twitterコンベンションは間近に迫っています。 しかし、私たちはFoursquareのアプローチを最良のアプローチと考えています。-camelCase(小文字の変数、クラス-大文字)。 この命名規則は、データをJSONに送信するのに最も適しています。データはJavaScriptのように見えます。 一般に、これはJSONにとって論理的です。
著者はキャメルケースをより頻繁に使用することを勧めていますが、クライアントについて考えてから決定する方が良いでしょう。 たとえば、Cで記述されたプログラムはAPIと通信できますが、彼女が少数のother_conventionsを使用することをお勧めします。
検索する
グローバル検索は簡単です:
/search?q=search+word
特定のエンティティの検索は、以前に学んだことに基づいて簡単に想像できます。
/owners/5678/dogs?q=red
また、さまざまな形式でデータを表示するために、拡張機能を思い出してください。
/search.xml?q=search+word
1つのドメインですべてのAPI呼び出しを収集します
Facebookは2つのドメインを提供します。
api.facebook.com
このアドレスが最初に表示されました
graph.facebook.com
このアドレスは、グローバルグラフの実装後に入力されました
1つの住所に限定されたFoursquare
api.foursquare.com
Twitterには3つのアドレスがあり、そのうち2つは投稿と検索に重点を置いています
stream.twitter.com
api.twitter.com
search.twitter.com
FacebookやTwitterがどのように複数のアドレスに到達したのかを推測するのは簡単です。ロジック経由よりもDNS経由で異なるクラスターにリクエストを送信する方が簡単です。 しかし、開発者向けの優れたAPIを作成しているため、再びFoursquareアプローチを選択します。
念のため、Webアプリケーションの小さなバックエンドの開発者は、フロントエンドでのクロスドメインAjaxリクエストで問題が発生しないように、個別のドメインを割り当てる必要がないことを思い出させてください。
リダイレクト
誰かがあなたのAPIドメインにアクセスし、パラメーターを渡さない場合は、開発者向けのドキュメントを使用してドメインにリダイレクトしてください。 直感的なドキュメントドメインをいくつか取得し、メインの開発者ドメインにリダイレクトします。
api.* -> developers.*
dev.* -> developers.*
developer.* -> developers.*
HTTP応答コードとクライアント例外
前述したように、エラーコードはAPI応答の本文だけでなく、HTTP応答コードでも送信するのが最適です。 しかし、200以外のHTTPコードを受け取ったときにクライアントが例外をスローしたらどうなるでしょうか? このような場合、Twitterのスタッフは、リクエストにパラメーターを追加するという、素晴らしいシンプルなソリューションを提供しました。
/public_timelines.json?suppress_response_code=true
その結果、エラーはコード200で発生します。
APIでsuppress_response_codesパラメーターを指定し、デフォルトでtrueに設定します。
しかし、クライアントがサポートしているHTTPメソッドのセットが限られている場合はどうでしょうか?
この場合、GETパラメーターを使用して完全なREST APIをエミュレートする必要があります。
/dogs
/dogs?method=post
/dogs/1234?method=put
/dogs/1234?method=delete
このアプローチには注意してください! そのようなリンクを不正確に処理し、適切なセキュリティを提供しない場合、ボット(Google検索ロボットなど)がそのようなリンクをトリガーできます。 そして、ボットが入るたびに無限に作成および削除されたレコードを取得します。
ログイン
これは複雑な問題であり、同僚と私はすぐに同意することはできません。 主要なプレーヤーが何をしているのか見てみましょう。
PayPal Permissions Service API
Facebook OAuth 2.0
Twitter 1.0a
OAuthが発明される前から、PayPalは承認システムを実装していました。
サードパーティアプリケーションを介したユーザー認証が必要な場合-OAuthのみ。 そして、OAuthのようなことは決してしませんが、「少し違います」。
Chatty API
「チャット」-これは、一般的な操作を実行するには、3〜4回のAPI呼び出しを連続して行う必要があることを意味します。 これは悪いです。
ユーザーの目を通してあなたの課題を見てみてください。 呼び出しの約80%が同じ構造のデータを送受信することがわかります。 これは、呼び出しシーケンスのエイリアスを作成できることを意味します。 その後、ユーザーは入力にデータを1回送信できるようになり、呼び出しのチェーン全体が自動的に実行されます。