在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。敬請期待。
原文地址:http://www.cnblogs.com/daxnet/p/6701119.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的在ASP.NET Core中使用Apworks开发数据服务:对HAL的支持的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于C#.NET的高端智能化网络爬虫
- 下一篇: ASP.NET Core 网站在Dock