web-dev-qa-db-ja.com

RESTfulアプリケーションロジックとリソース間操作

ユーザーが自分のビジネスに関する問い合わせを受け取れるようにするRESTful APIを持っています。 '日付yにサービスxを予約したいと思います。これは利用できますか?」 APIは、この情報をリソースとして次のURIに保存します

users/{userId}/enquiries/{enquiryId}

このリソースが取得されたときに表示される情報は、問い合わせから期待される標準的な種類のものです-電子メール、名、姓、住所、メッセージ

このAPIでは、ユーザー用に顧客を作成することもできます。顧客はログインとパスワード、そしてプロファイルも持っています。次のURIは、これら2つのリソースを公開します

PUT users/{userId}/customers/{customerId}
PUT users/{userId}/customers/{customerId}/profile

私が抱えている問題は、ユーザーが問い合わせから顧客を作成できるようにしたいということです。たとえば、ユーザーは要求された日にサービスを提供でき、その後、ログインの詳細などを顧客に設定して、残りのプロセスを管理できるようにします。

明白な答えは、次のようなURIを使用することです。

 users/{userId}/enquiries/{enquiryId}/convert-to-client

これの問題は、REST(具体的には、URIがリソースを指す必要があることを示唆する本Restful Web Servicesから)リソースの操作ではありません)。

他のオプションは、クライアントアプリケーション(つまり、APIを呼び出すコード)がこのアプリケーションロジックの一部を処理するようにすることです。これは私にはまったく適切ではないと感じています。私は自分のデザインに、クライアントアプリがかなり馬鹿げていることを実装しました。 APIからの結果を表示するのに十分な知識があり、アプリケーションロジックは含まれていません。

これを設定するための最良の方法について、他の意見を聞いていただければ幸いです

クライアントアプリにアプリケーションロジックがないのは間違っていますか? REST apiで純粋にこの操作を実行するにはどうすればよいですか?

4
Gaz_Edge

highlyは、 RESTful Webサービス 、特にRESTfulスタイルとRPCスタイルのWebプログラミングの違いに関する章を読むことをお勧めします。そして、リソースの発見と「動詞」の明らかな必要性に対処する方法に関する章(それらは通常、変装した別のリソースです)。

問い合わせを顧客に変換するのに「変換」動詞は必要ありません。顧客を作成したからといって照会を削除するのではなく、照会からの情報を入力として顧客を作成するだけです。

POST /users/{userId}/customers?enquiry={EnguiryId}

または単に

POST /users/{userId}/customers

リクエスト本文に問い合わせ情報があります。

ちなみに、私は顧客に対してPOSTを使用します。これは、サーバーアプリケーションが識別子の生成を制御している場合にそれを行う方法だからです。呼び出し元が1つである場合にのみ、PUTを使用してリソースを作成します。識別子を決定します。

余談ですが、URIに/ users/{UserId}を含めることに関連するセキュリティとプライバシーの問題を検討しましたか?これで、誰でもさまざまなユーザーIDを試し始めて、アプリケーションのさまざまなユーザーの情報を取得できます。それらをURIから除外し、各要求で送信する必要がある(場合によっては各応答で更新する)認証情報によって決定することを検討する必要があります。

5
Marjan Venema

あなたが与えた例を考慮に入れると、私はそれについて全く異なった見方をしています。他の答えは正しいですが、これは間違った出発点から来ていると思います。

実際、問い合わせは顧客からのものです。顧客は複数の問い合わせを受ける可能性がありますか?

変換ステップが必要になると、多くの場合、2つのリソースがほぼ等しくなります。

最初はリソースCustomerしかありません。そのリソースには、クライアントに関するすべての情報(email、first_name、last_name、address)が含まれています。

現在のステータス:問い合わせのない顧客。これがリードです(そのステータスにブールフィールドを追加できます)

次に、2つのことを定義できます。顧客にメッセージのあるフィールドを与えることができます(最初の連絡先またはそのフィールドを呼び出すことができます)。

今のステータス:メッセージのあるお客様がいるので、それらを除外して回答を開始できます

または、顧客を作成して照会します。したがって、最初に顧客を作成し、次に問い合わせます。これはクライアントが行うことができます。照会を作成するためにClientIdを必要とします。

オプションのフィールド(顧客の住所フィールド)を使用して新しい照会を作成できるようにすることで、これら2つのステップを1つで行うこともできます。それは一度に両方のステップを踏むことができます。あまり単純ではなく、結局は利点がほとんどないために複雑さが増すため、特に好きではありません。

現在のステータス:関連する問い合わせのあるお客様がいます。

これで、データベースに必要以上の顧客ができました。そこで、それらをフィルタリングして、クライアントの適切なリストを取得できます。同じデータなので、同じリソースに属していると思います。

2
Luc Franken

これの問題は、REST(具体的には、URIがリソースを指す必要があることを示唆する本Restful Web Servicesから)リソースの操作ではありません)。

これは正しいです。質問で提案した次の操作は、SOAPサービスにのみ適しています。RESTは、サービスをサービスとして宣言しないことをお勧めしますHTTPプロトコルは、GET、POST、PUT、DELETEなどを使用してリソースに対する操作を定義します。

になるRESTリソースでHTTP操作を実行し、これの結果がRepresentationを返すResource(Get it?Representational State Transfer)クライアントが照会を取得したい場合は、そのリソースの表現を変更し、そのデータをサーバーに返送する必要があります。これの実装について懸念があるかもしれませんがクライアント上のデータの変更。これは本質的に、RESTによって定義された制約に反するものではありません。

出典:ウィキペディア:Representational State Transfer-制約

コードオンデマンド(オプション)サーバーは、実行可能コードを転送することにより、クライアントの機能を一時的に拡張またはカスタマイズできます。この例には、Javaアプレットなどのコンパイル済みコンポーネントや、JavaScriptなどのクライアント側スクリプトが含まれる場合があります。

適切なオブジェクト指向の方法で実装されたJSONオブジェクトが、クライアントに変換するためにサーバーにポストバックできる状態でデータを変換する方法についてスクリプトの動作を定義していると想定することは、完全に許容できます。この機能は、複雑である必要はないかもしれません。おそらく、JSONオブジェクト自体のプロパティでさえ、サーバーがPOSTを返すと、変換されると理解します。

キャッチは、このリソースの表現が変更されることであり、これはサービスのクライアントに明確に伝達または文書化する必要があります。

0
maple_shaft