REST APIデザイナー向けの7つの悪いヒント

REST WORST PRACTICESから改編、©Jacob Kaplan-Moss。 この記事はDjangoに関連して書かれていますが、この情報は幅広い専門家に関連しています。



私は、それを行う方法を理解し、それを行う方法を学ぶための最良の方法は必要ないと思います。 REST APIデザイナーに有害なアドバイスを提供します。



数週間前、私はこのテキストを同僚に送信しました。同僚はDjangoでREST APIを設計するときにアドバイスを求めました。 それ以来、私は何度か自分自身を引用し、したがって、これらのヒントを公開することにしました。



モデルとリソースを組み合わせる



RESTの世界では、リソースは中心的な概念です。 単純にモデル(テーブルの行)を取得するのは非常に魅力的です。これはリソース(1つのモデル、1つのリソース)であると言えます。 この決定は、タスクが発生するとすぐに失敗します。ある種の複合リソースを提示するためであり、強く非正規化されたモデルでは確実に失敗します。



スーパーヒーローモデルを想像してください。ここに、すべての特性を返す必要がある唯一のGET / heros / superman /リクエストがあります。友人のリスト、それに関連付けられたアーティファクトのリストなどです。 リソースに関連付けられたデータは、実際には複数のモデルから取得できます。 また、ファサードパターンを思い出しておくと便利です。リソースは、特定のモデルではなく、モデルのファサードです。



APIコードで特定のアクセス制御サブシステムをハードワイヤード



アクセス制御メソッドはプラグ可能である必要があります。 アクセス制御モジュールは、どのオブジェクトに対してどの操作が有効であるかを判断する必要があります。これが、複雑な作業を行う唯一の方法です。



したがって、任意のシナリオを実装して、アクセス制御システムの制御を維持できます。 たとえば、あるシステムでは、匿名の読み取り、開発者トークンでアクセスする場合の読み取り/書き込み、および管理パネルを介した管理者データによるHTTP認証中のフルアクセスの実装が必要になる場合があります。



返されるデータの形式をリソースのタイプに依存させる



さまざまな理由で、リソースのタイプに応じて異なる形式の結果を使用することは非常に魅力的です。 しかし、このアプローチはクライアントコードを非常に複雑にするため、非常に悪い考えです。



Yahoo APIを覚えておいてください-ResultSet / Result形式はどこでも同じです。 Atom(GData)も同様です。



主な考え方は、クライアントコードが多くの異なるデータ形式を解析する方法を知る必要がないということです。



APIが1つの戻り形式のみをサポートするようにします



もちろん、JSONはクールで、最初からサポートする必要があります。 ただし、システムの開発に伴い、出力データの形式(AtomPubなど)を選択できるようになるはずです。



さらに、出力形式は、フォームの不要な構成ではなく、HTTP Acceptヘッダーを使用してネイティブに決定する必要がありますか?Format = xml。



標準のHTTPプロトコルメソッドをセマンティクスでオーバーロードする



私が見たREST APIのほとんどは、基本的な標準HTTPメソッド(POST / GET / PUT / DELETE)を対応するCRUDメソッド(作成/取得/更新/削除)にマップします。 一部のリソースはPOST-as-creator-linked-resourcesパターンを使用し、他のリソースはHTMLフォームとの後方互換性のためにPOSTのような編集を使用する場合があるため、これは良い考えではありません。 すべてのフォームは有効でなければなりません。



さらに、そのようなシステムでは、高度なHTTPメソッドを使用できません。 WebDAVはいくつかの便利なメソッドを定義しており、新しいHTTP PATCHメソッドはすでに正式に標準の一部になっています。 4つの主要なHTTPメソッドに限定する必要があると言う人はいません。これらのメソッドが広くサポートされていることについてのみです。 非標準のHTTPリクエストは、Webサーバーによって単に無視されます。



インデックスを使用してリソース間の関係を特定する



したがって、あるリソースが別のリソースを参照するようにします。 たとえば、PhotoAlbumはPhotoオブジェクトを指します。 通常、次のようにします。



{ 'album': 'whatever', 'photos': [1, 2, 3, 4] }
      
      





オブジェクトのIDを指定するだけです。 悲しいことに、これは、クライアントコードがPhotoリソースでURLを構築する方法について「知っている」必要があることを意味します。 また、クライアントとサーバーのコードが依存するようになります。 ボーナスとして、APIとクライアントコードの非互換性に関連するすべての問題が発生します。 地球上のほぼすべてのAPIがこの間違いを犯すため、URL形式をわずかに変更すると、APIのすべてのクライアントが自動的に破損します。



定義済みのURLを使用するだけです:



 { 'photos': ['http//example.com/ph/1', ...] }
      
      





または、髪の毛が複製に逆らって立っている場合は、URL形式を指定します。



 { 'photos': [1, 2, 3], 'photo_uri_template': 'http://example.com/ph/{id}' }
      
      





REST APIをアプリケーションにしっかりとバインドします



大規模なAPIには、その操作専用のサーバーが必要です。パフォーマンス特性とそれらが依存する要因は、大規模なAPIが個別に特別に構成されたサーバーを必要とする従来のWebアプリケーションとは大きく異なります。 これは事実です。 さらに、APIサーバーがクラッシュした場合、これは公開Webサイトに影響を与えません。



APIの設計におけるすべての成功!



All Articles