我希望我能解释一下令我不安的问题。
示例:我有一个包含产品对象列表的对象篮。所以通常我会建立像这样的baskets / {basketId} / products / {productId)的路线。但是产品是一个界面,并且有不同的实现,如CD和书籍都需要自己的资源表示。
那么我现在如何构建我的路线呢?
就像其中一个?:
baskets/{basketId}/products/{productId)/cds,
baskets/{basketId}/products/{productId)/books
等等
baskets/{basketId}/products/{productId)/cds/{productId} ,
baskets/{basketId}/products/{productId)/books/{productId}
baskets/{basketId}/cds/{productId},
baskets/{basketId}/books/{productId}
宁静的方式是什么?
答案 0 :(得分:2)
URI + Resource should define any Rest Endpoint.
在您的情况下,URI是
basket/{basketId}/product/{productId)
,资源为product
CDs and Books are just the type of resource. Its important you understand this.
所以可以定义为
/basket/{basketId}/product/{productId)?type=CD
/basket/{basketId}/product/{productId)?type=Book
答案 1 :(得分:1)
我认为可以使用下一种方式。我们有一个包含产品的篮子,所以每个产品都可以通过url:baskets/{basket_id}/products/{product_id}
来识别,如果你想指定具体的产品类型,这个url将代表普通产品(以json / form / etc的形式)应提供定义产品类型的查询参数,例如:baskets/{basket_id}/products/{product_id}?type=book
等。任何产品都将具有唯一标识符,但您应该控制具有提供的ID的产品具有您请求的类型。希望这会有所帮助。
另一种方法是,当您查询购物篮产品时,您可以返回某种快捷方式列表,该列表中的每个项目都将包含产品ID和产品类型ID。然后,要获得具体的产品,您应该使用具体的产品ID建造具体的产品网址。例如(如果我们使用json):
获取/baskets/{basket_id}/products
,获得[{ id: 1, type: "book"}, ...]
,然后获取/books/1
,但此方法需要两次服务器调用。
答案 2 :(得分:1)
认为更有活力,不要陷入静态语言的思考:我会保留baskets/{basketId}/products/{productId}
并返回多态类型。
这可以在java中实现:
public class BasketResponse {
private Product product;
}
public class Product {
private long id;
private String type;
}
public class CD extends Product {
private String albumName;
public CD() {
super.setType("CD");
}
}
这只适用于像json这样的动态数据类型。 Jackson使用实际类型的属性(而不是声明的类型)序列化对象。
在客户端,如果你使用像javascript这样的动态语言,那么这不是问题,因为你必须检查type
以查看你期望的属性。如果您使用的是像java这样的静态语言,则必须根据type
字段强制转换类型。通常Json framworks可以帮助您正确地投射您的类型(再次参见Jackson doc)
答案 3 :(得分:1)
Roy Fielding提供有关REST API的the following advice:
REST API不能定义固定资源名称或层次结构(客户端和服务器的明显耦合)。
因此,除此之外没有“RESTful”URI结构:不依赖于URI结构!
另请查看this answer至a similar question。
我认为您的界面/实现应该反映在媒体类型而不是uri路径中。