2012-10-17 9 views
9

mam podmiot z IDServiceStack Routing z ravendb identyfikatorów

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

(która pochodzi z RavenDB).

ja rejestracji następujących trasach w moim ServiceStack AppHost

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

Używam app szkieletowych POST i PUT do mego odpoczynku Service.

Co się out-of-the-box:

  • właściwość id odcinkach w json jako "działania/1"
  • właściwość
  • id kodowanych w szlaku "działaniami% 2F1"
  • ServiceStack daje pierwszeństwo właściwości id opartej na adresie URL, więc mój ciąg otrzymuje zakodowaną wartość, która nie ma bezpośredniego zastosowania do RavenDb.

Opcje Jestem świadomy:

  • Zmień szkieletu do umieszczenia na „/” działania i niech rzut JSON Serialiser w
  • generacji
  • Zmień RavenDb ID używać myślników zamiast ukośniki
  • bądź moją właściwość ID przetwarza na zakodowanym% 2F na planie i konwertować do ukośnikiem

Obie mają wady, że albo straci RESTfuln w moim interfejsie API, co jest niepożądane, lub nie stosuję się do konwencji RavenDb, które są zwykle sensowne poza lisami. Ponadto, mam osobistą preferencję do posiadania ukośników.

Zastanawiam się, czy są jakieś inne opcje w servicestack, które mógłbym użyć, aby rozwiązać ten problem, który wymaga mniej kompromisu? Albo konfiguracja Serialisera, albo routing wieloznaczny są w mojej głowie ...

Odpowiedz

10

Mam ten sam problem z ASP.Net WebAPI, więc nie sądzę, że jest to tak wiele problemów ServiceStack, ale tylko ogólna troska o transakcje z identyfikatorem stylu Raven na URL REST.

Na przykład, powiedzmy kwerendy GET: /api/users i zwrócić wynik jak:

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

Teraz chcę dostać konkretnego użytkownika. Jeśli zastosuję czystą metodę REST, identyfikator zostanie zebrany z tego dokumentu, a następnie przekażę go w id części adresu URL. Problem polega na tym, że kończy się to wyglądem jak GET: /api/users/users/1, co nie jest tylko mylące, ale ukośnik utrudnia sposób, w jaki WebAPI (i ServiceStack) kierują parametry url do metod działania.

Dokonany przeze mnie kompromis polegał na traktowaniu id jako liczby całkowitej wyłącznie z perspektywy adresu URL. Dlatego klient dzwoni pod numer GET: /api/users/1, a moją metodę definiuję jako public User Get(int id).

Chłodną częścią jest to, że Raven ma session.Load(id) ma przeciążenia, które przyjmują formę pełnego ciągu lub postaci całkowitej, więc nie musisz tłumaczyć przez większość czasu.

Jeśli znajdziesz się potrzeby tłumaczyć identyfikator, można użyć tej metody rozszerzenia:

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

Wywołanie to jest proste jak session.GetStringIdFor<User>(id). Zwykle tłumaczę ręcznie, jeśli robię coś z identyfikatorem innym niż ładowanie dokumentu natychmiast.

Rozumiem, że tłumacząc ids w ten sposób, łamie niektóre purystyczne konwencje REST, ale uważam, że jest to rozsądne zważywszy na okoliczności. Byłbym zainteresowany wszelkimi alternatywnymi podejściami, które ktoś może wymyślić.

+0

Dzięki za tym Matt. Czy zwracasz identyfikator Integer z GET:/api/users? – Chris

+0

Nie, okazało się to zbyt niezdarne, aby manipulować zestawem wyników, dlatego właśnie zwracam pełny ciąg znaków. Aplikacja kliencka zachowuje pełny ciąg znaków, ale kiedy buduje adres URL z identyfikatorem, usuwa przednią część za pomocą czegoś takiego jak id.split ("/") [1] –

0

Miałem ten problem podczas wypróbowywania Durandal JS z RavenDB.

Moje obejście polegało na niewielkiej zmianie adresu URL, aby działał. Więc w przykładzie:

GET /api/users/users/1 

Stał

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

Od jQuery, to staje się:

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

$.get("/api/users/?" + $.param({ id: "users/1" }) 
    .done(function(data) { 
     vm.users = data; 
    });