web-dev-qa-db-ja.com

URLマトリックスパラメーターとリクエストパラメーター

URLでマトリックスまたはクエリパラメーターを使用するかどうか疑問に思っています。古いトピック discussion が満足できないトピックを見つけました。

一見すると、マトリックスのパラメーターには利点しかありません。

  • より読みやすい
  • xMLドキュメントの「&」のエンコードとデコードは不要です
  • 「?」のあるURL多くの場合、キャッシュされません。行列パラメーターを持つURLはキャッシュされます
  • 行列パラメーターはパスのどこにでも表示でき、その終わりに限定されません
  • マトリックスパラメータには複数の値を指定できます:paramA=val1,val2

しかし、欠点もあります:

  • JAX-RS のような少数のフレームワークのみが行列パラメーターをサポートします
  • ブラウザーがGETを介してフォームを送信すると、パラメーターはクエリパラメーターになります。したがって、同じタスクの2種類のパラメーターになります。 RESTサービスのユーザーを混乱させず、サービスの開発者の労力を制限するには、この領域で常にクエリパラメータを使用する方が簡単です。

サービスの開発者は行列パラメーターをサポートするフレームワークを選択できるため、唯一残っている欠点は、ブラウザーがデフォルトでクエリパラメーターを作成することです。

他の欠点はありますか?あなたならどうしますか?

168
deamon

重要な違いは、マトリックスパラメーターが特定のパス要素に適用され、クエリパラメーターが要求全体に適用されることです。これは、複数レベルのリソースおよびサブリソースに対して複雑なRESTスタイルのクエリを作成するときに役立ちます。

http://example.com/res/categories;name=foo/objects;name=green/?page=1

それは本当に名前空間に帰着します。クエリパラメータのみを使用した場合、「category_name」や「object_name」などのパラメータになり、リクエスト内のパラメータの局所性によって追加された明瞭さが失われます。さらに、JAX-RSのようなフレームワークを使用すると、すべてのクエリパラメーターが各リソースハンドラー内に表示され、潜在的な競合と混乱につながります。

クエリに「レベル」が1つしかない場合、違いはあまり重要ではなく、2種類のパラメーターは事実上交換可能ですが、クエリパラメーターは一般にサポートが向上し、広く認識されています。一般に、HTMLフォームや単純な単一レベルのHTTP APIなどのクエリパラメータを使用することをお勧めします。

201
Tim Sylvester

-コメントセクションに委ねるにはあまりにも重要です-

マトリックスURLの重要性はわかりません。 TBLが書いたw3cのデザイン記事によると、これは単なるデザインのアイデアであり、Webの機能ではないと明示的に述べています。相対URLなどは、使用時に実装されません。あなたがそれを使いたいなら、それは問題ありません。標準ではないため、標準的な使用方法はありません。 –スティーブポメロイ

簡単に言えば、ビジネス目的でRSが必要な場合は、リクエストパラメータを使用するほうが良いでしょう。

10
Ajeet Ganga

Tim Sylvester's answerに加えて、JAX-RSを使用してマトリックスパラメーターを処理する方法の例を示します。

  1. 最後のリソース要素のマトリックスパラメーター

    http://localhost:8080/res/categories/objects;name=green
    

    @MatrixParam アノテーションを使用してそれらにアクセスできます

    @GET
    @Path("categories/objects")
    public String objects(@MatrixParam("name") String objectName) {
      return objectName;
    }
    

    Response

    green
    

    しかし、Javadocの状態のように

    @MatrixParam注釈値は、マトリックスパラメーターの値を注入するPath注釈付きJava構造体の最後に一致したパスセグメントにあるマトリックスパラメーターの名前を参照することに注意してください。 。

    ...ポイント2に至った理由

  2. RLの途中のマトリックスパラメーター

    http://localhost:8080/res/categories;name=foo/objects;name=green
    

    パス変数と@PathParamPathSegment を使用して、どこからでもマトリックスパラメーターにアクセスできます。

    @GET
    @Path("{categoryVar:categories}/objects")
    public String objectsByCategory(@PathParam("categoryVar") PathSegment categorySegment, 
                                    @MatrixParam("name") String objectName) {
      MultivaluedMap<String, String> matrixParameters = categorySegment.getMatrixParameters();
      String categorySegmentPath = categorySegment.getPath();
      String string = String.format("object %s, path:%s, matrixParams:%s%n", objectName,
              categorySegmentPath, matrixParameters);
      return string;
    }
    

    Response

    object green, path:categories, matrixParams:[name=foo]
    

    マトリックスパラメーターは MultivaluedMap として提供されるため、それぞれにアクセスできます。

    List<String> names = matrixParameters.get("name");
    

    または、最初のものだけが必要な場合

    String name = matrixParameters.getFirst("name");
    
  3. すべてのマトリックスパラメーターを1つのメソッドパラメーターとして取得

    http://localhost:8080/res/categories;name=foo/objects;name=green//attributes;name=size
    

    List<PathSegment>を使用してそれらをすべて取得します

    @GET
    @Path("all/{var:.+}")
    public String allSegments(@PathParam("var") List<PathSegment> pathSegments) {
      StringBuilder sb =  new StringBuilder();
    
      for (PathSegment pathSegment : pathSegments) {
        sb.append("path: ");
        sb.append(pathSegment.getPath());
        sb.append(", matrix parameters ");
        sb.append(pathSegment.getMatrixParameters());
        sb.append("<br/>");
      }
    
      return sb.toString();
    }
    

    Response

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]
    
8
René Link