我正在寻找以下用例的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),而是对象的所有字段一起形成主键(此约束存在于数据库层中)。
我们无法灵活地更改此域模型以添加单个字段唯一标识符。
所以我的问题如下 - 如果我想在这个为CREATE,UPDATE,DELETE和GET Vehicle提供简单功能的域对象之上添加一个简单的REST API,那么PATH端点的最佳实践是什么?方法
按照上面的例子,如果域模型具有单个字段唯一标识符vehicleId,那么我可以想象以下端点:
GET /vehicles/:vehicleId
PUT /vehicles/:vehicleId
DELETE /vehicles/:vehicleId
我不知道复合键存在与此类似的模式:
GET /vehicles/:vehicleTypecolourtransmissionyearOfIssue
GET /vehicles/CarRedAutomatic2008
似乎不正确。
对于此用例的良好模式的任何建议将不胜感激。
由于
答案 0 :(得分:3)
在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)
答案 1 :(得分:1)
要实现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:Get 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>
}