OCAPI リソースの状態 23.1

リソースの状態は、買い物カゴや顧客といった特定のリソースのサーバー側の状態を表します。これは、すべてのリソースプロパティ情報上で作成される文字列トークンです。

OCAPI は、_resource_state を使用して、リソースの状態の情報をレスポンスペイロード (ボディ) に表示します。レスポンスには、1 つのリソースの状態が含まれるか、あるいはコレクションや検索のリソースを呼び出す場合は複数のリソースの状態が含まれます。ボディのないレスポンス (HEAD など) の場合は、リソースの状態は x-dw-resource-state レスポンスヘッダーによって表示されます。

リソースの状態の使用目的 

リソースの状態は、クライアントに楽観的ロック を実装するためのオプションのメカニズムを提供します。“失われた更新” の問題を解決するなど、同時実行リクエスト間での競合を防ぐために使用できます。

リソースの状態と Etag 

強い Etag はサーバー側のリソース状態だけではなく、ビットレベルで HTTP レスポンス全体を対象とします。つまり、圧縮 (gzip など) が使用されるかどうかも対象とします。プロキシが中間にあるシナリオでは、これによって予期しない動作が引き起こされる可能性があります。たとえば、クライアントが圧縮をリクエストしていないにもかかわらず、プロキシとサーバー間で圧縮が行われた場合、Etag 値に “-gzip” を付加するプロキシと、Etag を完全に吸収するプロキシが発生します。

OCAPI は用語 “resource_state” を使用して、その概念を Etag と明確に区別しています。OCAPI は現在 Etag をサポートしていません。

Note

仕組み 

楽観的ロックにリソースの状態を使用するには、次回の状態変更 (DELETE、PATCH、POST、PUT) リクエストに、最後のサーバーレスポンスからのリソース状態を含める必要があります。ボディには常に _resource_state プロパティを使用するようにします。リクエストした API にボディがない場合は、x-dw-resource-state ヘッダーを使用します。リソースの状態がクライアントのリクエストの一部である場合は常に、OCAPI は指定された値をサーバーのリソース状態と比較して、検証します。両方のリソースの状態が等しい場合、操作は実行されます。等しくない場合は、HTTP 409 ResourceStateConflictException フォールトが返されます。(PUT を使用する場合など) リクエスト作成で (not_exists 状態を使用して) リソースが存在する必要がない場合、返されるフォールトは HTTP 409 ResourceAlreadyExistsException です。

お使いのアプリケーションで状態変更 (DELETE、PATCH、POST、PUT) 操作の実行時に同時実行リクエストの可能性がある場合、リソースの状態を基にした楽観的ロックの使用をお勧めします。

Note

サンプル 

OCAPI は、リソースの状態をレスポンスボディで _resource_state プロパティとして、および x-dw-resource-state ヘッダーとして表示します。

1# Create a new basket in the Shop API:
2REQUEST:
3POST /dw/shop/v23_1/baskets
4Host: example.com
5Authorization:Bearer eyJfdiI6IjXXXXXX.eyJfdiI6IjEiLCJleHAXXXXXXX.-d5wQW4c4O4wt-Zkl7_fiEiALW1XXXX
6Content-Type: application/json
7
8# in case of success, response contains new created basket with the resource state in response
9# header and also as single property in response body
10RESPONSE:
11HTTP/1.1 200 OK
12Content-Length:124
13x-dw-resource-state:ba4e84383e1790597e49eeee34b201633d80ed3f499992f5af11d639dd903a36
14Content-Type:application/json;charset=UTF-8
15{
16   "_resource_state" : "ba4e84383e1790597e49eeee34b201633d80ed3f499992f5af11d639dd903a36",
17   ...
18   "basket_id" : "bczFTaOjgEqUkaaadkvHwbgrP5",
19   ...
20}
21
22# Search for stores in the Data API:
23REQUEST:
24POST /s/-/dw/data/v23_1/sites/SiteGenesis/store_search HTTP/1.1
25Host: example.com
26Authorization: Bearer a5b6eb0d-8312-41a3-88f3-2c53c4507367
27...
28
29# in case of success, response contains multiple resource states - one per search hit
30RESPONSE:
31HTTP/1.1 200 OK
32{
33   ...
34   "hits" : [{
35      "_resource_state" : "12ab34cd",
36      "id" : ...
37   },{
38      "_resource_state" : "ef56gh78",
39      "id" : ...
40   }]
41}

リソースの状態は、いずれかの状態変更メソッド (DELETE、PATCH、POST、PUT) に渡すことができます。リソースの状態が渡されないと、リソースは、デフォルトの HTTP メソッド動作に基づいて通知なしに上書き、更新、または削除されます。リソースの状態が渡されると、サーバーのリソースの状態に照らし合わせて検証されます。両方の状態が一致しない場合、ResourceStateConflictException または ResourceAlreadyExistsException フォールトが返されます。API ユーザーがリソースの存在を必要としない場合 (リソース作成時など)、リソースの状態 not_exists を渡すことができます。これにより、既存のリソースが間違って上書きされることのないようにします。

リソース上での書き込み操作では、リソース状態トークンを渡せますが、必須ではありません。トークンが渡されないと、リソースは通知なしに上書き、更新、削除されます。リソースの状態が渡されると、リソースのサーバー状態に照らし合わせて確認されます。両方の状態が一致しない場合、409 ステータスコードが取得されます。API ユーザーがリソースの存在を必要としない場合、リソースの状態 not_exists を渡す必要があります (リクエストの作成の場合)。

1# add an item to the basket, the resource state from the response header is given as x-dw-resource-state
2# header ...
3REQUEST:
4POST /dw/shop/v23_1/baskets/bczFTaOjgEqUkaaadkvHwbgrP5/items?client_id=af123-456....
5Host: example.com
6Authorization:Bearer eyJfdiI6IjXXXXXX.eyJfdiI6IjEiLCJleHAXXXXXXX.-d5wQW4c4O4wt-Zkl7_fiEiALW1XXXX
7x-dw-resource-state:ba4e84383e1790597e49eeee34b201633d80ed3f499992f5af11d639dd903a36
8Content-Type: application/json
9{
10...
11}
12
13# ... or as _resource_state property in the body
14
15# Add an item to the basket, send resource state via body
16
17REQUEST:
18POST /dw/shop/v23_1/baskets/bczFTaOjgEqUkaaadkvHwbgrP5/items
19Host: example.com
20Authorization: Bearer eyJfdiI6IjXXXXXX.eyJfdiI6IjEiLCJleHAXXXXXXX.-d5wQW4c4O4wt-Zkl7_fiEiALW1XXXX
21Content-Type: application/json
22{
23   "_resource_state" : "ba4e84383e1790597e49eeee34b201633d80ed3f499992f5af11d639dd903a36"
24   ...
25}
26
27# in case of success, the next response header contains a new resource state
28RESPONSE:
29HTTP/1.1 200 OK
30Content-Length:124
31x-dw-resource-state: ba4e84383e1790597e49eeee34b201633d80ed3f499992f5af11d639dd903a36
32Content-Type:application/json;charset=UTF-8
33{
34   "_resource_state" : "ba4e84383e1790597e49eeee34b201633d80ed3f499992f5af11d639dd903a36"
35   ...
36   "basket_id" : "bczFTaOjgEqUkaaadkvHwbgrP5",
37   ...
38}
39
40# Delete an item from the basket, resource state is send via header
41
42REQUEST:
43DELETE /dw/shop/v23_1/baskets/bczFTaOjgEqUkaaadkvHwbgrP5/items/te352d63gdh62hd6hd
44Host: example.com
45Authorization: Bearer eyJfdiI6IjXXXXXX.eyJfdiI6IjEiLCJleHAXXXXXXX.-d5wQW4c4O4wt-Zkl7_fiEiALW1XXXX
46x-dw-resource-state: 100001
47Content-Length: 0
48
49# in case of creating a not existent customer
50
51REQUEST:
52PUT /s/-/dw/data/v23_1/customer_lists/4711/customers/0815 HTTP/1.1
53Host: example.com
54Authorization: Bearer a5b6eb0d-8312-41a3-88f3-2c53c4507367
55Content-Type: application/json; charset=UTF-8
56{
57   "_resource_state" : "not_exists",
58   "email" : "dude@salesforce.com",
59   ...
60}
61
62# when a customer with that ID already exists
63
64RESPONSE:
65HTTP/1.1 409 CONFLICT
66Content-Type: application/json;charset=UTF-8
67{
68  "_v" : "23.1",
69   "_type" : "fault",
70  "fault" : {
71    "type" : "ResourceAlreadyExistsException",
72    "message" : "Resource already exists, state is 'ab12cd34'."
73  }
74}

DID THIS ARTICLE SOLVE YOUR ISSUE?
Let us know so we can improve!