REST API方法的组合键

时间:2015-09-07 21:11:25

标签: api rest

我正在寻找以下用例的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

似乎不正确。

对于此用例的良好模式的任何建议将不胜感激。

由于

2 个答案:

答案 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)

enter image description here

答案 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>
    }