在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的返回结果中。

大致对上面的代码做一些介绍:

  1. DataServiceHalBuildConfiguration及其子类主要负责对HAL Resource Builder(Builder模式,[GoF95])的定义和注册,它能将某一个HAL的资源构造器(Resource Builder)关联到某一个ASP.NET Core Web API的控制器上

  2. RegisterHalBuilderFactory方法会根据其第一个参数(ControllerActionSignature)确定一个ASP.NET Core Web API的Controller Action方法,并将第二个参数所指定的HAL Resource Builder工厂方法委托(Delegate)注册到由ControllerActionSignature指定的Controller Action方法上

  3. 在HalResultFilterAttribute类中,当Controller Action执行完成时,会根据所注册的Hal Resource Builder Factory来获取最终的HAL内容(通过调用ResourceBuilder的Build方法),然后将产生的HAL以application/hal+json格式返回

  4. 在SupportsHalAttribute类中会根据是否存在一个IHalBuildConfiguration的Service注册,来确定是否使用HAL的返回内容

  5. DataServiceController类已经使用了SupportsHalAttribute,因此,它具有使用HAL功能的能力,那么继承于它的控制器都会被应用SupportsHalAttribute特性,因此,你开发的数据服务控制器(Data Service Controller)无需关注HAL的功能

  6. 最后,在DataServiceConfigurationOptions类的构造函数中,通过指定useHalSupport以及halBuildConfigurationFactory两个参数,来决定是否需要HAL的支持,以及如何产生HAL的结果

事实上,如果你不打算使用DataServiceController来快速开发数据服务,而是希望使用传统的方式自己开发自己的RESTful服务,你完全可以使用Apworks.Integration.AspNetCore.Hal命名空间下的类型来使得你的RESTful服务也支持流行的HAL,而且开发过程非常方便。由此可见,Apworks.Integration.AspNetCore中对HAL的支持并不是专为框架本身的数据服务开发而设计的,它能够应用于普通的RESTful服务的开发,数据服务只不过是HAL的一个客户而已。

总结

本文介绍了Apworks数据服务开发中对HAL的支持,可以看到,Apworks框架的设计是:

  1. 灵活的:通过不同的配置信息来干预数据服务的执行过程,同时还支持自定义扩展来定制自己的数据服务

  2. 通用的:组件的设计尽可能达到通用性,比如HAL的机制,它不仅仅是Apworks数据服务的“特供”,它可以被应用在任何由ASP.NET Core Web API所开发的RESTful服务上

  3. 开发体验友好的:简单的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。敬请期待。

原文地址:http://www.cnblogs.com/daxnet/p/6701119.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326010.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.net三层架构开发步骤

City城市表,id ,name,password,address,phone; 1.新建一个windows窗体应用程序,CitySys 2.文件–》添加–》新建项目–》类库(CitySysModel)–》重命名class1.cs的类(CityModel)。 3.根据数据表里面的字段&…

JAVA多线程和并发面试问题

转载自 JAVA多线程和并发面试问题 Java多线程面试问题 1.进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的…

C#各个版本中的新增特性详解

序言 自从2000年初期发布以来,c#编程语言不断的得到改进,使我们能够更加清晰的编写代码,也更加容易维护我们的代码,增强的功能已经从1.0搞到啦7.0甚至7.1,每一次改过都伴随着.NET Framework库的相应支持,也…

微内核操作系统能做服务器系统吗,科普:微内核操作系统现状

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼微内核结构是1980年代产生出来的较新的内核结构,强调结构性部件与功能性部件的分离。20世纪末,基于微内核结构,理论界中又发展出了超微内核与外内核等多种结构。尽管自1980年代起,大部…

2019蓝桥杯省赛---java---A---8(修改数组)

题目描述 思路分析 不是每次1了,而是直接加相同数字出现过的次数,比如有3个1,第二个1就是1,第三个直接2,而不是两次1,而且每次都记录每次的新值出现的次数,这样循环到新数未出现过为止 代码实…

HTML、sqlserver数据库和java前七章节的复习(一)

1.HTML的基本结构 <!doctype> <html><head><title></title></head><body></body> </html>2.有序列表 <ol><li></li></ol>3.无序列表 <ul><li></li></ul>4.写一个边…

Java异常面试问题

转载自 Java异常面试问题 1.什么是Java中的异常&#xff1f; 异常是在程序执行期间可能发生的错误事件&#xff0c;并且会中断它的正常流程。异常可能来自不同类型的情况&#xff0c;例如用户输入的错误数据&#xff0c;硬件故障&#xff0c;网络连接故障等。 每当执行jav…

复习总结01110

.1.//从控制台输入3个数&#xff0c;然后按从小到输出public static void test_num(){Scanner sc new Scanner(System.in);System.out.println("请输入第一个数&#xff1a;");int num1 sc.nextInt();System.out.println("请输入第二个数&#xff1a;");…

ASP.NET Core 网站在Docker中运行

Docker作为新一代的虚拟化方式&#xff0c;未来肯定会得到广泛的应用&#xff0c;传统虚拟机的部署方式要保证开发环境、测试环境、UAT环境、生产环境的依赖一致性&#xff0c;需要大量的运维人力&#xff0c;使用Docker我们可以实现一次部署&#xff0c;到处运行。 本文介绍如…

键值存储之外,Redis还有这些用法

转载自 键值存储之外&#xff0c;Redis还有这些用法 Redis是一个强大的内存数据结构存储&#xff0c;包含数据库&#xff0c;缓存和消息代理等多种用途。大多数人经常认为它不过是一个简单的键值存储&#xff0c;但其实它有更多的能力。下面给出一些实例 1.全页面缓存 首先…

2018蓝桥杯省赛---java---C---3(字母阵列)

题目描述 测试数据 FOAIQNALWIKEGNICJWAOSXDHTHZPOLGYELORAUHOHCZIERPTOOJUITQJCFNIYYQHSBEABBQZPNGYQTCLSKZFCYWDGOAIADKLSNGJ GSOZTQKCCSDWGUWAUOZKNILGVNLMCLXQVBJENIHIVLRPVVXXFTHQUXUAVZZOFFJHYLMGTLANQIAOQQILCDCJERJASNCTLYGRMHGF TSDFYTLVIBHKLJVVJUDMKGJZGNNSTPVLCKT…

复习总结0111

1.从控制台中输入三个数&#xff0c;然后从小到大输出 public static void mian(String []args){Scanner sc new Scanner(System.in);System.out.println("请输入第一个数&#xff1a;");int a sc.nextInt();System.out.println("请输入第二个数&#xff1a;&…

sql基本命令整理

1、 查看数据库中的表或查询数据库&#xff1b; show tables/databases&#xff1b; 2、 查看数据库中所有的表 show tables&#xff1b;&#xff08;前提是使用use database 数据库&#xff1b;&#xff09; 3、 查看数据表结构 describe 表名&#xff1b; 4、 创建数据…

微软确认5月2日召开新品发布会 8天后就是Build 2017大会

援引外媒 ZDNet 报道&#xff0c;微软计划在 5 月上旬召开新品发布会&#xff0c;重点围绕着 Windows 10 Cloud&#xff0c;并且有望公布关于 Surface Pro 5 的相关信息。今天这条消息已经得到了证实&#xff0c;微软官方宣布将于 5 月 2 日将会在纽约召开发布会&#xff0c;也…

面试进阶之字符串常量池

转载自 面试进阶之字符串常量池 作为最基础的引用数据类型&#xff0c;Java 设计者为 String 提供了字符串常量池以提高其性能&#xff0c;那么字符串常量池的具体原理是什么&#xff0c;我们带着以下三个问题&#xff0c;去理解字符串常量池&#xff1a; 字符串常量池的设计…

java实现人脸识别V3版本开发

有段时间没有写更新公众号了&#xff0c;也许好多人都忘记了自己还关注了这么个公众号。因为这段时间确实是有其他的事比较忙&#xff0c;还有一个原因就是自己在技术方面没有学习新的东西&#xff0c;所以没有可更新的&#xff08;包括博客&#xff09;今天&#xff0c;我决定…

2018蓝桥杯省赛---java---A---7(三体攻击)

题目描述 题目&#xff1a;三体人将对地球发起攻击。为了抵御攻击&#xff0c;地球人派出了 A  B  C 艘战舰&#xff0c;在太空中排成一个 A 层 B 行 C 列的立方体。其中&#xff0c;第 i 层第 j 行第 k 列的战舰&#xff08;记为战舰 (i, j, k)&#xff09;的生命值为 …

23种设计模式彩图

原文地址&#xff1a;http://www.jianshu.com/p/4a02646f7c9d.NET社区新闻&#xff0c;深度好文&#xff0c;微信中搜索dotNET跨平台或扫描二维码关注

JDBC面试问题

转载自 JDBC面试问题 1.什么是JDBC API&#xff0c;何时使用它&#xff1f; Java DataBase Connectivity API允许我们使用关系数据库。JDBC API接口和类是 java.sql和javax.sql包的一部分。我们可以使用JDBC API来获取数据库连接&#xff0c;在数据库服务器中运行SQL查询和…

java实现人脸识别(使用百度云V3版本)

2017年&#xff0c;开发了第一个版本的人脸识别&#xff0c;当时费时有5天之久终于写出来了&#xff0c;但是只适用于火狐浏览器&#xff0c;别的浏览器都打不开摄像头。 2018年&#xff0c;将人脸识别重新完善&#xff0c;可以支持360、火狐、谷歌等主流浏览器&#xff0c;版…