您的应用程序需要过滤数据 - 使用 ODATA






4.41/5 (5投票s)
对于仍然使用老式 REST 的人来说,这里指引您转向 ODATA。
引言
常见的场景是,我们的应用程序(无论是移动应用还是 Web 应用)都由一个服务支持。如今,这些服务通常是 RESTful 的,因为 REST 的优势和灵活性是不可否认的。但是,我经常看到这些为应用程序消费而编写的服务,其端点是根据客户端应用程序的要求公开的。我们最近继承了一个项目的代码,这是一个 ASP.NET Web API,它旨在被 Angular 应用程序(基于 PhoneGap 的混合移动应用程序)使用。令我惊讶的是,这个 Web API 公开了为 Angular 应用程序需求量身定制的端点。例如,页面大小、页码、搜索排序等参数被传递到 API 的操作方法,以便在应用程序中获取过滤后的数据。
背景
我可能错了,但对我来说,这种方法感觉像是某种程度上污染了基于 Web API 的方式,因为 API 端点是由客户端应用程序的要求决定的。如果我们有另一个应用程序对数据有不同的需求怎么办?我们会公开更多端点来满足这个需求吗?最痛苦的是每个端点的实现。我们必须在 API 端有操作方法来满足这些需求。最终,API 为了满足所有这些需求而变得臃肿,并成为维护噩梦。
这种方法本身没有错,关键在于它是否满足我们的目的,以及我们是否能够承受这种复杂性。但是,对于此类服务,为什么不采用一种标准化的方法呢?如果您想到了 ODATA,那么您就答对了。
ODATA 是一种协议,我们可以使用它来共享和访问使用 AtomPub 协议的数据。AtomPub 协议主要用于创建网站的 Feed。它基于 REST 架构理念构建,其中可以使用 HTTP 协议(如 GET、PUT、POST 和 DELETE)执行远程数据资源的 CRUD 操作。
有关 ODATA 的更多信息: http://www.odata.org/
ODATA 和 ASP.NET Web API
现在从 ASP.NET Web API 的角度来看,支持 ODATA 相当容易。拥有 Web API 最好的部分是它已经构建用于创建 RESTful 服务。创建符合 ODATA 规范的 Web API 也相当容易。如果我必须用简单的词来说,创建符合 ODATA 规范的 Web API 只需要导入一个 NuGet 包。事实上,Visual Studio 带有一个脚手架模板,可用于生成符合 ODATA 规范的 API 控制器。将 APIControllers 转换为符合 ODATA 规范的控制器的所有魔法都在以下 NuGet 包中:Microsoft.AspNet.Odata
。
有关如何创建符合 ODATA 规范的 Web API 的分步教程: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint
这里需要注意的是,如果我们使用 Visual Studio 的 ODATA API 控制器脚手架,它会将ObjectContext
和数据访问代码放在控制器本身中。从模式的角度来看,这可能不是一个好主意。因此,如果我们希望我们的控制器使用存储库模式,我们只需要确保我们的存储库返回IQueryable
而不是IEnumerable
,ODATA 包将处理其余部分。
更新:有人提出了一个关于连接管理如何与之配合工作的问题。为了澄清这一点,使用 ODATA 并不意味着我们在客户端服务器之间创建了实时连接。它是以 ODATA 格式传递的参数,控制器以传统方式评估参数,就像在普通 APIController 中管理参数一样。为了更好地理解这一点,让我们来看一下在控制器中创建的方法。
public class MoviesController : ODataController
{
private MoviesDbEntities db = new MoviesDbEntities();
// GET: odata/Movies
[EnableQuery]
public IQueryable<Movie> GetMovies()
{
return db.Movies;
}
}
在上面的代码中,连接管理与传统操作方法没有什么不同,因为 Context 类对象在控制器被释放后立即被释放。
那么 ODATA 查询是如何神奇地工作的呢?这里发生的事情是,放在我们的查询方法顶部的属性EnableQuery
查看 URL/查询字符串中的 ODATA 特定参数。然后,它将获取我们操作方法的返回值,即IQueryable
,并根据用户传递的 IDATA 参数(在将其返回给调用者之前)对其应用 LINQ。应用此 LINQ 并准备好最终数据后,将调用相应 Context 类和控制器的 dispose 方法,从而处理连接的释放。
注意:这里的总体理念是让服务以标准格式公开数据,应用程序使用此格式使用数据。无需根据使用应用程序的要求公开端点。我只是提供了创建符合 ODATA 规范的 ASP.NET Web API 的参考,但相同的理念可以应用于任何技术栈。