NET Core中使用Apworks

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的开发支持。首先我们回顾一下这段代码:

1
2
3
4
5
6
7
8
9
10
11
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即可:

1
2
3
4
5
6
7
8
9
10
11
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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参数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
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 BuilderBuilder模式,[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。敬请期待。

NET Core中使用Apworks的更多相关文章

  1. 在ASP.NET Core中使用Apworks快速开发数据服务

    不少关注我博客的朋友都知道我在2009年左右开发过一个名为Apworks的企业级应用程序开发框架,旨在为分布式企业系统软件开发提供面向领域驱动(DDD)的框架级别的解决方案,并对多种系统架构风格提供支 ...

  2. 在ASP.NET Core中使用Apworks开发数据服务:对HAL的支持

    HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单.统一的形式,在API中引入超链接特性,使得API的可发现性(discoverable ...

  3. 使用Angular 4、Bootstrap 4、TypeScript和ASP.NET Core开发的Apworks框架案例应用:Task List

    最近我为我自己的应用开发框架Apworks设计了一套案例应用程序,并以Apache 2.0开源,开源地址是:https://github.com/daxnet/apworks-examples,目的是 ...

  4. 在.NET Core中使用Irony实现自己的查询语言语法解析器

    在之前<在ASP.NET Core中使用Apworks快速开发数据服务>一文的评论部分,.NET大神张善友为我提了个建议,可以使用Compile As a Service的Roslyn为语 ...

  5. NET Core中使用Irony

    在.NET Core中使用Irony实现自己的查询语言语法解析器   在之前<在ASP.NET Core中使用Apworks快速开发数据服务>一文的评论部分,.NET大神张善友为我提了个建 ...

  6. .NET Core中的认证管理解析

    .NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...

  7. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  8. Asp.net Core中使用Session

    前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...

  9. 在ASP.NET Core中使用百度在线编辑器UEditor

    在ASP.NET Core中使用百度在线编辑器UEditor 0x00 起因 最近需要一个在线编辑器,之前听人说过百度的UEditor不错,去官网下了一个.不过服务端只有ASP.NET版的,如果是为了 ...

随机推荐

  1. jQuery 获取有多个class名的元素

    HTML内容: <div class="write-upload"> <p class="write-files old-files"> ...

  2. latex编译过程-关于嵌入所有字体

    我们的初始目的是想在编译的过程中嵌入所有字体 参考 我们进行了设置,但是不起作用,后发现使用pdflatex编译时是不会调用 ps2pdf的 然后,我们就需要了解编译过程 1. 通常,我们使用texs ...

  3. 联系E-R:学生选课系统

  4. swift的arc 是不是有问题?

    class Arctest { let name: String = "Arctest" @lazy var ret:() -> String? = { [weak self ...

  5. 解决 maps to localhost, but this does not map back to the address

    修改  /etc/ssh/ssh_config vim  /etc/ssh/ssh_config GSSAPIAuthentication no

  6. 1123 Is It a Complete AVL Tree(30 分)

    An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...

  7. 51 nod 1522 上下序列——序列dp

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522 很好的思想.考虑从小到大一对一对填数,这样也能对它的大小限制 ...

  8. CF 438 E & bzoj 3625 小朋友和二叉树 —— 多项式开方

    题目:http://codeforces.com/contest/438/problem/E https://www.lydsy.com/JudgeOnline/problem.php?id=3625 ...

  9. python set集合的用法

    python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和 ...

  10. wamp + wordpress 安装

    WAMP是一个windows上的php开发集成环境,一键安装php,apache和mysql,非常方便. 双击wampserver2.2exxxxxxxxxx.exe文件进行安装,安装过程中直接下一步 ...