17

ServiceStackで構築された単純なRESTサービスがあります。

次のようにルートを構成すると、次のようになります。

        //register user-defined REST-ful urls
        Routes
            .Add<Contact>("/Contacts")
            .Add<Contact>("/Contacts/{ContactId}")

このリクエストは成功します。

http://<server>:59557/Contacts?ContactId=9999 //Works

このようにルートを構成した場合(ビジネスアナリストは生成されたメタデータを優先します)

        //register user-defined REST-ful urls
        Routes
            .Add<UpdateContact>("/UpdateContact", "PUT")
            .Add<CreateContact>("/CreateContact", "POST")
            .Add<GetContact>("/Contacts/{ContactId}", "GET")

http://<server>:59557/Contacts/9999           //Works
http://<server>:59557/Contacts?ContactId=9999 //Fails, Handler for request not found

/Contacts?ContactId=9999へのリクエストが成功するように2番目のサンプルのルートを設定するにはどうすればよいですか?

ありがとう。

4

2 に答える 2

34

ServiceStackのルーティングの一部は、最初の Web サイトの説明 wikiページで説明されています。

[Route("/hello/{Name}")]

のみ一致:

/hello/name

一方:

[Route("/hello")]

一致:

/hello?Name=XXX

注: QueryString、FormData、および HTTP Request Body は Route の一部ではありません (つまり、/path/info のみです) が、すべての Web サービス呼び出しに加えて、Request DTO をさらに設定するために使用できます。

次のようなワイルドカードパスを含むルートを使用します。

[Route("/hello/{Name*}")]

一致:

/hello
/hello/name
/hello/my/name/is/ServiceStack

ワイルドカード ルートを使用する場合のもう 1 つの適切な使用例です

したがって、一致させるには、これらの両方のルートに一致するルートを登録する必要が/Customers?Key=Valueあり/Customers/{Id}ます。

Routes
    .Add<GetContact>("/Contacts", "GET")
    .Add<GetContact>("/Contacts/{ContactId}", "GET")

すべてのサービスの規則ベースのルートを自動登録する方法

また、これに関連して、 AddFromAssembly拡張メソッドを介して自動ルートを登録します。ここで、この単一の呼び出し:

Routes.AddFromAssembly(typeof(MyService).Assembly)

すべてのサービス (指定されたアセンブリ内) を調べてスキャンし、実装したすべての HTTP メソッドに基づいて規則ベースのルートを登録します。たとえばGetContactUpdateContactサービスにIdプロパティがある場合、次のルートが自動的に登録されます。

Routes
    .Add<GetContact>("/Contacts", "GET")
    .Add<GetContact>("/Contacts/{Id}", "GET")
    .Add<UpdateContact>("/Contacts", "POST PUT")
    .Add<UpdateContact>("/Contacts/{Id}", "POST PUT")

また、すべての HTTP 動詞の実装を備えた単一のContactsREST サービスがあれば、次のルートが登録されます。

Routes
    .Add<Contacts>("/Contacts", "GET POST PUT DELETE PATCH")
    .Add<Contacts>("/Contacts/{Id}", "GET POST PUT DELETE PATCH")

ルーティング解決順序

これについては、 New API Design wikiで詳しく説明されていますが、ルートの選択に使用される重み付けは以下に基づいています。

  1. 正確なリテラル一致が最初に使用されます
  2. すべての動詞よりも動詞の完全一致が優先されます
  3. ルート内の変数が多いほど、重み付けが少なくなります
  4. ルートの重みが同じ場合、順序はサービス内のアクションの位置または登録順序 (FIFO) によって決定されます。

例については、wikiのSmart Routingセクションを参照してください。

素晴らしいパフォーマンス

多数のルートがあると MVC でのルーティングが遅くなる可能性があるため、 ServiceStack のルーティング実装はハッシュ ルックアップを使用して実装されているため、MVC で発生した可能性のある線形パフォーマンス回帰の問題が発生しないことを指摘する価値があると思います。

于 2012-08-28T18:39:49.677 に答える
1

他の StackOverflow 投稿の回答に従って、次のルートを試すことができます。

/Contacts/{Ids*}

このリクエストクラスを使用します:

public class ContactRequest { public string Ids { get; set; } }

次に、指定された URL <service>/Contacts?Id=1&Id=2&Id=3ServiceStack はIds、リクエスト オブジェクトのプロパティに次の文字列を設定します。

Id=1&Id=2&Id=3

ID のリストに解析できます。

public object Get(ContactRequest request)
{
    var idPairs = request.Ids.Split("&");
    var ids = new List<string>();
    foreach (var idPair in idPairs)
    {
        ids.Add(idPair.Split("=")[1];
    }
    // ... do something with your ids now ...
    // ... return results ...
}

もちろん、ID 解析ロジック全体をtry...catchブロックにラップして、不正な形式のクエリ文字列を処理することもできます。

于 2013-07-12T15:12:56.520 に答える