私は、多くの問題に苦しんでいる非常に不十分に設計されたソフトウェアプロジェクトへの変更を提案しています。高レベルでは、プロジェクトはフロントエンドでAngularを利用し、さまざまなREST APIsを使用します。これはすべて素晴らしいです(私は私たちのテクノロジーやツールを変更します。問題は、コードベースがサーバー側のAPIよりもUIで過度に大きいということです。ビジネスロジックの多くは、REST APIs UIレイヤーへのシンプルなCRUDデータベースインターフェイスです。
たとえば、POST to customerは顧客レコードを作成しますが、PUTはその顧客を変更します。それほど多くはなく、それほど少なくもありません。しかし、ビジネスロジックはそれよりも要求が厳しいです。顧客を作成する一般的なプロセスは、1つのデータベースレコードを挿入するだけではありません。他の必要なテーブルにデータをプロビジョニングし、特定の検証と計算などを実行します。この動作をすべてカプセル化する単一のPOST/PUT呼び出しを実行したいと思います。消費クライアントの負荷を軽減します。
したがって、私の見解では、この包括的なオーケストレーションはUIではなくサーバー(フルコントロール、ログなどがある)に存在する必要がありますが、反論の1つとして、このアプローチはRESTfulではなくなります。したがって、既存のテクノロジスタックを継続することをお勧めしますが、コードが属する場所に根本的なシフトを実装する場合、このアプローチを最もよく説明する方法はわかりません。
既存のテクノロジースタックを継続することをお勧めしますが、コードが属する場所に根本的なシフトを実装する場合、このアプローチを最もよく説明する方法はわかりません。
Service oriented architecture
。
ビジネスルールとデータが同じ場所にあるようにシステムを再設計することを提案しています。これは事実上、service;の定義です。 Udi Dahanの Finding Service Boundaries に関する講演をご覧ください。
補足:エリックが指摘したように、これは「REST」とは関係ありません。 REST API(つまり、 RESTアーキテクチャスタイル )の制約を満たすAPI)を前に置くことができないという理由は絶対にありません。ただし、RESTを理解して、データベース操作をHTTPメソッドにマッピングすることを意味する人にとっては、それは明らかではないかもしれません。
RESTに対する読者の理解を変えることに投資する価値があるかもしれませんし、そうでないかもしれません。
RESTはCRUDではありません。この「反論」は、RESTが何であるかという根本的な欠陥のある理解に基づいています。変更によってAPIが多少なりともRESTfulになることを示す投稿は見ていません。
もう1つ覚えておくべきことは次のとおりです。ビジネスルールのサーバー側を検証しないということは、たとえばPOSTリクエストを通じて有効であるということによって)入ってくるものを暗黙的に信頼することを意味します。
たとえば、angularアプリケーションは、顧客が有効な年齢層を持っているかどうかを確認し、正当なユーザーが正しいフィードバックを確実に得るようにする一方で、APIのURLを知っている人なら誰でも= POST検証されない正当でない値を含むリクエスト。
したがって、私の提案は、ビジネスルールをAPIに移動し、入力を検証して、応答の本文で適切なエラー(またはおそらく何が問題かを示すコード)を返すようにすることです。これらのコードをフロントエンドアプリケーションで使用して、問題の原因を示すことができます。
ここで他の良い答えに追加するには:
RESTまたはそれ以外の場合、インターフェイスは、実装の詳細に関するある種の仮定に基づいて制約されるべきではありません。これは、抽象化層としてのサービスの概念とは完全に相反します。
サービスを使用する主な利点の1つは、クライアントが何もしなくても実装の詳細を変更できることです。あなたが述べたことから、それは本当の抽象化層がないように聞こえます。実装の詳細はHTTP経由で公開されています。 RESTはそれが必要、役立つ、または望ましいと言っています。実際、 RESTの定義 の特定の部分を主張して、これが実際に、RESTfulでない実装。
あなたが提案しているのは、適切なサービス層をどのように設計すべきかということです。 RESTfulでないためにそれを行うことができないと誰かがあなたに言っているなら、それは残念です。 RESTについてほとんど何も知らない人に言われても安心です。
あなたの質問に基づいて、顧客というリソースがあります。有効な顧客リソースを作成するために必要なものはすべて、顧客ベースリソースへのPOST
で処理できます(存在しない場合は、代わりに/オプションで特定の顧客リソースへのPUTで処理します)。 RESTは、特定の呼び出しで作成する必要のあるデータベースレコードの数については何も述べていません。ColinYoungがコメントしたように、データベースはまったく必要ありません。サービスの実装方法はまったく関係ありません。 RESTの観点から。
ここには良い答えがいくつかありますが、同僚を説得するのに役立つかどうかはわかりません。多くの人が指摘しているように、あなたが提案しているのはRESTfulな設計からの転換ではありません。それが提案に参加するための鍵だと思います。
RESTは、APIがデータの保存と取得のみを許可することを確認することについてではありません。むしろ、アクションasリソースのモデリングに関係しています。 APIはアクションを実行できるようにする必要があります(結局のところ、これはアプリケーションプログラミングインターフェイスです)。問題は、これらのアクションをモデル化する方法です。
用語を考え出すよりも、例がおそらくこれを同僚に説明する最良の方法です。このようにして、彼らが現在どのように行っているか、どのような問題が発生しているのか、問題を解決するソリューション、そして依然としてRESTfulであり続ける方法を示すことができます。
Customerオブジェクトを見てみましょう。
問題:
UIはお客様をPOSTしますが、後続のテーブルはまだ更新されていません。 UIコードのエラー(またはブラウザープラグインの誤動作など)が原因で後続の呼び出しの1つが失敗した場合はどうなりますか?これで、データは不整合な状態になります。単に無効であることは言うまでもなく、APIまたはUIの他の部分を壊す状態である可能性さえあります。どのように回復しますか?これが何かを壊さないことを確認するために、可能なすべての状態をテストする必要がありますが、何が可能かを知るのは難しいでしょう。
ソリューション:
APIエンドポイントを作成して顧客を作成します。 createは動詞であり、RESTに違反するため、「/ customer/create」または「/ create-customer」エンドポイントも必要ないことがわかっています。だからそれを統一する。 「/ customer-creation」は機能します。 POST CustomerCreationオブジェクトの場合、顧客が完全に作成されるために必要なすべてのフィールドが送信されます。エンドポイントは、データが完全で有効であることを保証します(400または検証に失敗します)。たとえば、単一のdbトランザクション内ですべて持続する場合があります。
/ customerオブジェクトを取得するためのエンドポイントも必要な場合は問題ありません。あなたは両方を持つことができます。秘訣は、消費者のニーズを満たすエンドポイントを作成することです。
利点:
欠点:
人々がこのパラダイムを理解するのは難しいかもしれませんし、彼らがそれを試していなければ、それについて何が良いのかを理解するのは難しいかもしれません。うまくいけば、あなたはあなた自身のコードからの例を使用することによって彼らが見るのを助けることができます。
私自身の経験では、私のチームの開発者がこの戦略の実装を開始すると、ほとんどすぐにメリットがわかりました。
さらなる調査:
Thoughtworksのこの記事は、実際的な例を使用してアクションをオブジェクトとしてモデリングするというアイデアを得るのに本当に役立ちました https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling
CQRSとイベントソーシングもこの種の事柄(つまり、実際の永続化ロジックからAPIを分離する)に正確に関係しているため、それらを読むことをお勧めします。 。あなたの同僚がこの種のことをどの程度喜んで読むかはわかりませんが、それによってあなたはより明確になり、彼らにそれを説明するのを助けるかもしれません。