Web services ServiceStack客户端和不明确路由
我有一个服务堆栈服务,我们将调用Web services ServiceStack客户端和不明确路由,web-services,rest,routes,servicestack,Web Services,Rest,Routes,servicestack,我有一个服务堆栈服务,我们将调用Orders,它具有标准的GET路由 /orders-获取所有客户 /orders/{Ids}-获取特定客户 这一切都很好,但我想我应该添加另一条路线 /orders/customers/{CustomerId}-获取具有特定客户id的订单 当在浏览器中点击路由时可以找到,但当我使用ServiceStack客户端时,会出现不明确路由异常,它列出了三条路由 我不太确定最好的解决方法是什么……我所做的不是正确的RESTish方式吗 我知道我只需手动将路由输入J
Orders
,它具有标准的GET路由
-获取所有客户/orders
-获取特定客户/orders/{Ids}
-获取具有特定客户id的订单/orders/customers/{CustomerId}
JsonServiceClient
即可
client.Get(“/orders/customers/7”)
这也行,但我更喜欢用打字的方式…也就是说
client.Get(新订单请求{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;
}
}
公共类订单请求:IReturn
{
公共int[]Ids{get;set;}
公共CustomerId{get;set;}
公共订单请求(参数int[]id)
{
这个.Ids=Ids;
}
}
我必须使用不同的DTO进行此操作还是
如果有任何帮助或指向任何示例的指针能够解决这个问题,或者有更好的方法来创建服务,我们将不胜感激
谢谢我的建议是你没有正确使用REST。有。刚开始的时候这是一个常见的问题,我也有类似的问题
了解您的用例:
在您的具体案例中,如果我们看一下/orders/customers/7
,如果您这样想,效果会更好:
/客户/7/订单
您这样做的原因是:
- 它解决了路线模糊的问题
- 背景很清楚。我们可以看到,我们正在使用Customer 7,而无需导航长url
- 我们可以看到“与客户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
显然,这些只是场景,你的路线会有所不同
简化操作处理程序:
您可能需要定义动作处理程序,以便它们能够处理来自多个路由的动作。我的意思是,一个操作处理程序将负责列出订单
/orders
/customers/6/orders
我所做的是:
[路由(“/orders”,“GET”)]
[路线(“/customers/{CustomerId}/orders”,“GET”)]
公共类ListOrdersRequest:IReturn
{
public int?CustomerId{get;set;}
}
因此,您可以看到两个订单列表路线。如果他们使用/orders
,则我们的customerId
将没有值,但另一条路径将有值。因此,在我们的操作处理程序中,我们可以简单地测试:
公共列表获取(ListOrdersRequest请求)
{
//使用“CustomerId”缩小搜索范围
if(request.CustomerId.HasValue){
//查找特定于客户的订单
}否则{
//查找所有订单
}
退货订单;
}
客户端关注点:
因此,要解决您使用“类型化”客户端的问题。使用上述方法创建路由和操作处理程序将允许您执行以下操作:
client.Get(新的ListOrdersRequest{CustomerId=7});//获取客户7的订单
client.Get(新建ListOrdersRequest());//所有命令
因此,为您提供了一个列出订单的清晰方法
最后的想法:
显然,这意味着你将不得不重做你所拥有的,这可能是一种痛苦,但这是最好的方法,值得付出努力
我希望这有助于您理解最佳结构
更新:
@stefan2410要求我解决Kyle在GET请求的路由中使用int[]
的问题:
如果您想在GET请求中使用<代码> INT[]/COD>,您必须考虑在URL中的传输过程中更改它,以便可以放心使用。
所以你可以这样做:
类顺序请求
{
公共字符串ID{get;set;}
公共订单请求(int[]id)
{
Ids=string.Join(“,”,Array.ConvertAll(ints,item=>item.ToString());
}
}
Get(newordersrequest(new[]{1,2,3}));
创建路由/orders/1,2,3
并匹配/orders/{Ids}
。这样做的问题是,为了在服务器端使用ID,您必须将字符串“1,2,3”
转换回int[]
处理请求中的int[]
的更好方法是使用POST。因此,您可以:
类顺序请求
{
公共int[]Ids{get;set;}
公共订单请求(int[]id)
{
Ids=Ids;
}
}
client.Post(newordersrequest(new[]{1,2,3}));
创建路线/orders
并匹配路线/orders
非常有用的答案,如果可以的话,我会给你+2。@Scott,也许你说的路线更符合用例,但我不明白歧义在哪里。Dto(带参数数组的构造函数)中有错误。还有/orders/{Ids},首先它意味着订单的ID而不是客户的ID,其次,Get中是否可能在Uri中有一个整数数组?(当然不是正确的REST)@stefan2410是的,你是对的,在路由中传递一个ID数组是错误的。我认为Kyle可能简化了他的问题,消除了歧义,但他确实在访问请求(可能是其他路由)时通过一个含糊不清的routeException
说出了这个问题。使用/orders/customers
lea