ROA(リソース指向アーキテクチャ)を利用したRESTfulWebサービスを設計しています。
サーバーがリソースキーを指定した場合に、新しいリソースを作成するPUT要求のべき等性を保証する効率的な方法を見つけようとしています。
私の理解では、従来のアプローチは/CREATE_PERSONなどのタイプのトランザクションリソースを作成することです。新しい個人リソースを作成するためのクライアント/サーバーの相互作用は、次の2つの部分になります。
ステップ1:新しいPERSONリソースを作成するための一意のトランザクションIDを取得します:::
**Client request:**
POST /CREATE_PERSON
**Server response:**
200 OK
transaction-id:"as8yfasiob"
ステップ2:トランザクションIDを使用して一意であることが保証されているリクエストに新しい個人リソースを作成します:::
**Client request**
PUT /CREATE_PERSON/{transaction_id}
first_name="Big bubba"
**Server response**
201 Created // (If the request is a duplicate, it would send this
PersonKey="398u4nsdf" // same response without creating a new resource. It
// would perhaps send an error response if the was used
// on a transaction id non-duplicate request, but I have
// control over the client, so I can guarantee that this
// won't happen)
このアプローチで私が目にする問題は、新しいPERSONリソースを作成する単一の操作を実行するために、サーバーに2つの要求を送信する必要があることです。これによりパフォーマンスの問題が発生し、ユーザーがクライアントがリクエストを完了するのを待つ可能性が高くなります。
リクエストごとにtransaction-idを事前送信するなど、最初のステップを排除するためのアイデアをハッシュ化しようとしていますが、私のアイデアのほとんどには他の問題があるか、アプリケーションのステートレス性を犠牲にする必要があります。
これを行う方法はありますか?
編集::::::
最終的に解決したのは、クライアントがUUIDを取得し、それをリクエストと一緒に送信することでした。UUIDは、16バイト(2 ^ 128)のスペースを占める非常に大きな数です。プログラミングマインドを持っている人が直感的に考えるかもしれないこととは反対に、UUIDをランダムに生成し、それが一意の値であると想定することは一般的に受け入れられています。これは、可能な値の数が非常に多いため、同じ数の2つをランダムに生成する確率が十分に低く、事実上不可能であるためです。
注意点の1つは、クライアントがサーバーにUUIDを要求するようにしていることです(GET uuid/
)。これは、クライアントが実行されている環境を保証できないためです。クライアントに乱数ジェネレーターをシードするなどの問題が発生した場合は、UUIDの衝突が発生する可能性があります。