简体   繁体   English

WebApi和OData

[英]WebApi and OData

I'm new to WebApi and I don't quite get it . 我是WebApi的新手,我不太明白

I do get that all the verbs are focused on Get, Put, Post and Delete. 我确实知道所有动词都集中在Get,Put,Post和Delete上。 But Coming from a heavy DDD and MVC background, I need some pointers. 但是由于DDD和MVC的背景很深,我需要一些指导。

I'm used to expose services/resources/actions whatever you want to call it that does some internal filtering. 我习惯于公开服务/资源/操作,无论您想调用它进行一些内部过滤。 eg for an SalesOrder service I might have operations like GetTodaysOrders , GetUnapprovedOrders etc. Operations that applies some filtering on the "SalesOrder set" 例如,对于SalesOrder服务,我可能具有GetTodaysOrders,GetUnapprovedOrders等操作。对“ SalesOrder集”应用某些过滤的操作

So, In WebApi and rest in general I suppose, I'm not supposed to do this? 因此,我想在WebApi和一般的休息中,我不应该这样做吗? I'm supposed to expose the entire SalesOrder set? 我应该公开整个SalesOrder集吗?

And filtering could be done with OData but that moves the responisbillity of knowing what to filter to the consumer, the consumer must know what to ask for, eg any domain/business rule must be known by the consumer. 可以使用OData进行过滤,但是这将知道要过滤的内容的责任移交给了消费者,消费者必须知道要提出的要求,例如,消费者必须知道任何域/业务规则。 That part seems totally alien to me. 这部分对我来说似乎完全陌生。

How do you deal with this sort of things? 您如何处理这类事情? Can this be handled in some way, and I don't mean in a hacky way like creating a new web api controller for each and every way you can filter some data. 可以以某种方式处理此问题吗?我并不是说要像为每种可以过滤某些数据的方式创建新的Web api控制器那样简单的方法。

I feel your pain. 我感到你很痛苦。 The first time i was really forced to change my way of thinking is when I started developing on Ruby On Rails. 第一次真正被迫改变思维方式是当我开始在Ruby On Rails上进行开发时。

regarding exposing methods in general, Try doing it in this order: 关于一般公开方法,请尝试按以下顺序进行操作:

  1. start by exposing the full set of CRUD operations for the resource (aka make your RESTful resource) 首先,公开资源的完整CRUD操作集(也就是使您的RESTful资源)
  2. go back and privatize the things that should not be exposed by doing pre- and post- hooks on those methods for authentication / permissions checks and whatnot. 返回并通过对身份验证/权限检查之类的方法进行前后挂钩来私有化不应公开的内容。

Then, when you've got your resources, a generally good rule of thumb is to show what is necessary before the ? 然后,当您拥有资源时,通常的经验法则是在?之前显示必要的内容? and hide the complexity behind the ? 隐藏背后的复杂性 ? , thus making your resources able to do filtering, but not requiring it. ,从而使您的资源能够执行过滤,但不需要过滤。 In other words, decorate your methods with filtering. 换句话说,用过滤装饰您的方法。

So, lets say you want to have an /orders endpoint: 因此,假设您要使用/orders端点:

Base URL: /orders
REST params: /orders(:/id)
Additional params:
  - dateRange
  - purchaseStatus
  - price
  - etc
Example usage: 
  /orders?dateRange=1y&price=lt:100

Of course, I say all of this because I tend to agree with what APIGEE said about it in their API best practices whitepaper. 当然,我之所以这么说,是因为我倾向于同意APIGEE在其API最佳做法白皮书中对它的描述。 I think you'll find it helpful. 我想您会发现它会有所帮助。

https://pages.apigee.com/rs/apigee/images/api-design-ebook-2012-03.pdf https://pages.apigee.com/rs/apigee/images/api-design-ebook-2012-03.pdf

It takes a bit of time to get used to but you will find the APIGEE approach referenced by Kristian very useful. 习惯需要一些时间,但是您会发现Kristian引用的APIGEE方法非常有用。

I'm supposed to expose the entire SalesOrder set? 我应该公开整个SalesOrder集吗?

Only if you you want to. 仅在您想要的时候。 The default Index method is just there to help you get started, if it does not make sense in your case, remove it. 缺省的Index方法仅用于帮助您入门,如果这种情况对您没有帮助,请将其删除。 Or change it to return the sales orders in a paged fashion, or just the most recent. 或更改它以分页的方式返回销售订单,或仅返回最新的销售订单。

In your scenario - 在您的情况下-

GetTodaysOrders would be a GET request like api/orders?period=1 GetTodaysOrders将是GET请求,例如api / orders?period = 1

GetUnapprovedOrders would be a GET request like api/orders?approved=false GetUnapprovedOrders将是GET请求,例如api / orders?approved = false

Both of these calls could be to the same action method - ActionResult Index(int period, bool approved) (I'm not at a dev machine now and can't remember if parameters need to be nullable/optional) 这两个调用都可能是相同的操作方法ActionResult Index(int period, bool approved) (我现在不在开发机器上,不记得参数是否需要可为空/可选)

As for OData, it is very powerful, but yes the consumer of the API must know how to call it, and what to filter on. 至于OData,它非常强大,但是是的,API的使用者必须知道如何调用它以及对其进行过滤的内容。 But they should know that anyway. 但是无论如何,他们应该知道这一点。 You can set limits with OData on how many records can be pull, which orderby's you support (to protect searching on unindexed columns in your db) and more see here for examples. 您可以使用OData设置限制,以限制可提取的记录数,支持的排序方式(以保护对数据库中未索引列的搜索),更多示例请参见此处

In addition to all the great answers above: if there is a certain function/method that really requires some functionality that cannot (easily) be supported by any of the CRUD operations, you can always fall back on OData Actions. 除了上述所有出色的答案之外:如果某些功能/方法确实需要某些CRUD操作无法(轻松)支持的功能,则可以始终使用OData操作。

You can manually declare a specific method as an action, and then you actually get the exposed methods like you are used to from MVC. 您可以手动将一个特定的方法声明为一个动作,然后您实际上可以像从MVC中那样获得公开的方法。 Mike Wasson has written a perfect article on OData Actions, which you can find here: Supporting OData Actions in ASP.NET Web API Mike Wasson写了一篇有关OData Actions的完美文章,您可以在这里找到: 在ASP.NET Web API中支持OData Actions

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM