9

IDが

public string ID {get;set;}    
activities/1

(これはRavenDBからのものです)。

ServiceStackAppHostに次のルートを登録しています

Routes
    .Add<Activity>("/activities")
    .Add<Activity("/activities/{id}");

バックボーンアプリを使用して、RESTサービスにPOSTおよびPUTします。

箱から出して何が起こるか:

  • idプロパティは「activities/1」としてjsonにシリアル化されます
  • idプロパティは、「activities%2F1」としてルートにエンコードされます
  • ServiceStackはURLベースのidプロパティを優先するため、私の文字列はRavenDbに直接使用されないエンコードされた値を取得します。

私が知っているオプション:

  • バックボーンを変更して「/activities」に投稿し、JSONシリアライザーを起動させます
  • スラッシュではなくハイフンを使用するようにRavenDbIDの生成を変更します
  • セットでエンコードされた%2FのIdプロパティを解析し、スラッシュに変換します

どちらにも、APIのRESTfulnessが失われるという欠点があります。これは望ましくないか、RavenDbの規則に従わないためです。また、私はスラッシュを持つことを個人的に好みます。

それで、妥協の少ないこの問題をソートするために使用できるサービススタックの他のオプションがあるかどうか疑問に思っていますか?シリアライザーのカスタマイズまたはワイルドカードルーティングのいずれかが私の頭の中にあります。

4

2 に答える 2

10

ASP.Net WebAPIでも同じ問題があるので、これはServiceStackの問題ではないと思いますが、RESTURLでのRavenスタイルIDの処理に関する一般的な懸念事項です。

たとえば、次のGET: /api/usersようなクエリを実行して結果を返したとします。

[{
  Id:"users/1",
  Name:"John"
},
{
  Id:"users/2",
  Name:"Mary"
}]

ここで、特定のユーザーを取得したいと思います。純粋なRESTアプローチに従う場合、IDはこのドキュメントから収集され、URLのid部分に渡されます。ここでの問題は、これが GET: /api/users/users/1混乱を招くだけでなく、WebAPI(およびServiceStack)がURLパラメーターをアクションメソッドにルーティングする方法の邪魔になるように見えることです。

私が行った妥協案は、URLの観点からのみIDを整数として扱うことでした。したがって、クライアントはを呼び出しGET: /api/users/1、メソッドを。として定義しますpublic User Get(int id)

クールな部分は、Ravensession.Load(id)には完全な文字列形式または整数形式のいずれかをとるオーバーロードがあるため、ほとんどの場合、翻訳する必要がないことです。

IDを変換する必要がある場合は、次の拡張メソッドを使用できます。

public static string GetStringIdFor<T>(this IDocumentSession session, int id)
{
  var c = session.Advanced.DocumentStore.Conventions;
  return c.FindFullDocumentKeyFromNonStringIdentifier(id, typeof (T), false);
}

それを呼び出すのは簡単session.GetStringIdFor<User>(id)です。私は通常、ドキュメントをすぐにロードする以外のIDで何かをしている場合にのみ、手動で翻訳する必要があります。

このようにIDを変換することで、RESTの純粋主義者の慣習を破っていることを理解していますが、状況を考えると、これは合理的だと思います。誰かが思いついた別のアプローチに興味があります。

于 2012-10-17T17:26:04.477 に答える
0

RavenDBでDurandalJSを試してみると、この問題が発生しました。

私の回避策は、URLを少し変更して機能させることでした。したがって、あなたの例では:

GET /api/users/users/1

なりました

GET /api/users/?id=users/1

jQueryから、これは次のようになります。

var vm = {};
vm.users = [];

$.get("/api/users/?" + $.param( { id: "users/1" })
  .done(function(data) {
      vm.users = data;
  });
于 2014-07-02T12:36:50.470 に答える