在ASP.NET Core中使用Apworks开发数据服务:对HAL的支持
HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单、统一的形式,在API中引入超链接特性,使得API的可发现性(discoverable)更强,并具有自描述的特点。使用了HAL的API会更容易地被第三方开源库所调用,并且使用起来也很方便,开发者可以像处理普通JSON数据那样去处理API数据。有关HAL的更多信息,可以参考官方网站:http://stateless.co/hal_specification.html。目前,很多RESTful服务开发框架都支持HAL的Response格式(Content-Type为application/hal+json),比如大名鼎鼎的Spring Data,默认就支持HAL。现在,使用全新的Apworks Core(今后简称Apworks)开发数据服务时,默认也提供对HAL的支持。
HAL的启用和禁用
在上一篇快速开发文章中,演练部分通过修改Startup.cs文件中的ConfigureServices方法以在ASP.NET Core Web API中启用Apworks以及Data Service的开发支持。首先我们回顾一下这段代码:
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddApworks() .WithDataServiceSupport(new DataServiceConfigurationOptions (new MongoRepositoryContext (new MongoRepositorySettings("localhost", "customer-service")))) .Configure(); }
默认情况下,HAL的支持是启用的。也就是说,当你运行Data Service时,直接发起HTTP GET请求,返回的Response已经是application/hal+json格式的了:
注意:由于返回的数据量并没有超出一页的分页尺寸,所以在_links下仅显示了一个self的链接。如果存在多个分页,那么_links部分也会出现prev、next、first、last等链接。
如果希望禁用HAL的功能,其实非常简单,在上面的代码中,在构造DataServiceConfigurationOptions时直接指定useHalSupport参数为false即可:
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddApworks() .WithDataServiceSupport(new DataServiceConfigurationOptions (new MongoRepositoryContext (new MongoRepositorySettings("localhost", "customer-service")), useHalSupport: false)) .Configure(); }
于是,得到的返回内容就不再是application/hal+json,而是application/json了:
开发人员在开发Data Service的时候,可以根据自己的需求启用或者禁用HAL的支持。
自定义HAL的返回内容
在ASP.NET Core Web API中使用Apworks开发数据服务时,对于HAL的返回内容是可以自定义的。当然,这并不会改变HTTP Response的Content-Type,而是针对Response Body,其Json内容是可以被自定义的。例如,在上面的例子中,HTTP GET的Response Body中不仅包含所请求的数据对象数组(customers),而且还包含分页信息,以及一个含有分页链接的_links的对象。在实现Data Service的时候,如果这些返回内容不能满足需求,开发人员完全可以自定义。
举个例子,假设我们希望在返回内容中包含当前的服务器时间,其开发过程如下。
首先,新建一个继承于Apworks.Integration.AspNetCore.DataServices.DataServiceHalBuildConfiguration的类型,取名为ServerTimeHalBuildConfiguration:
using Apworks.Integration.AspNetCore.DataServices; using Hal.Builders; using Microsoft.AspNetCore.Http.Extensions; using System; namespace CustomerService { public class ServerTimeHalBuildConfiguration : DataServiceHalBuildConfiguration { protected override void RegisterHalBuilderFactoryForGetAll() { this.RegisterHalBuilderFactory("*.Get(int, int)", context => new ResourceBuilder() .WithState(new { ServerTime = DateTime.UtcNow }) .AddSelfLink().WithLinkItem(context.HttpContext.Request.GetEncodedUrl()) .AddEmbedded(context.ControllerAction.ControllerName.ToLower()) .Resource(new ResourceBuilder().WithState(context.State)) ); } } }
然后,回到Startup.cs文件中的ConfigureServices方法,在DataServiceConfigurationOptions的构造函数参数中,指定halBuildConfigurationFactory参数,代码如下:
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddApworks() .WithDataServiceSupport(new DataServiceConfigurationOptions (new MongoRepositoryContext (new MongoRepositorySettings("localhost", "customer-service")), halBuildConfigurationFactory: _ => new ServerTimeHalBuildConfiguration())) .Configure(); }
OK,任务完成,测试一下。打开MINGW,执行curl http://localhost:2238/api/customers -i命令,看看结果如何:
可以看到,我们已经在返回的HAL结果中加入了服务器的UTC时间,同时,还是保留了_self的链接。不过,分页的链接没有包含在内,这是因为我们通过override重写了RegisterHalBuilderFactoryForGetAll方法。你可以参考Apworks框架源代码中的Apworks.Integration.AspNetCore.DataServices.DataServiceHalBuildConfiguration类来了解如何将分页的链接加入到HAL的返回结果中。
大致对上面的代码做一些介绍:
- DataServiceHalBuildConfiguration及其子类主要负责对HAL Resource Builder(Builder模式,[GoF95])的定义和注册,它能将某一个HAL的资源构造器(Resource Builder)关联到某一个ASP.NET Core Web API的控制器上
- RegisterHalBuilderFactory方法会根据其第一个参数(ControllerActionSignature)确定一个ASP.NET Core Web API的Controller Action方法,并将第二个参数所指定的HAL Resource Builder工厂方法委托(Delegate)注册到由ControllerActionSignature指定的Controller Action方法上
- 在HalResultFilterAttribute类中,当Controller Action执行完成时,会根据所注册的Hal Resource Builder Factory来获取最终的HAL内容(通过调用ResourceBuilder的Build方法),然后将产生的HAL以application/hal+json格式返回
- 在SupportsHalAttribute类中会根据是否存在一个IHalBuildConfiguration的Service注册,来确定是否使用HAL的返回内容
- DataServiceController类已经使用了SupportsHalAttribute,因此,它具有使用HAL功能的能力,那么继承于它的控制器都会被应用SupportsHalAttribute特性,因此,你开发的数据服务控制器(Data Service Controller)无需关注HAL的功能
- 最后,在DataServiceConfigurationOptions类的构造函数中,通过指定useHalSupport以及halBuildConfigurationFactory两个参数,来决定是否需要HAL的支持,以及如何产生HAL的结果
事实上,如果你不打算使用DataServiceController来快速开发数据服务,而是希望使用传统的方式自己开发自己的RESTful服务,你完全可以使用Apworks.Integration.AspNetCore.Hal命名空间下的类型来使得你的RESTful服务也支持流行的HAL,而且开发过程非常方便。由此可见,Apworks.Integration.AspNetCore中对HAL的支持并不是专为框架本身的数据服务开发而设计的,它能够应用于普通的RESTful服务的开发,数据服务只不过是HAL的一个客户而已。
总结
本文介绍了Apworks数据服务开发中对HAL的支持,可以看到,Apworks框架的设计是:
- 灵活的:通过不同的配置信息来干预数据服务的执行过程,同时还支持自定义扩展来定制自己的数据服务
- 通用的:组件的设计尽可能达到通用性,比如HAL的机制,它不仅仅是Apworks数据服务的“特供”,它可以被应用在任何由ASP.NET Core Web API所开发的RESTful服务上
- 开发体验友好的:简单的API定义使得应用程序快速开发成为可能,Fluent Interface API(流畅接口)的设计,使得开发者能够用更为自然的语言来完成所需要的功能操作,大大提升开发生产率。在Apworks的整个框架中,会更多地引入流畅接口以便保持较好的开发者体验
就HAL这部分来说,它利用了ASP.NET Core中的ResultFilter以及Filter Factory,建议大家可以了解一下HAL以及Data Service的相关代码,来熟悉ASP.NET Core中Filter的相关内容。
值得一提的是,Apworks中对HAL的支持使用的正是我自己开发的HAL库,这套库也是开源的,开源地址是:https://github.com/daxnet/hal,它是为数较少的完整实现HAL规范,并支持.NET Core的HAL开发库,同样,它支持流畅接口。
下一讲打算介绍一下如何在Apworks数据服务中使用Entity Framework Core。敬请期待。
相关文章
- ASP .NET CORE 源码地址
- ASP.NET Core 2.0 MVC 发布部署--------- IIS 具体操作
- ASP.NET Core 2.0 MVC 发布部署--------- SUSE 16 Linux Enterprise Server 12 SP2 X64 具体操作
- ASP.NET Core之多语言配置
- ASP.NET Core分布式缓存Redis主从Sentinel哨兵模式实战演练
- ASP.NET Core WebAPI基于IdentityServer4实现Token令牌身份认证
- 进入ASP .net mvc的世界
- ASP.NET中使用HttpWebRequest调用WCF
- ASP.NET利用JQuery实现AJAX(前台脚本代码)调用后台静态方法
- Asp.Net中使用Couchbase——Memcached缓存入门篇
- asp.net中C#对象与方法 属性详解
- ASP.NET MVC3中Controller与View之间的数据传递总结
- 【ASP.NET Core】依赖注入高级玩法——如何注入多个服务实现类
- asp .net 为图片添加文字水印(内包含有加图片水印的方法) .
- ASP.NET MVC - The view must derive from WebViewPage, or WebViewPage<TModel>
- 【转】在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求
- IIS 编译器错误消息: CS0016未能写入输出文件“c:WINDOWSMicrosoft.NETFrameworkv1.1.4322Temporary ASP.NET Filesroo
- ASP.NET Core 6框架揭秘实例演示[17]:利用IHttpClientFactory工厂来创建HttpClient
- 《ASP.NET Core 3框架揭秘》博文汇总
- ASP.NET Core的路由[4]:来认识一下实现路由的RouterMiddleware中间件
- Atitit ..Net Framework sdk 3.0 3.5 4.04.5 4.6 4.7 .net core版本新特性 v2 s22 1. 新特性来源于 down ms 官方网站1
- ASP.NET MVC - 样式和布局
- ASP.NET,C#后台调用前台javascript的五种方法
- Asp.net Core中实现自定义身份认证
- asp.net core mvc权限控制:分配权限
- Crk:TX Text Control .NET Server for ASP.NET 31.0 SP1