リンクされたリソースの拡張をサポートする ReST API を構築していますが、ServiceStack のネイティブ バインディング機能を使用して URL を入力済みの「リクエスト DTO」オブジェクトに変換する方法がわかりません。
たとえば、私の API で、次のリクエストを使用してバンドに関する情報を取得できるとします。
GET /bands/123
< 200 OK
< Content-Type: application/json
{
"href": "/bands/123",
"name": "Van Halen",
"genre": "Rock",
"albums" {
"href" : "/bands/1/albums",
}
}
バンドのアルバム リストを拡張したい場合は、次のようにします。
GET /bands/1?expand=albums
< 200 OK
< Content-Type: application/json
{
"href": "/bands/123",
"name": "Van Halen",
"genre": "Rock",
"albums" {
"href" : "/bands/1/albums",
"items": [
{ "href" : "/bands/1/albums/17892" },
{ "href" : "/bands/1/albums/28971" }
]
}
}
ServiceStack を使用していますが、既存のサービス メソッドを再利用してこのインライン展開を実行したいと考えています。
私の ServiceStack 応答 DTO は次のようになります。
public class BandDto {
public string Href { get; set; }
public string Name { get; set; }
public AlbumListDto Albums { get; set; }
}
public class AlbumListDto {
public string Href { get; set; }
public IList<AlbumDto> Items { get; set;}
}
public class AlbumDto {
public string Href { get; set; }
public string Name { get; set; }
public int ReleaseYear { get; set; }
}
私のServiceStackリクエスト/ルートオブジェクトは次のようなものです:
[Route("/bands/{BandId}", "GET")]
public class Band : IReturn<BandDto> {
public string Expand { get; set; }
public int BandId { get; set; }
}
[Route("/bands/{BandId}/albums", "GET")]
public class BandAlbums : IReturn<AlbumListDto> {
public int BandId { get; set; }
}
リクエストを処理する実際のサービスは次のようになります。
public class BandAlbumService : Service {
public object Get(BandAlbums request) {
return(musicDb.GetAlbumsByBand(request.BandId));
}
}
public class BandService : Service {
private IMusicDatabase db;
private BandAlbumService bandAlbumService;
public BandService(IMusicDatabase musicDb, BandAlbumService bandAlbumService) {
this.db = musicDb;
this.bandAlbumService = bandAlbumService;
}
public object Get(Band request) {
var result = musicDb.GetBand(request.BandId);
if (request.Expand.Contains("albums")) {
// OK, I already have the string /bands/123/albums
// How do I translate this into a BandAlbums object
// so I can just invoke BandAlbumService.Get(albums)
var albumsRequest = Translate(result.Albums.Href);
result.Albums = bandAlbumService.Get(albumsRequest);
}
}
/bands/123/albums
上記の例で、Van Halen のアルバム リストの HREF として文字列を計算したとします。
ServiceStack の組み込みバインディング機能を使用して、文字列/bands/123/albums
を BandAlbums の「リクエスト」オブジェクトに変換し、BandAlbumService に直接渡すことができます。データが入力された BandAlbumsDto オブジェクトを取得し、それを応答オブジェクトに含めるにはどうすればよいですか?
(もちろん、データベース ヒットを最小限に抑えるという点では、これがおそらく最適なアプローチではないことは承知しています。これについては後で考えます。)