多くのパラメーターを使用したREST API呼び出しのベストプラクティス


11

パラメーターの(長い)リスト(たとえば、8つのパラメーター)を受け取るGET操作を備えたREST APIがあります。この操作の目的は、要素を検索してフィルタリングすることです。

このシナリオを管理するためのベストプラクティスはどれですか。:

(1)パラメータのリスト受け取りますか?:

public ResultType Get(int p1, int p2, string p3...) { ... }

(2)または、これらのパラメーターをカプセル化するオブジェクトを受け取りますか?:

public class MyClass
{
    public int X { get; set; }
    public int Y { get; set; }
    public string Z { get; set; }
}

public ResultType Get(MyClass parameter) { ... }

名前、説明、カテゴリ、ブランド、モデル、価格などで「製品」を検索およびフィルタリングするeコマースシナリオを考えてみてください。


1
位置は、値の適切な名前よりも識別子の方が小さいです。
SD

なぜ8つのパラメーターがあるのですか?彼らは何をしますか?いくつかの決定ロジックが含まれていますか(混乱していますか?)そのAPI /メソッドを3つまたは4つのパラメーターを取るいくつかのメソッドに分割できますか?
FilipMilovanović18年

1
8つのパラメーターは単なる例です。Get操作は「検索」メソッドです。名前、説明、カテゴリ、ブランド、モデル、価格などで「製品」を検索およびフィルタリングするeコマースのシナリオを考えてみてください。質問を編集してコンテキストを追加しました
Jose Alonso Monge

回答:


10

>パラメータの(長い)リストを受け取るGET操作を備えたREST APIがあります。このシナリオを管理するためのベストプラクティスはどれですか。

AFAIK、しっかりと確立されたベストプラクティスはありません(申し訳ありません)。ただし、いくつかの推奨事項があります。

  • リクエストが安全な場合(つまり、副作用がなく、特にデータを変更しない場合)は(の代わりに)使用POSTないようにしてください。パラメータが非常に大きい場合は、長さの制限を回避するために使用する必要がある場合がありますが、通常これは問題ではなく(ほとんどのソフトウェアは非常に長いURLをサポートします)、安全な要求を使用して、キャッシュやプリフェッチなどの最適化を許可する必要があります。GETPOSTGET

  • を使用する場合はGET、パラメーターをURLパラメーターとして送信する必要があります1)。そのような状況では、自然で一般的な解決策は、パラメーターのリストを使用することです。そのため、これをお勧めします。はい、リストは長くなりますが、REST APIは(おそらく)プログラムでの使用を目的としているため、この問題は発生しません。APIのユーザーは、独自のコード内のオブジェクトのパラメーターを自由にカプセル化できます。

  • 技術的には、オブジェクトをURLパラメーター(JSON、XMLなど)に入れることもできますが、それは珍しいので、可能であれば避けま​​す。

1)厳密に言えば、GETリクエストでボディを使用できますが、これは一般的ではなく、一般的には推奨されません。たとえば、リクエストボディを伴うHTTP GETを参照してください。


最後に、長いパラメーターリストを持つソースコードのメソッドと同様に、REST APIにリファクタリングが必要かどうかを検討する必要があります。ソースコードと同様に、このような長いパラメーターリストは、APIエンドポイントがさまざまなことを実行していることを示します。それを分割したり、デフォルト設定を提供したりするのは理にかなっていますか?しかし、それは別の質問です...


技術的には、GETでボディを送信することもできますが、珍しいことです
Ewan

また、あなたがべき等であることを確信していますか?私は 'キャッシュ可能' GetTodaysDayName()はべき等と見なされるかもしれませんが、それをキャッシュしたくないでしょう
Ewan

GET vs POSTの戦いを始めましょう!!!! :)
ユアン

@Ewan:GetTodaysDayNameのキャッシュに関して:今日の名前が1秒間に10回必要であり、数秒間間違った日を使用する必要がないと仮定すると、おそらくキャッシュする必要があります。それでも、私は誤って「べき等」を使用しましたが、私が頭に浮かんだのは「安全」(=変更しない)でした。編集。
sleske 2018

1
「対戦相手」がお互いの反応を豊かにする@Ewan建設的な戦いは歓迎以上のものです。すべてのオプションについて非常に包括的な概要を提供してくれた2人に感謝します。
クリストフ

3

ベストプラクティスは、パラメーターをオブジェクトとしてPOSTすることです。

これにより、URLの長さの制限やクエリ文字列に関するその他の問題を回避できます。JSONで複数のパラメーターを送信する場合、オブジェクトはそれを行うための標準的な方法であるため、1つにデシリアライズすることは理にかなっています。

必要に応じて動的オブジェクトに逆シリアル化することで、コントローラーでのみ使用されるランダムな「リクエスト」オブジェクトの作成を回避できます。後で正しいタイプにキャストすることも同様に面倒です。

昔は、コントローラーアクションの複数のパラメーターを受信JSONオブジェクトのフィールドに自動的にバインドすることができました。しかし、これは.netコアではそのままでは機能しません。

これがありますが、試してみたくなるかもしれませんが

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/application-model?view=aspnetcore-2.1#application-model-usage-in-webapicompatshim

編集:GETの使用についていくつかの点を追加するだけです

  • キャッシュ:GETは、HTTP仕様に従うクライアントによってキャッシュされます。ただし、この仕様はウェブページの読み込みを高速化するように設計されています。キャッシュは、API結果にWebページと同じキャッシュ要件がある場合に役立ちますが、そうでない場合は役に立ちません。必要に応じて、クライアントに独自のPOST応答のキャッシュを追加できます。

  • URLの長さ:これは主に、配列を送信するときの問題です。明らかに、配列は非常に長くなる可能性があり、クエリ文字列パラメーター名はアイテムごとに繰り返されます。ただし、1つの文字列のみを送信する場合でも、技術的にはその文字列は非常に長くなる可能性があります。

  • ロギング:デフォルトでは、多くのWebサーバーがクエリ文字列全体を記録します。多くの場合、パラメーターデータがプレーンテキストのログに記録されることを望まない場合があります。

  • GET with body:これは完璧な答えのように思われ、REST純粋主義者を満足させながら素敵なデータ構造を可能にしますが、それは珍しく眉をひそめています。POSTは本文を送信する標準的な方法です。


2
これは合意されたベストプラクティスではないと思います。特に、リクエストがべき等である場合、(キャッシュ可能性などのために)使用GETせずに使用することベストプラクティスPUTです。また、URLの長さの制限は最近非常に大きくなっているため、必ずしも問題ではありません。
sleske 2018

@sleske GETの方が優れていると思う場合は、その理由について回答を書いてください。ただし、文字列zは4Mbの長さにすることができます
Ewan

実際にグーグルするだけで、jsonの最大文字列長が不確かに見える
Ewan

文脈を考えると、リクエストパラメータを持ってする必要はありませんではない -あなたのログには、あなたがしたくない場合を除き、分析を、人々があなたのページに後を求めたものに)GET2つの観点から完全に理にかなって:)分析、およびb)Aユーザーはクエリを後で保存したり、共有したりできます。
トーマスジャンク

@ThomasJunkどんなコンテキストを参照していますか?文字列は「z」と呼ばれ、文字列には何でも含めることができます。GDPRの罰金2,000万ドルは?
ユアン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.