gpt4 book ai didi

web-services - ServiceStack 客户端和二义性路由

转载 作者:行者123 更新时间:2023-12-04 05:18:02 25 4
gpt4 key购买 nike

我有一个服务堆栈服务,我们将调用 Orders具有标准 GET 路由

  • /orders - 获取所有客户
  • /orders/{Ids} - 获取特定客户

  • 这一切正常,但我想我会添加另一条路线
  • /orders/customers/{CustomerId} - 获取具有特定客户 ID 的订单

  • 这在浏览器中找到路由时有效,但是当我使用 ServiceStack Client 时,我得到了不明确的路由异常,它列出了三个路由。

    我不太确定解决这个问题的最佳方法是什么……是我做的不是正确的 RESTish 方法吗?

    我知道我可以简单地手动将路线输入到 JsonServiceClient喜欢
    client.Get<List<Orders>>("/orders/customers/7")
    这会奏效,但我更愿意用打字的方式来做……即
    client.Get(new OrdersRequest { CustomerId = 7 });
    这是我正在使用的 RequestDTO 示例
    public class OrdersRequest : IReturn<List<Orders>>
    {
    public int[] Ids {get; set;}
    public CustomerId {get; set;}

    public OrdersRequest(params int[] ids)
    {
    this.Ids = ids;
    }
    }

    我是否必须为此使用不同的 Dtos 或...?

    任何有办法解决此问题的示例的任何帮助或指针,或创建服务的更好方法,将不胜感激。

    谢谢

    最佳答案

    我的建议是您没有正确使用 REST。有a good answer about how to best structure a ServiceStack REST service .这是开始时的常见问题,我也遇到过这样的问题。

    了解您的用例:

    在您的具体情况下,如果我们查看 /orders/customers/7如果你这样想,这会更好:

    /customers/7/orders



    你这样做的原因:
  • 它解决了您的路线模糊问题
  • 上下文很清楚。我们可以看到我们正在与客户 7 合作,而无需导航长网址
  • 我们可以看到“与客户 7”我们想要他们的订单

  • 考虑这样的路由:
    /orders                   Everybody's Orders
    /orders/1 Order 1 (without being aware of the customer it belongs to)
    /customers All Customers
    /customers/7 Customer 7's details
    /customers/7/orders All Customer 7's orders
    /customers/7/orders/3 Customer 7's order number 3

    做这样的事情的美妙之处在于对数据的操作是一致的。所以你想找到所有取消的订单:
    /orders/cancelled

    您想通过 orderId 取消特定订单
    /orders/4/cancel

    您想列出特定客户的未结订单
    /customers/6/orders/open

    您想列出客户 6 的取消订单
    /customers/6/orders/cancelled

    您想取消正在查看的客户 6 的订单
    /customers/6/orders/2/cancel

    显然,这些只是场景,您的路线会有所不同。

    简化 Action 处理程序:

    您可能希望定义您的 Action 处理程序,以便它们可以处理来自多个路由的问题。我的意思是,一个 Action 处理程序将负责列出订单
    /orders
    /customers/6/orders

    我做的是这样的:

    [Route("/orders","GET")]
    [Route("/customers/{CustomerId}/orders","GET")]
    public class ListOrdersRequest : IReturn<List<Order>>
    {
    public int? CustomerId { get; set; }
    }

    所以你可以看到两个订单列表路由进来了。如果他们使用 /orders那么我们的 customerId不会有值(value),但另一条路线会有。所以在我们的 Action 处理程序中,我们可以简单地测试一下:

    public List<Order> Get(ListOrdersRequest request)
    {
    // Use `CustomerId` to narrow down your search scope

    if(request.CustomerId.HasValue){
    // Find customer specific orders
    } else {
    // Find all orders
    }

    return orders;
    }

    客户端关注点:

    因此,要解决您使用“类型化”客户端的问题。使用上述方法创建路由和操作处理程序将允许您执行以下操作:

    client.Get(new ListOrdersRequest { CustomerId = 7 }); // To get customer 7's orders
    client.Get(new ListOrdersRequest()); // All orders

    从而为您提供 1 种明确的上市订单方法。

    最后的想法:

    显然,这意味着您将不得不重新制作您拥有的东西,这可能会很痛苦,但这是最好的方法,值得付出努力。

    我希望这可以帮助您理解最佳结构。

    更新:

    @stefan2410 要求我解决 Kyle 使用 int[] 的问题在 GET 请求的路由中:

    如果您想使用 int[]在 GET 请求中,您必须考虑在 URL 传输期间更改它,以便可以 REST 方式使用它。

    所以你可以这样做:

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

    public OrdersRequest(int[] ids)
    {
    Ids = string.Join(",", Array.ConvertAll(ints, item => item.ToString()));
    }
    }

    client.Get(new OrdersRequest(new [] {1,2,3}));

    创建路由 /orders/1,2,3并匹配 /orders/{Ids} .这样做的问题是为了在服务器端使用 Id,您必须转换字符串 "1,2,3"回到 int[] .

    更好的方法 处理 int[]在一个请求中是使用 POST。所以你可以这样做:

    class OrdersRequest
    {
    public int[] Ids { get; set; }

    public OrdersRequest(int[] ids)
    {
    Ids = ids;
    }
    }

    client.Post(new OrdersRequest(new[] {1,2,3}));

    创建路由 /orders并匹配路线 /orders .

    关于web-services - ServiceStack 客户端和二义性路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20590550/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com