私は非常に遅れていることを知っていますが、私の考えが他の人を助けることができるかもしれません...
私の解決策は少し異なります。
リソースは、リソースごとに 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 接続を介してクエリされます。
キープアライブ接続には他にも懸念事項があることは承知していますので、すべてのアイデアについてお気軽にご相談ください。
ありがとう!