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的支持。html
在上一篇快速开发文章中,演练部分经过修改Startup.cs文件中的ConfigureServices方法以在ASP.NET Core Web API中启用Apworks以及Data Service的开发支持。首先咱们回顾一下这段代码:git
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格式的了:github
注意:因为返回的数据量并无超出一页的分页尺寸,因此在_links下仅显示了一个self的连接。若是存在多个分页,那么_links部分也会出现prev、next、first、last等连接。json
若是但愿禁用HAL的功能,其实很是简单,在上面的代码中,在构造DataServiceConfigurationOptions时直接指定useHalSupport参数为false便可:api
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的支持。服务器
在ASP.NET Core Web API中使用Apworks开发数据服务时,对于HAL的返回内容是能够自定义的。固然,这并不会改变HTTP Response的Content-Type,而是针对Response Body,其Json内容是能够被自定义的。例如,在上面的例子中,HTTP GET的Response Body中不只包含所请求的数据对象数组(customers),并且还包含分页信息,以及一个含有分页连接的_links的对象。在实现Data Service的时候,若是这些返回内容不能知足需求,开发人员彻底能够自定义。app
举个例子,假设咱们但愿在返回内容中包含当前的服务器时间,其开发过程以下。框架
首先,新建一个继承于Apworks.Integration.AspNetCore.DataServices.DataServiceHalBuildConfiguration的类型,取名为ServerTimeHalBuildConfiguration:less
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的返回结果中。
大体对上面的代码作一些介绍:
事实上,若是你不打算使用DataServiceController来快速开发数据服务,而是但愿使用传统的方式本身开发本身的RESTful服务,你彻底可使用Apworks.Integration.AspNetCore.Hal命名空间下的类型来使得你的RESTful服务也支持流行的HAL,并且开发过程很是方便。因而可知,Apworks.Integration.AspNetCore中对HAL的支持并非专为框架自己的数据服务开发而设计的,它可以应用于普通的RESTful服务的开发,数据服务只不过是HAL的一个客户而已。
本文介绍了Apworks数据服务开发中对HAL的支持,能够看到,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。敬请期待。