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


176

私のURLでマトリックスまたはクエリパラメーターを使用するかどうか疑問に思っています。そのトピックについての古い議論は満足のいくものではなかった。

一見すると、マトリックスparamsには利点しかないようです。

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

ただし、欠点もあります。

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

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

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


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

2
@Steve Pomeroy:これはあなたが言及した記事です:w3.org/DesignIssues/MatrixURIs.html
Marcel

3
@マルセル:うん。マトリックスURLについて考える場合は、ドキュメントの上部にある「ステータス:個人用ビュー」に注意してください。
スティーブポメロイ2012

行列パラメーターは複数の値を持つことができますか?本当に?
Ayyash、

回答:


212

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

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

それは本当に名前空間に帰着します。

注:ここでのリソースの「レベル」はcategoriesおよびobjectsです。

クエリパラメータのみがマルチレベルURLに使用された場合、次のようになります。

http://example.com/res?categories_name=foo&objects_name=green&page=1

このようにすると、リクエスト内のパラメーターの局所性によって追加された明瞭さが失われます。さらに、JAX-RSなどのフレームワークを使用すると、すべてのクエリパラメータが各リソースハンドラ内に表示されるため、競合や混乱が発生する可能性があります。

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


2
無関係:/?リソースを表す部分はありますか?
Jin Kwon、

7
?リクエストのクエリパラメータの一部を開始します。クエリパラメータは、マトリックスパラメータとは対照的に、最も一般的なタイプのURLパラメータです。疑問符の前のスラッシュは、クエリパラメータpageがスラッシュの前のマトリックスパラメータに実行されないようにします。添付何行列パラメータがなかった場合、私は考えますcategories:クエリパラメータは、このようなスラッシュなしで接続でき、http://example.com/res/categories?page=1
テームLeisti

8
マトリックスパラメータは任意のパスセグメントで指定できることは事実ですが、たとえばJAX-RSは、@ MatrixParamを挿入するときに追加されたパスセグメントにそれらを関連付けません。「Restful Java with JAX-RS 2.0」によると、「GET / mercedes / e55; color = black / 2006 / interior; color = tan」のようなリクエストでは、カラーマトリックスパラメーターの定義があいまいになります。各PathSegmentを個別に処理するように見えますが、それを理解することができます... categoryName = foo; objectName = greenを指定する場合よりも、非常に便利ですが、より多くの作業が必要になります。
UFL1138 2014年

15

Tim Sylvesterの回答に加えて、マトリックスパラメーターを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;
    }

    応答

    green

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

    @MatrixParamアノテーション値は、マトリックスパラメーターの値を挿入するパス注釈付きJava構造の最後に一致したパスセグメントに存在するマトリックスパラメーターの名前を指すことに注意してください。

    ...ポイント2をもたらすもの

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

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

    パス変数とを使用して、どこでも行列パラメーターにアクセスできます@PathParam PathSegment

    @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;
    }

    応答

    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>それらをすべて取得するにはa を使用します

    @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();
    }

    応答

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]

10

-コメントセクションに降格することは重要です。--

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

つまり、ビジネス上の目的でRSが必要な場合は、リクエストパラメータを使用したほうがよいでしょう。


5
非常にユニークであると判断したAngular 2開発者に、代わりにこれを実装する必要があると誰かが言う!
Matt Pileggi、2016

2
@MattPileggi私もAngular 2のおかげでこれを読んでいます。Angular2のほぼすべての側面は非常に特殊化されており、型破りであり、既存の使用パターンとは矛盾しています。これにより、軽減価値が追加されることはまだ証明されていません。
Aluan Haddad 2016

1
だからみんな、私も同じ理由でここにいますが、角の2チームのgithubページのurlマトリックスとgoogle analytisに関するこの問題でこの議論にいくつかのポイントを追加さ​​せてください:github.com/angular/angular/issues/11740 しかしそれについていくつかの調査をした後、URLマトリックス表記は、主に(途中だけでなく)URLの一部のパラメーターが必要な場合に、URLクエリパラメーターよりも人間が読めるように見えます。
リチャードリー

8
これが非標準だと思う人は誰でも、uriテンプレートの仕様に精通していないと思いますか?パスパラメータで複雑なオブジェクトをエンコードすることは、uriテンプレートの非常に便利な機能です。ほとんどの人がそれを知らない、または使用していないからといって、それが角度のある開発者による悪の陰謀であり、あなたの人生に無用な複雑さを注入しているわけではありません。
Ajax

2
Pffft-「<今まで存在していたことを知らなかったもの>は非標準であるため、私の無知の受容性は維持されます」。TBLがアイデアを使用して決定したこと、または決定しなかったことは、ほとんど重要ではありません。これは2001年の彼の Webの機能ではありませんでした。Webの機能は、クライアントとサーバーの実装者が選択したものです。Angularが行列パラメーターをサポートし、JAX-RSがそれらをサポートし、これらが選択された実装ツールである場合は、先に進んで機能するものを使用してください。
デイブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.