web-dev-qa-db-ja.com

単一のエンドポイントを使用して複数の同様のタスクを実行することは悪い習慣ですか?

したがって、シナリオは、REST APIを、同様のタスクを実行する複数のエンドポイントを組み合わせることによって再設計およびリファクタリングすることを求められています。

たとえば、10個の異なるエンドポイントがあり、それらはすべて異なるリソースをアップロードするために使用されます。ファイルのアップロード先は、POSTリクエスト本文のfile-typeパラメーターによって決定されます。

これは、単一の責任の原則に対する明確な違反のように感じられるので、複数のアップロードエンドポイントを単一のアップロードエンドポイントに結合することが悪い習慣であるかどうかを尋ねます。

また、それが悪い習慣である場合、エンドポイントの数を減らすことができる代替策のいくつかは何ですか?

9
lincredibleJC

ある時点で、関数を設計するとき、それらがAPIエンドポイント、ライブラリメソッドなどであっても、「単一の責任」が何であるかを決定する必要があります。この種のことについて、決定的なベストプラクティスはありません。すべての選択にはトレードオフがあります。

各エンドポイント間で機能はどのように異なりますか?多くの機能を共有している場合、それらは同じ責任の一部であることは理にかなっています。

基本的な算術を例にとってみましょう。加算、減算、乗算、および除算。私の唯一の目標がエンドポイントの数を減らすことだった場合は、次のようにします。

doMath(string operator, string... operands)

しかし、そのエンドポイントはいくつかのフラグを立てる必要があります。それは非常にあいまいで説明的ではありません。あまり理想的ではありません。正確で更新されたドキュメントがなければ、この関数/エンドポイントの使用を開始することすらできません。私も完全に反対の方向に行くことができ、パラメータを完全に回避できます:

add5and5()
add10and5()
multiple4and8()
...

これがほとんど意味をなさないか、まったく意味がない理由は明らかです。明らかに、ある種の中間基盤が必要です。

add(int op1, int op2)
subtract(int op1, int op2)
multiply(int op1, int op2)
divide(int op1, int op2)

現在、悪い解決策ではありません。しかし、4つのエンドポイントが1つよりも優れているのはなぜですか?ええと、基本的な計算を行うだけで済みます。したがって、APIが後で大きく膨らむことはないと確信できます。ただし、文字通りあらゆる種類の数学を実行するAPIがある場合、基本的な演算を単一のエンドポイントまたは関数にグループ化することは実際には理にかなっています。

同様に、「アップロード」エンドポイントをさらに追加することを計画している場合、それらを組み合わせない限り、APIは少し肥大化し始めます。もちろん、APIがどれほど肥大化するかは、あなたとあなたのユースケース次第です。それを理解するために、クライアントがAPIをどのように使用するかを理解します。

これらの質問を自問してください:

  • これらのエンドポイントは多くの機能を共有していますか?
  • APIに「アップロード」機能を追加する必要がある可能性は高いですか?
  • APIはアップロード以上のことをしますか?
  • 将来エンドポイントのシグネチャを変更した場合、コンシューマーで大幅なリファクタリングが必要になりますか?

これらの質問で「はい」と言えるほど、機能をパラメーターにオフロードしてエンドポイントの数を減らすことで、より多くの利益を得ることができます。

13
Clay07g

@ Hans-MartinMosnerに同意します。残りの方法は、POSTまたは/api/script/api/soundなどの論理リソースにPUTすることです。

データ(別名ファイル)が異なるという事実は、論理リソース名によってモデル化されます。次に、そのタイプに固有のパラメーター、またはすべてのリソースタイプに適用可能なパラメーターを使用できます。

その後、より具体的であるが多くの類似パラメーターを共有する多くのサブリソースタイプの多くのバリエーションをカバーする多くのオプションパラメーターを持つエンドポイントがあるかどうかは、判断の問題です。

この Tweetシリーズ は、メソッドを分割するタイミングについて興味深い見解を持っています。

[変数が宣言されている場合]宣言すると、すぐにifにヒットします。両方のブランチで設定されているため、これはifが抽出可能なメソッドであるという強力な手がかりです。

これを一般化して、オプションのパラメーターがあり、すぐにcaseステートメントがある場合、または早期に2つのパスを持つifステートメントが戻る場合は、2つのエンドポイントにすることを検討する必要があることを強く示します。しかし、それが純粋に内部実装の詳細である場合は、APIを使用するクライアントにとって明確ではなく、どちらを使用するかを理解するために両方のメソッドのドキュメントを読まなければならないため、そのようなことはしたくないでしょう。

1
simbo1905