[英]Composite key for REST API methods
我正在尋找以下用例的RESTful API設計的最佳實踐:
域對象工具:
class Vehicle {
private String vehicleType;
private String colour;
private String transmission;
private String yearOfIssue;
}
一個示例對象:
Vehicle = {vehicleType : 'Car', colour : 'Red', transmission : 'Automatic', yearOfIssue : '2008'};
在此域模型中,沒有單個字段唯一標識符(例如vehicleId),而是對象的所有字段一起形成主鍵(此約束存在於數據庫層中)。
我們無法靈活地更改此域模型以添加單個字段唯一標識符。
所以我的問題如下 - 如果我想在這個域對象之上添加一個簡單的REST API,為CREATE,UPDATE,DELETE和GET Vehicle提供簡單的功能,這些方法的PATH端點的最佳實踐是什么?
按照上面的例子,如果域模型具有單個字段唯一標識符vehicleId,那么我可以想象以下端點:
GET /vehicles/:vehicleId
PUT /vehicles/:vehicleId
DELETE /vehicles/:vehicleId
我不知道復合鍵存在的類似於此的模式:
GET /vehicles/:vehicleTypecolourtransmissionyearOfIssue
GET /vehicles/CarRedAutomatic2008
似乎不正確。
關於此用例的良好模式的任何建議將不勝感激。
謝謝
根據一般的REST標准,每個端點都會公開一個資源,客戶端可以使用http動詞來處理它們。 在此示例中,您的資源是車輛,客戶端使用GET從服務器獲取數據。 理想情況下,應使用唯一(單個)密鑰唯一標識每個資源。
但是您的資源(車輛)沒有單值唯一鍵,並且無法在系統中更改! 在這種情況下,您仍然可以使用所有必需參數進行GET調用以識別資源,就像任何其他標准http調用一樣
GET /vehicles?type=Car&color=Red&transmission=Automatic&manufactureYear=2008
您正在使用的技術/平台,如果允許為您的方法制作自定義路線,您可以創建類似的自定義路線
new route("/vehicles/{type}/{color}/{transmission}/{manufactureYear}")
並將您的服務稱為
GET /vehicles/Car/Red/Automatic/2008
關於這一點的好處是,你的uri變短了。 但另一方面[1]對於這種類型的所有方法/資源,你必須創建自定義路由,並且[2]除非你了解具體的方法和路由,否則這個uri沒有多大意義。
在ASP.NET Core中,我通常代表一個這樣的復合鍵:
POST /vehicles/(car:red:automatic:2008)
要么
POST /vehicles/(car|red|automatic|2008)
框架在按指定順序將這些映射到操作參數方面沒有問題。
[HttpPut("vehicles/({car}:{color}:{trans}:{year})")]
public async Task<IActionResult> Add(
string car, string color, string trans, int year, [FromBody] Vehicle request)
{
await Task.CompletedTask;
return Ok();
}
示例請求: PUT /vehicles/(Ford:Ranger:100% genuine:2000)
要成為RESTful,您需要創建一個唯一的標識符來擴充您的類。
class Vehicle {
public int vechicleId { get; set; }
public string vehicleType { get; set; }
public string colour { get; set; }
public string transmission { get; set; }
public string yearOfIssue { get; set; }
}
然后你可以使用HTTP訪問它:獲取http:// mysite / vehicles / 3842 。 但是,您可能無法訪問內部唯一標識符,尤其是在種子或更新數據庫時。 我遇到過類似的問題並使用REST動詞我將包含一個外部標識符,以便人類和外部系統更容易訪問記錄:
class Vehicle {
public int vechicleId { get; set; }
public string externalId { get; set; }
public string vehicleType { get; set; }
public string colour { get; set; }
public string transmission { get; set; }
public string yearOfIssue { get; set; }
}
然后動詞看起來像:HTTP:獲取http:// mysite / vehicles / externalId / sedanbluemanual2015 。 您不必解析URI,因為所有數據都應該在消息正文中,您只需要確保字符串唯一標識車輛。
[HttpPut("externalId/{externalId}")]
public IActionResult PutVehicle([FromRoute] string externalId, [FromBody] JObject jObject)
{
// See if the record exists already.
var oldVehicle = (from v in vehicles
where vehicle.ExternalId == externalId
select v).FirstOrDefault();
if (oldVehicle != null)
{
<insert new vehicle>
}
else
{
<update old vehicle>
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.