在 ASP.NET Web API 2 基礎下,建立整合完備的應用程式專案範本。

  • 整合套件或自行開發來提供 RESTFul API 最佳實踐 中的建議功能。
  • 配合 開發規範 提供一致有效率的開發方式及程式品質。

這篇介紹整合已有的套件,以達到對 RESTFul 最佳實踐的支援。

相關套件

  • Halcyon
  • SnakeCase.JsonNet
  • Compression.Server
  • CacheCow

HATEOAS

利用這個套件 Halcyon,可以簡單在現有 Model 上加上簡單 HAL 的連結,並支援 Accept Header 的判斷。也和 Halon 這個 HAL Javascript client 相容。

ASP.NET 4.5 安裝 Install-Package Halcyon.WebApi

在 model 加上 HAL 連結:

1
2
3
4
return HAL(model, new Link[] {
new Link("self", "/api/foo/{id}"),
new Link("foo:bar", "/api/foo/{id}/bar")
})

或利用 HALResponse class

1
2
3
4
5
6
var response = new HALResponse(model)
.AddLinks(linkOne)
.AddLinks(linkTwo)
.AddEmbeddedCollection(embeddedName, embedded);

return this.Ok(response);

套用 snake_case

Request 和 Response 轉換

套件:Install-Package SnakeCase.JsonNet

套用 SnakeCaseContractResolver
在 Global.asax 中 Application_Start() 加上

1
2
3
4
5
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new SnakeCaseContractResolver();

轉換後,輸出排版也改為 pretty print。

網址參數轉換

自行實作 ActionSelector,原理就是對 QueryString 做轉換和重寫。參考 自製篇 的介紹。

gzip 的支援

套件:Install-Package Microsoft.AspNet.WebApi.Extensions.Compression.Server

WebApiConfig.cs 加上

1
GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));

快取

Client 端配合互動才有效。

套件:Install-Package CacheCow.Server

WebApiConfig.cs 加上

1
GlobalConfiguration.Configuration.MessageHandlers.Add(new CachingHandler(GlobalConfiguration.Configuration));

資料預設儲存在本機的 memory 中。

要更完善的儲存機制,CacheCow 有提供 SQLServer、Memcached、Redis、MongoDB、RavenDB、ElasticSearch、Azure Caching 的儲存套件。

以 SQLServer 儲存快取資料

套件:Install-Package CacheCow.Server.EntityTagStore.SqlServer

修改 WebApiConfig.cs

1
2
3
4
var connectionString = ConfigurationManager.ConnectionStrings["ConnectionName"].ConnectionString;
var eTagStore = new SqlServerEntityTagStore(connectionString);
var cacheHandler = new CachingHandler(config, eTagStore);
config.MessageHandlers.Add(cacheHandler);

系列文章