Answers:
RESTful API设计的最佳实践是使用路径参数来标识一个或多个特定资源,而使用查询参数来对这些资源进行排序/过滤。
这是一个例子。假设您正在为称为Car的实体实现RESTful API端点。您将像这样构造端点:
GET /cars
GET /cars/:id
POST /cars
PUT /cars/:id
DELETE/cars/:id
这样,您仅在指定要提取的资源时才使用路径参数,但这不会以任何方式对资源进行排序/过滤。
现在,假设您想在GET请求中添加按颜色过滤汽车的功能。因为color不是资源(它是资源的属性),所以您可以添加执行此操作的查询参数。您可以将查询参数添加到GET/cars
请求中,如下所示:
得到 /cars?color=blue
将实现此端点,以便仅退回蓝色汽车。
就语法而言,您的URL名称应全部小写。如果您的实体名称通常是两个英文单词,则可以使用连字符来分隔单词,而不要使用驼峰式大小写。
例如 /two-words
思考此主题的基本方法如下:
URI是一种资源标识符,可以唯一地标识资源类型的特定实例。就像生活中的所有其他事物一样,每个对象(作为某种类型的实例)都具有时不变或时态的属性集。
在上面的示例中,汽车是非常有形的物体,具有诸如make,model和VIN的属性-永不改变,以及颜色,悬架等可能随时间改变的属性。因此,如果我们使用随时间(时间)变化的属性对URI进行编码,那么对于同一个对象,我们可能会获得多个URI:
GET /cars/honda/civic/coupe/{vin}/{color=red}
数年后,如果这辆完全相同的汽车的颜色变为黑色:
GET /cars/honda/civic/coupe/{vin}/{color=black}
请注意,汽车实例本身(对象)没有改变-只是颜色改变了。具有指向同一对象实例的多个URI将迫使您创建多个URI处理程序-这不是有效的设计,当然也不直观。
因此,URI应该仅由永不改变的部分组成,并将在整个生命周期中继续唯一地标识该资源。可能更改的所有内容都应保留给查询参数,例如:
GET /cars/honda/civic/coupe/{vin}?color={black}
底线-考虑多态性。
在REST API中,可预测的URI不应过分担心。URI可预测性的暗示暗示了对RESTful体系结构的误解。它假定客户端应该自己构造URI,而这实际上并不是必须的。
但是,我假设您不是在创建真正的REST API,而是在创建“受REST启发”的API(例如Google Drive)。在这些情况下,经验法则是“路径参数=资源标识”和“查询参数=资源排序”。因此,问题就变成了,您可以在没有状态/地区的情况下唯一地标识您的资源吗?如果是,则可能是查询参数。如果否,则其为路径参数。
HTH。
一旦我设计了一个API,其主要资源是people
。通常,用户会请求过滤,people
因此为了防止用户/people?settlement=urban
每次都调用类似的东西,我实现了/people/urban
该功能,后来使我能够轻松添加/people/rural
。/people
如果以后有任何用处,这也允许访问完整列表。简而言之,我的推理是为通用子集添加一条路径
从这里:
常见查询的别名
为了使普通用户对API的体验更加愉快,请考虑将条件集打包到易于访问的RESTful路径中。例如,上面最近关闭的票证查询可以打包为
GET /tickets/recently_closed
细分更加分层和“漂亮”,但可能会受到限制。
例如,如果您有一个包含三个细分的网址,则每个细分都传递不同的参数以通过品牌,型号和颜色搜索汽车:
www.example.com/search/honda/civic/blue
这是一个非常漂亮的url,更容易被最终用户记住,但是现在您受此结构的困扰。假设您要这样做,以便用户在搜索中可以搜索所有蓝色汽车或所有本田思域?查询参数解决了这个问题,因为它提供了一个键值对。这样您就可以通过:
www.example.com/search?color=blue
www.example.com/search?make=civic
现在,您可以通过其键在查询代码中引用值“ color”或“ make”。
您可以通过使用更多细分来创建一种键值结构来解决此问题,例如:
www.example.com/search/make/honda/model/civic/color/blue
希望有道理..