LastUser
とはクライアントが変更できないためLastUpdate
、リソースの表現から完全に削除します。例を挙げて私の推論を説明しましょう。
単一のリソースを提供するように求められたときに、典型的な API の例がクライアントに次の表現を返すとします。
GET /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>ipsum</lorem>
<dolor>sit amet</dolor>
<lastUser uri="/user/321">321</lastUser>
<lastUpdate>2011-04-16 20:00:00 GMT</lastUpdate>
</example>
クライアントがリソースを変更したい場合、おそらく表現全体を取り、それを API に送り返します。
PUT /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
<lastUser>322</lastUser>
<lastUpdate>2011-04-16 20:46:15 GMT+2</lastUpdate>
</example>
API は and の値を自動的に生成lastUser
しlastUpdate
、クライアントから提供されたデータを受け入れることができないため、最も適切な応答は400 Bad Request
or403 Forbidden
です (クライアントはこれらの値を変更できないため)。
lastUser
REST に準拠し、PUT 要求を実行するときにリソースの完全な表現を送信する場合は、リソースの表現からとを削除する必要がありlastUpdate
ます。これにより、クライアントは PUT 経由でエンティティ全体を送信できます。
PUT /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
lastUpdate
およびが含まれていないため、サーバーは完全な表現を受け入れるようになりlastUser
ます。
lastUpdate
残っている問題は、クライアントにおよびへのアクセスを提供する方法lastUser
です。彼らがそれを必要としない場合 (これらのフィールドは API によって内部的に必要とされるだけです)、私たちは問題なく、私たちのソリューションは完全に RESTful です。ただし、クライアントがこのデータにアクセスする必要がある場合、最もクリーンな方法は HTTP ヘッダーを使用することです。
GET /example/123
...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
X-Last-User: /user/322
...
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
カスタム HTTP ヘッダーの使用は、ユーザー エージェントに読み方を教える必要があるため、理想的ではありません。クライアントに同じデータへのアクセスをより簡単な方法で提供したい場合、私たちができる唯一のことはデータを表現に入れることであり、元の質問と同じ問題に直面しています。少なくとも何とか軽減しようと思います。API で使用されるコンテンツ タイプが XML の場合、データをノード値として直接公開するのではなく、ノード属性に入れることができます。つまり、次のようになります。
GET /example/123
...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
...
<?xml version="1.0" encoding="UTF-8" ?>
<example last-update="2011-04-16 18:46:15 GMT" last-user="/user/322">
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
このようにして、少なくとも、クライアントがフォローアップの PUT 要求ですべての XML ノードを送信しようとする問題を回避できます。これは JSON では機能せず、解決策はまだ冪等性の端にあります (API はリクエストを処理するときに XML 属性を無視する必要があるため)。
さらに良いことに、ジョナがコメントで指摘したように、クライアントがlastUser
およびにアクセスする必要がある場合lastUpdate
、これらは新しいリソースとして公開され、元のリソースからリンクされます。たとえば、次のようになります。
GET /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
<lastUpdateUri>/example/123/last-update</lastUpdateUri>
</example>
... その後:
GET /example/123/last-update
<?xml version="1.0" encoding="UTF-8" ?>
<lastUpdate>
<resourceUri>/example/123</resourceUri>
<updatedBy uri="/user/321">321</updatedBy>
<updatedAt>2011-04-16 20:00:00 GMT</updatedAt>
</lastUpdate>
(リソースの変更ログが利用可能であれば、上記を適切に拡張して、個々の変更を含む完全な監査ログを提供することもできます。)
注: Darrel Millerの質問に対する
見解
には同意しますが、その上で別のアプローチを提供したかったのです。このアプローチは、標準/RFC/などによってバックアップされていないことに注意してください。これは、問題に対する別の見方です。