Kyl*_*bel 8 rest web-services routes servicestack
我有一个服务堆栈服务,我们将调用Orders
具有标准GET路由
/orders
- 获取所有客户/orders/{Ids}
- 获取特定客户这一切都很好,花花公子,但我想我会添加另一条路线
/orders/customers/{CustomerId}
- 获取具有特定客户ID的订单这可以在浏览器中找到路由时找到,但是当我使用ServiceStack Client时,我得到了不明确的路由异常,并列出了三条路由.
我不太确定最好的解决方法是什么..我正在做的不是正确的REST方式吗?
我知道我可以简单地手动输入路线之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;
}
}
Run Code Online (Sandbox Code Playgroud)
我是否必须为此使用不同的Dt或......?
任何有关此方法的示例的任何帮助或指针,或者更好的方式来创建服务将是值得赞赏的.
谢谢
我的建议是你没有正确使用REST.关于如何最好地构建ServiceStack REST服务有一个很好的答案.开始时这是一个常见的问题,我也遇到过类似的问题.
在您的具体情况下,如果我们看一下/orders/customers/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
Run Code Online (Sandbox Code Playgroud)
这样做的好处是对数据的操作是一致的.所以你想找到所有被取消的订单:
/orders/cancelled
Run Code Online (Sandbox Code Playgroud)
您想通过它取消特定订单 orderId
/orders/4/cancel
Run Code Online (Sandbox Code Playgroud)
您想列出特定客户的未结订单
/customers/6/orders/open
Run Code Online (Sandbox Code Playgroud)
您想列出客户6的已取消订单
/customers/6/orders/cancelled
Run Code Online (Sandbox Code Playgroud)
您想要取消您正在查看的客户6的订单
/customers/6/orders/2/cancel
Run Code Online (Sandbox Code Playgroud)
显然这些只是场景,你的路线会有所不同.
您可能希望定义操作处理程序,以便它们可以应对来自多个路径的操作.我的意思是,一个动作处理程序将负责列表订单
/orders
/customers/6/orders
Run Code Online (Sandbox Code Playgroud)
我这样做是:
[Route("/orders","GET")]
[Route("/customers/{CustomerId}/orders","GET")]
public class ListOrdersRequest : IReturn<List<Order>>
{
public int? CustomerId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所以你可以看到两个订单列表路线进来.如果他们使用/orders
那么我们customerId
将没有值,但另一个路线将.所以在我们的动作处理程序中,我们可以简单地测试:
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;
}
Run Code Online (Sandbox Code Playgroud)
因此,要解决您使用'打字'客户关注的问题.使用上述方法创建路径和操作处理程序将允许您执行以下操作:
client.Get(new ListOrdersRequest { CustomerId = 7 }); // To get customer 7's orders
client.Get(new ListOrdersRequest()); // All orders
Run Code Online (Sandbox Code Playgroud)
因此,为您提供一个明确的上市订单方法.
显然这意味着你将不得不重做你所拥有的可能会带来痛苦的东西,但这是最好的方法,非常值得付出努力.
我希望这有助于您了解最佳结构.
@ stefan2410要求我解决Kyle int[]
在路由中使用GET请求的问题:
如果要int[]
在GET请求中使用,则必须考虑在URL中传输期间更改它,以便可以RESTful地使用它.
所以你可以这样做:
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}));
Run Code Online (Sandbox Code Playgroud)
创建路线/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}));
Run Code Online (Sandbox Code Playgroud)
创建路线/orders
并匹配路线/orders
.
归档时间: |
|
查看次数: |
368 次 |
最近记录: |