RESTの標準を意図的に破るアーキテクチャの変化をどのように説明しますか?


37

私は、多くの問題に苦しんでいる非常に貧弱に設計されたソフトウェアプロジェクトへの変更を提案しています。高レベルでは、プロジェクトはフロントエンドでAngularを利用し、さまざまなREST APIを使用します。それはすべて素晴らしいことです(私たちの技術やツールを変更する必要はありません)。問題は、コードベースがUIでサーバー側のAPIよりも不均衡に大きいことです。ビジネスロジックの多くはUIに存在し、REST APIはUIレイヤーへの単純なCRUDデータベースインターフェイスです。

たとえば、顧客へのPOSTは顧客レコードを作成し、PUTはその顧客を変更します。それ以上でもそれ以下でもありません。ただし、ビジネスロジックはそれよりも要求が厳しくなります。顧客を作成する一般的なプロセスは、1つのデータベースレコードを挿入するだけではありません。他の必要なテーブルにデータをプロビジョニングし、特定の検証と計算などを実行します。この動作のすべてをカプセル化する単一のPOST / PUT呼び出しを行い、消費クライアントの負荷を軽減します。

したがって、私の視点では、この包括的なオーケストレーションはUIではなくサーバー(フルコントロール、ログなど)上に存在する必要がありますが、1つの反論は、このアプローチはRESTfulではなくなるということです。したがって、既存の技術スタックを継続することを推奨するが、コードが属する場所で基本的なシフトを実装することが推奨される場合、このアプローチをどのように説明するのが最適かはわかりません。


44
APIをCRUDに限定することは、「RESTful」にするための呼び出しであり、トレードオフとしては不十分です。
ロバートハーベイ

38
@EsbenSkovPedersen:永遠の親友?
ロバートハーヴェイ

5
サービスがRESTに準拠しているかどうかを心配する代わりに(iirc、ほとんどなし)、HTTP仕様に準拠することをもっと心配します。私が使ったほとんどのAPIも仕様に準拠していませんが、より達成可能で価値のある目標imoです。
aaaaaa

7
@ aaaaaa、RESTに準拠するサービスがほとんどない理由は、RESTが何であるかを誰も決定できないためです。私が見つけた唯一の合意点は、「他の誰もが間違っている」ことです。
マーク

16
-「REST標準を意図的に破るアーキテクチャシフトの記述方法」- disRESTpect。(プロのコメントは申し訳ありませんが、私よりも強かった。
luk32

回答:


49

既存のテクノロジスタックを継続することが推奨される場合、このアプローチをどのように説明するのが最適かはわかりませんが、コードが属する場所に根本的なシフトを実装します。

Service oriented architecture

ビジネスルールとデータが同じ場所にあるようにシステムを再設計することを提案しています。これは事実上、サービスの定義です。サービス境界の検索に関するUdi Dahanの講演をご覧ください。

補足:Ericが述べたように、これは「REST」とは関係ありません。サービスの前にREST API(つまり、RESTアーキテクチャスタイルの制約を満たすAPI)を配置できない理由はまったくありません。しかし、RESTを理解している人にとって、データベース操作のHTTPメソッドへのマッピングを意味することは明らかではないかもしれません。

視聴者のRESTに対する理解を変えることに投資する価値があるかもしれませんし、そうでないかもしれません。


32
また、RESTに投資する価値もまったくありません。ロイ・フィールディングの論文(または私が妻にRESTを説明した方法)を読んだ場合、RESTの真の目的は、インターネット上のリソースの標準的な表現提供することです。 。 個人所有のアプリケーションには、この機能さえ必要ないかもしれません。
ロバートハーベイ

29

RESTはCRUDではありません。その「反論」は、RESTが何であるかという根本的に欠陥のある理解に基づいています。あなたの変更があなたのAPIを多かれ少なかれRESTfulにすることを示すものはあなたの投稿には見ていません。


6
まあ、いや、それはCRUDへの完全なマッピングではありませんが、少なくともほとんどの人が解釈する方法では、CRUDのように歩き、話し、歌います。
ロバートハーベイ

11
@RobertHarvey私はそれがここでの問題であると(誤)理解していると思います。
ジミージェームズ

4
@JimmyJames:誤解が広まっています。ほとんどの人が利点が何であるか、またはそれらの利点が彼らにどのように適用されるかさえ理解していないとき、物事を「安らかにする」という強い意欲があります。
ロバートハーベイ

4
@RobertHarvey間違った方法でRESTを実行する場合、RESTを目標にすべきではないと言っていると思います。わかりましたが、これを「RESTではない」と呼ぶ方法はでたらめであり、私はでたらめ者にでたらめを呼ぶことの大きな支持者です。 単語は有用であるために一般的に理解されている意味を必要とします。
ジミージェームズ

5
@RobertHarvey承認されましたが、用語のこれらの誤用を修正してくれる十分な人がいる限り、それは起こりません。私はタオルを投げる準備ができていません。
ジミージェームズ

24

覚えておくべきもう1つのことは次のとおりです。ビジネスルールのサーバー側を検証しないということは、POST要求などによって着信したものが有効であることを暗黙的に信頼することを意味します。

つまり、たとえば、角度アプリケーションが顧客に有効な年齢範囲があるかどうかを確認し、正当なユーザーが正しいフィードバックを取得できるようにする一方で、apiのURLを知っている人はだれでも非正当な値を含むPOSTリクエストを実行できます検証されなくなりました。

したがって、私の提案は、ビジネスルールをAPIに移動し、入力を検証し、応答の本文に適切なエラー(または単に問題を示すコードだけ)を返すことです。これらのコードをフロントエンドアプリケーションで使用して、問題の原因を示すことができます。


5
これはここで最も有用な答えです:APIは攻撃面であり、クライアントへの入力ではありません。すべてのAPIリクエストはなりすましが可能です。したがって、純粋なAPIでできることは、才能のない悪意のあるスクリプトキディができることです。クライアントソフトウェアを使用してユーザーエクスペリエンスを向上させることもできますが、ルールを実施する必要があるのはサーバーです。
cmaster

10

ここに他の良い答えを追加するには:

実装の詳細に関する何らかの仮定に基づいて、RESTまたはそれ以外のインターフェースを制約すべきではありません。これは、抽象化層としてのサービスの概念とは完全に相反しています。

サービスを使用する主な利点の1つは、クライアントが何もしなくても実装の詳細を変更できることです。あなたが説明したことから、それは本当の抽象化層がないように聞こえます。実装の詳細は、HTTPを介して公開されています。RESTについて、それが必要、有用、または望ましいということはありません。実際、REST定義の特定の部分が、これが実際には非RESTful実装であることを意味すると主張できると思います。

あなたが提案しているのは、適切なサービス層の設計方法です。RESTfulではないため、できないと誰かから言われた場合、それは残念です。あなたは、RESTについてほとんど何も知らないことをあなたに伝える誰かを安心させることができます。

質問に基づいて、顧客というリソースがあります。有効な顧客リソースを作成するために必要なものはすべてPOST、顧客ベースリソース(または、存在しない場合は特定の顧客リソースへのPUTで代替/オプション)で処理できます。特定の呼び出しで作成する必要があるデータベースレコード。Colin Youngがコメントしたように、データベースはまったく必要ありません。RESTの観点からサービスを実装する方法はまったく関係ありません。


3
RESTは、データベースレコードについては何も言っていません。水バルブを制御し、水バルブ、水供給、およびタンクレベルのリソースを公開するRESTサービスを作成できます。物理オブジェクト自体は「データベース」であると主張することできますが、それは少し物事を伸ばしています。
コリンヤング

@ColinYoungはい、わかりやすくしてくれてありがとう。
ジミージェームズ

3

ここには良い答えがいくつかありますが、彼らがあなたの同僚を説得するのに役立つかどうかはわかりません。多くの人が指摘しているように、あなたが提案しているのはRESTfulなデザインからの移行ではありません。それがあなたの提案でそれらを採用するための鍵だと思います。

RESTは、APIがデータの保存と取得のみを許可するようにすることではありません。むしろ、アクションリソースとしてモデル化することに関係しています。API 、実行されるアクションを有効にする必要があります(結局、これはアプリケーションプログラミングインターフェイスです)。問題はこれらのアクションをモデル化する方法です。

用語を考え出すよりも、例がおそらく同僚にこれを説明するための最良の方法です。このようにして、彼らが今どのようにそれを行っているのか、これがどのような問題を引き起こすのか、問題を解決するソリューション、そしてそれがどのようにRESTfulのままであるかを示すことができます。

Customerオブジェクトを見てみましょう。

問題:

UIは顧客をPOSTしますが、後続のテーブルはまだ更新されていません。UIコードのエラー(またはブラウザープラグインの誤動作など)のため、後続の呼び出しの1つが失敗した場合はどうなりますか?これで、データは一貫性のない状態になりました。単に無効であることは言うまでもなく、APIまたはUIの他の部分を壊す状態になることさえあります。どのように回復しますか?これが何かを壊さないことを確認するために、可能性のあるすべての状態をテストする必要がありますが、何が可能かを知るのは難しいでしょう。

溶液:

APIエンドポイントを作成して顧客を作成します。createは動詞であり、RESTに違反するため、「/ customer / create」または「/ create-customer」エンドポイントを持ちたくないことを知っています。だからそれを名詞化します。「/ customer-creation」は機能します。これで、CustomerCreationオブジェクトをPOSTすると、顧客が完全に作成されるために必要なすべてのフィールドが送信されます。エンドポイントは、データが完全で有効であることを確認し(検証に失敗した場合は400または何かを返します)、たとえば、すべてが単一のdbトランザクション内に保持される場合があります。

/ customerオブジェクトを取得するエンドポイントも必要な場合は、それで問題ありません。両方持つことができます。秘trickは、消費者のニーズを満たすエンドポイントを作成することです。

利点:

  1. 悪い状態に陥らないことを保証します
  2. UIの開発者は、リクエストの順序、検証の問題などを「知る」必要がない場合、実際には簡単です。
  3. APIほどおしゃべりではないので、ネットワークリクエストの待ち時間が短縮されます。
  4. シナリオをテストおよび概念化するのが簡単です(UIからのデータの欠落/不正な部分はリクエスト全体に分散されず、一部は失敗する可能性があります)
  5. ビジネスロジックのカプセル化を改善します。
  6. 一般に、セキュリティが簡単になります(UIのビジネスおよびオーケストレーションロジックはユーザーが変更できるため)
  7. ロジックの重複を減らす可能性があります(同じデータへのアクセスを提供する2+ APIよりも、APIの消費者が2+多い可能性が高くなります)
  8. まだ100%RESTful

短所:

  1. バックエンド開発者にとっては潜在的にはより多くの作業です(ただし、長期的にはそうではないかもしれません)

人々がこのパラダイムを理解するのは難しいかもしれませんし、彼らがそれを試していないなら、それについて何が良いのかもしれません。あなた自身のコードの例を使用することで、彼らが見やすくなることを願っています。

私自身の経験では、私のチームの開発者がこの戦略の実装を開始すると、ほとんどすぐに利点を目にしました。

さらなる研究:

thoughtworksのこの記事は、実際の例を使用してオブジェクトとしてアクションをモデル化するアイデアを得るのに非常に役立ちました:https ://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling

また、CQRSとイベントソーシングを参照することもお勧めします。これらは、この種の問題に正確に関係しているためです(つまり、実際の永続ロジックからAPI を切り離す)。同僚がこの種のことをどのように読んでくれるのかわからないが、それはあなたにもっと明快さを与え、あなたにそれを説明するのを助けるかもしれない。


createは動詞であり、RESTに違反するため」-まったく正しい。つまり、「RPC over REST」を実行するのは47.258.346番目のアプローチになります。これは少なくとも「不自然」だと思うものです。RESTfulアプローチを誤用し、誤って伝えているためです(ユースケースはありますが、RPCはそれらの1つではありません)。
JensG
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.