【问题标题】:How can I translate an href into a RequestDto using ServiceStack?如何使用 ServiceStack 将 href 转换为 RequestDto?
【发布时间】:2013-07-30 10:43:09
【问题描述】:

我正在构建一个支持链接资源扩展的 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作为范海伦专辑列表的HREF。

我现在如何使用 ServiceStack 的内置绑定功能将字符串 /bands/123/albums 转换为可以直接传递到 BandAlbumService 的 BandAlbums“请求”对象,取回填充的 BandAlbumsDto 对象并将其包含在我的响应对象中?

(是的,我知道这可能不是最小化数据库命中的最佳方法。我稍后会担心这个问题。)

【问题讨论】:

    标签: rest servicestack hateoas


    【解决方案1】:

    RestPath 应该能帮到你:

    我认为这应该可行:

    var restPath = EndpointHostConfig.Instance.Metadata.Routes.RestPaths.Single(x => x.RequestType == typeof(AlbumRequest));
    var request = restPath.CreateRequest("/bands/123/albums")
    

    【讨论】:

    • 效果很好 - 谢谢 :) 请注意,您需要实际实例化和初始化 API 主机才能在单元测试中执行此操作。
    猜你喜欢
    • 1970-01-01
    • 2014-07-13
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    相关资源
    最近更新 更多