19

複雑な Web アプリケーションの場合、1 つのページ ビューでさまざまな種類のデータが必要になる場合があります。クライアント側でテンプレートを作成し、RESTful Web サービスからこのデータを取得している場合、ページに入力するために多くの要求を行う必要がある場合があります。必要なすべての応答を含む単一のペイロードを受信するために、REST 要求を組み合わせる規則はありますか?

例として Stack Exchange User ページを使用するには、ページを構築するためにStack Exchange APIから少なくともこれらを呼び出す必要があります。

  • /users/{id}
  • /users/{id}/answers
  • /users/{id}/評判
  • /users/{id}/tags
  • /users/{id}/質問
  • ...等

そのような API のプロバイダーは、単一の要求でそのすべてのデータを取得できるでしょうか? 特に他のルート タイプが関係している場合、何らかの理由で /revisions/{id} と /tags も要求してページを作成する必要があるとします。

明確にするために、Web API でそのような機能を提供できるかどうかは知りたくありません。それを行うための標準的な手段または少なくとも文書化された手段があるかどうかを知りたいのです。

4

4 に答える 4

5

これを行うには標準的な方法が必要だと思いますが、それまではおそらくあなた自身であるでしょう.

過去に、複数のリソースにまたがるトランザクションを実行したいときに、同様の課題がありました。私は自分が行おうとしているアクションをより明確に説明する新しいリソースを発明しました (アカウント A から 5 を引き、アカウント B に 5 を追加すると、メンバーとの間のトランザクションになります)。

おそらく、別の REST 呼び出しをコンテナーとして使用することで、同様の (ただしより一般的な) アプローチを適用できます。

POST /batchRequests { requests: [
    { method: 'POST', url: '/resource', payload: { ... } }
], transactional: false }

結果を含む「BatchRequest」オブジェクトが返されました。これは、Facebook が行ったことにもかなり近いものです。

于 2013-08-07T10:55:27.703 に答える
3

それはRESTの原則に反するかもしれないと思いますね。つまり、オブジェクト表現ごとの一意のURIとそのペイロード。それは事態を悪化させませんか?それがTI計算機ではなく、並列HTTP要求が可能な最新のコンピューターを考えると、それらすべての中で最も長い時間がかかる単一のコンピューターとは対照的です。

標準があるとは思わないが、ここに例がある-https://developers.facebook.com/docs/reference/api/batch/

于 2013-01-31T22:51:19.557 に答える
1

私は非常に遅れていることを知っていますが、私の考えが他の人を助けることができるかもしれません...

私の解決策は少し異なります。

リソースは、リソースごとに 1 つの uri (統一リソース識別子) に格納します。

ユーザー

GET /user => INDEX
PUT /user => CREATE (RETURN LOCATION HEADER)
GET /user/{id} => FIND
POST /user/{id} => UPDATE
DELETE /user/{id} => REMOVE

メッセージ

GET /user/{id}/message => INDEX
PUT /user/{id}/message => CREATE (RETURN LOCATION HEADER)
GET /user/{id}/message => FIND
POST /user/{id}/message/{id} => UPDATE
DELETE /user/{id}/message/{id} => REMOVE

友達

GET /user/{id}/friend => INDEX
PUT /user/{id}/friend => CREATE (RETURN LOCATION HEADER)
GET /user/{id}/friend => FIND
POST /user/{id}/friend/{id} => UPDATE
DELETE /user/{id}/friend/{id} => REMOVE

結果の content-type は、クライアントが指定する必要があるHTTP-Headerを介して変更できます。

Accept: "application/vnd.com.example.api+json; version: 1.0;"

現在、使用するバージョンとコンテンツ タイプをサーバーに通知するのはAccept HTTP-Headerフィールドです。

ブラウザーまたはプロキシーのキャッシュ機能を維持するために、API にVary HTTP ヘッダーフィールドを返すことにしました。すべてのコンテンツがその中の HTTP ヘッダーを変更し、ブラウザーがuri と headersによってリソース間で正しく異なるようにします。

Vary: "Accept, Accept-Language"

最大の問題は、リソースを組み合わせて、クライアントが一度に多くの tcp 接続を開かないようにする方法です。

例: /userを介して API からユーザー リストをクエリすると、API は目的のコンテンツ タイプ (JSON、XML、HTML) でユーザー オブジェクトの配列を返します。

ページネーションとフィルター/検索のサポートが利用できるため、詳細には触れません。

各ユーザー オブジェクトには、友人メッセージなどの依存リソースがあります。

HAL (Hypertext Application Language)と呼ばれる非常に優れた構造化された標準があり、リソースをその依存リソースまたはリンクされたリソースと組み合わせる簡単な方法を提供します。JSON を使用してデータを表します。

http://stateless.co/hal_specification.html by Mike Kellyをご覧ください。

ただし、このソリューションも 1 回の呼び出しでリソースを結合するのではなく、依存リソースまたはリンクされたリソースの URI をペイロードと共にクライアントに送信するだけです。

これにより、クライアントはどの追加情報を表示するかを決定できます。

そしてもちろん、非常に重要なすべてのキャッシュ機能が機能しています。

リソースを参照するときのトラフィックのほとんどは、非常に簡単にキャッシュできる複製されたリクエストになります。

与えられた例で、ユーザー リスト内のユーザーの友人の数またはメッセージの数を表示したい場合は、依存リソースを結果のキーとして追加することを検討してください。

ユーザー応答の例 (JSON)

{
     id: 1,
     email: test@test.com,
     ...
     friends: {
         count: 1,
         _links: [{
             'id': '2',
             'name': 'Peter Parker',
             'uri': '//api.example.com/user/2'
         }]
     },
     messages: {
         count: 1,
         _links: [{
             'id': 'x4gZ6',
             'subject': 'Testmessage',
             'uri': '//api.example.com/user/1/message/x4gZ6'
         }]
     },
     ...
}

それでは、複数の TCP 接続を使用しないようにする方法について説明しましょう。

そのための非常にシンプルで優れたアプローチがあります...

使用しない理由:

 Connection: "keep-alive"

これにより、クライアントは一度に必要な数のリソースを照会できるようになります。すべてのリソースは、サーバーへの単一の TCP 接続を介してクエリされます。

キープアライブ接続には他にも懸念事項があることは承知していますので、すべてのアイデアについてお気軽にご相談ください。

ありがとう!

于 2014-05-06T14:56:10.640 に答える
1

このパーティーに参加するのが非常に遅くなりましたが、クリーンな REST 設計と実際の Web サイトの現実とのバランスを取るというトピックについて、オンラインで明るい情報を探していました。私は通常の「パフォーマンスのために http リクエストを減らす」ことを見つけましたが、トレードオフに目を向けたグッドプラクティスに関する良いエッセイはありません。(コメンターは気軽に私に方向性を示してくれます!) そして何ということでしょう、まだ明確な答えはありません。

これを行うことで他の人があなたの生活を楽にすることができるかどうかを尋ねているのか、それとも API を設計しているために尋ねているのかはわかりません。あなたの質問は他の人が言っているので、ここに行きます。

そのような API のプロバイダーは、単一の要求でそのすべてのデータを取得できるでしょうか? 特に他のルート タイプが関係している場合は、何らかの理由でページを構築するために /revisions/{id} と /tags も要求する必要があるとします。

明確にするために、Web API でそのような機能を提供できるかどうかは知りたくありません。それを行うための標準的な方法または少なくとも文書化された方法があるかどうかを知りたいのです。

簡単に言うと、このテーマに関する優れたエッセイはあまり見たことがありません。REST の人気は、アカデミック コンセンサス スタイルの優れた一連の回答に対してまだ若いかもしれません。それを回避できる場合は、やらなければならないことを行い、自分の設計がどれほど純粋であるかについてあまり心配しません。re:REST のような頭字語です。しかし、もし私が大規模なパブリック API (以下を参照) のプロバイダーであるとしたら、おそらくより純粋な標準 (REST など) の実装に向かうと思います。

それは可能です。私は自分のアプリケーションで多くの純粋な REST 設計を台無しにして、パフォーマンスに関して必要なものを達成しました。主に RPC を使用するか、リソースの取得/更新を組み合わせて、HTTP 要求の数を最小限に抑え、最新のフランケンシュタイン Web 開発者が作成できるものにします。

そのような API のプロバイダーは、単一の要求でそのすべてのデータを取得できるでしょうか?

技術的には、彼/彼は確かにそれを行うことができました. しかし、私が一般向けの人気のある API のパブリッシャーである場合は、おそらくより「純粋な」REST アプローチを使用するでしょう。なぜなら、多くの見知らぬ人がそれを使用するようになると、シンプルさ、使いやすさ、およびメンテナンスがまったく新しい意味を持つようになるからです。この場合、私と消費者のパフォーマンスは、私が消費者とプロバイダーの両方であるエンタープライズ アプリの場合よりも優先度が低くなる可能性があります。

いつものように、開発者は、実装の速度、クリーンなデザイン、保守性、パフォーマンス、およびその他無数のものの間で適切なバランスを決定する必要があります。(その決定は言語の選択からすでに始まっています -- Python/Ruby vs Java/C# vs C++ vs...)

于 2014-09-16T17:20:27.677 に答える