REST API方法的组合键

Jos*_*ies 23 api rest

我正在寻找以下用例的RESTful API设计的最佳实践:

域对象工具:

class Vehicle {
    private String vehicleType;
    private String colour;
    private String transmission;
    private String yearOfIssue;
}
Run Code Online (Sandbox Code Playgroud)

一个示例对象:

Vehicle = {vehicleType : 'Car', colour : 'Red', transmission : 'Automatic', yearOfIssue : '2008'};
Run Code Online (Sandbox Code Playgroud)

在此域模型中,没有单个字段唯一标识符(例如vehicleId),而是对象的所有字段一起形成主键(此约束存在于数据库层中).

我们无法灵活地更改此域模型以添加单个字段唯一标识符.

所以我的问题如下 - 如果我想在这个域对象之上添加一个简单的REST API,为CREATE,UPDATE,DELETE和GET Vehicle提供简单的功能,这些方法的PATH端点的最佳实践是什么?

按照上面的例子,如果域模型具有单个字段唯一标识符vehicleId,那么我可以想象以下端点:

GET /vehicles/:vehicleId
PUT /vehicles/:vehicleId
DELETE /vehicles/:vehicleId
Run Code Online (Sandbox Code Playgroud)

我不知道复合键存在的类似于此的模式:

GET /vehicles/:vehicleTypecolourtransmissionyearOfIssue
GET /vehicles/CarRedAutomatic2008
Run Code Online (Sandbox Code Playgroud)

似乎不正确.

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

谢谢

Arg*_*a C 16

根据一般的REST标准,每个端点都会公开一个资源,客户端可以使用http动词来处理它们.在此示例中,您的资源是车辆,客户端使用GET从服务器获取数据.理想情况下,应使用唯一(单个)密钥唯一标识每个资源.

但是您的资源(车辆)没有单值唯一键,并且无法在系统中更改!在这种情况下,您仍然可以使用所有必需参数进行GET调用以识别资源,就像任何其他标准http调用一样

GET /vehicles?type=Car&color=Red&transmission=Automatic&manufactureYear=2008
Run Code Online (Sandbox Code Playgroud)

您正在使用的技术/平台,如果允许为您的方法制作自定义路线,您可以创建类似的自定义路线

new route("/vehicles/{type}/{color}/{transmission}/{manufactureYear}")
Run Code Online (Sandbox Code Playgroud)

并将您的服务称为

GET /vehicles/Car/Red/Automatic/2008
Run Code Online (Sandbox Code Playgroud)

关于这一点的好处是,你的uri变短了.但另一方面[1]对于这种类型的所有方法/资源,你必须创建自定义路由,并且[2]除非你了解具体的方法和路由,否则这个uri没有多大意义.

  • 使用path比params更好地指定键,因为它适用于任何动词.您可以使用`POST/vehicles/Car/Red/Automatic/2008`更新实例 (5认同)
  • @JohnHenckel 根据 http://tools.ietf.org/html/rfc3986#section-3.4,查询参数是 URL 的一部分,因此您也应该能够 POST 给它们。见 /sf/answers/1444593881/ (3认同)
  • 我希望看到更大的问题得到解决:OP 的任务可以使用 REST 来完成,还是只是一个标准的 HTTP Get?我猜想如果没有一个唯一的标识符,它就不是 REST。 (2认同)

bug*_*d87 5

在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();
}
Run Code Online (Sandbox Code Playgroud)

请求示例: PUT /vehicles/(Ford:Ranger:100% genuine:2000)

在此处输入图片说明

  • 这是一个弱解决方案,因为它假设数据不包含任何特殊字符。例如,有人插入一辆带有名为“100%正品”变速器的汽车,那么 ASP.NET 将抛出异常。它不允许在路径中出现特殊字符。 (2认同)
  • @JohnHenckel这个答案专门针对“ ASP.NET Core”(如上所述),该框架允许特殊字符就好了。请参阅添加到答案的屏幕截图。 (2认同)