HAL,全稱爲Hypertext Application Language,它是一種簡單的數據格式,它能以一種簡單、統一的形式,在API中引入超連接特性,使得API的可發現性(discoverable)更強,並具備自描述的特色。使用了HAL的API會更容易地被第三方開源庫所調用,而且使用起來也很方便,開發者能夠像處理普通JSON數據那樣去處理API數據。有關HAL的更多信息,能夠參考官方網站:http://stateless.co/hal_specification.html。html
下面就是一個典型的使用HAL的API的響應數據。git
{ "_links": { "self": { "href": "/orders" }, "curies": [{ "name": "ea", "href": "http://example.com/docs/rels/{rel}", "templated": true }], "next": { "href": "/orders?page=2" }, "ea:find": { "href": "/orders{?id}", "templated": true } }, "currentlyProcessing": 14, "shippedToday": 20, "_embedded": { "ea:order": [{ "_links": { "self": { "href": "/orders/123" }, "ea:basket": { "href": "/baskets/98712" }, "ea:customer": { "href": "/customers/7809" } }, "total": 30.00, "currency": "USD", "status": "shipped" }, { "_links": { "self": { "href": "/orders/124" }, "ea:basket": { "href": "/baskets/97213" }, "ea:customer": { "href": "/customers/12369" } }, "total": 20.00, "currency": "USD", "status": "processing" }] } }
上面的JSON數據中,標註了高亮的幾行實際上是真正的數據部分,其它部分就是增長的一些超連接,用以定位與當前資源(對象)相關的其它資源。好比,在_embedded節點下包含了兩個訂單信息,在訂單信息的_links節點下,就包含了與該訂單相關的其它資源的訪問連接,例如能夠經過訪問/customers/7809連接,就能夠得到第一條訂單的客戶信息。另外,在HAL中,超連接是能夠爲模板的,模板連接能夠給定一個名稱,並指定templated爲true。例如,上面,,子中的curies連接,指定了API文檔的連接模板,那麼,經過訪問http://example.com/docs/rels/find,就能夠得到有關獲取某個銷售訂單詳細信息API的文檔,經過訪問http://example.com/docs/rels/order,就能夠得到有關銷售訂單API的文檔。此外,上面的例子中還包含了獲取下一頁數據的連接(next連接),所以,客戶端只須要調用一次API,就能得到與其相關的其它API的訪問連接。github
Java中Spring Data在新建的Data Service API都默認使用了HAL,返回數據格式是application/hal+json或者application/hal+xml(HAL能夠有JSON和XML兩種格式,本文只討論JSON格式)。因而,我基於.NET Core實現了HAL的編程模型,經過這個編程模型,從此就能很方便地在.NET Core Web API中啓用HAL的功能。項目的開源地址是:https://github.com/daxnet/hal。我也經過Jenkins持續集成,發佈了NuGet包,能夠支持.NET Framework 4.6.1以及Net Standard 1.6,這樣,既能夠在經典.NET Framework,又能夠在.NET Core中使用HAL庫。編程
在Visual Studio中,在NuGet Package Manager中添加NuGet Feed:https://www.myget.org/F/daxnet-utils/api/v3/index.jsonjson
而後,在控制檯應用程序(Console Application)項目上選擇Manage NuGet Packages,打開NuGet,Package source選擇剛剛添加的那個,而後選擇Hal後,點擊Install進行安裝。api
安裝完成後,輸入下面代碼:app
using System; using Hal.Builders; namespace ConsoleApp8 { public class Program { public static void Main(string[] args) { var builder = new ResourceBuilder(); var resource = builder .WithState(new { currentlyProcessing = 14, shippedToday = 20 }) .AddSelfLink().WithLinkItem("/orders") .AddCuriesLink().WithLinkItem("http://example.com/docs/rels/{rel}", "ea", true) .AddLink("next").WithLinkItem("/orders?page=2") .AddLink("ea:find").WithLinkItem("/orders{?id}", templated: true) .AddEmbedded("ea:order") .Resource(new ResourceBuilder() .WithState(new { total = 30.00F, currency = "USD", status = "shipped" }) .AddSelfLink().WithLinkItem("/orders/123") .AddLink("ea:basket").WithLinkItem("/baskets/98712") .AddLink("ea:customer").WithLinkItem("/customers/7809")) .Resource(new ResourceBuilder() .WithState(new { total = 20.00F, currency = "USD", status = "processing" }) .AddSelfLink().WithLinkItem("/orders/124") .AddLink("ea:basket").WithLinkItem("/baskets/97213") .AddLink("ea:customer").WithLinkItem("/customers/12369")) .Build(); Console.WriteLine(resource); } } }
運行一下試試?是否已經輸出了前面例子中的HAL JSON數據(以下)?less
這個開發庫的一個亮點就是使用了流暢接口(Fluent API)的編程風格,開發人員可以很是方便地使用此庫來產生所需的HAL數據。流暢接口的實現結合了裝飾器(Decorator)模式和C#的擴展方法,都定義在Hal.Builders命名空間下,有興趣的讀者能夠下載源代碼查看。網站
附上整個HAL的對象模型類圖:ui
相信本庫應該是.NET Core下第一個比較完整地實現了HAL規範的開源庫,它發佈在MIT許可協議之下,商業友好,歡迎使用並提寶貴意見。在發現Bug後,也歡迎在Issue中提出,或者提交Pull Request。