简体   繁体   English

对于树层次结构,REST URL架构应该如何?

[英]How should a REST URL schema look like for a tree hierarchy?

Let's assume that I have stores, shelves in a store, and products on a shelf. 我们假设我有商店,商店货架和货架上的产品。 So in order to get a list of products on a shelf in a store, I'd use the following request: 因此,为了获得商店货架上的产品列表,我将使用以下请求:

GET http://server/stores/123/shelves/456/products

From here, how would I get an individual product? 从这里,我如何获得个别产品? Should I use: 我应该使用:

GET http://server/products/789

Or: 要么:

GET http://server/stores/123/shelves/456/products/789

The first method is more concise, since once you get a list of products, you don't really care which store it belongs to if you just want to view the details for a particular product. 第一种方法更简洁,因为一旦获得产品列表,如果您只想查看特定产品的详细信息,则不关心它属于哪个商店。 However, the second method is more logical, since you're viewing the products for a specific shelf in a specific store. 但是,第二种方法更符合逻辑,因为您正在查看特定商店中特定货架的产品。

Likewise, what about a PUT/DELETE operation? 同样,PUT / DELETE操作怎么样?

DELETE http://server/stores/123/shelves/456/products/789

Or: 要么:

DELETE http://server/products/789

What would be the correct way of designing a schema for a tree hierarchy like this? 为这样的树层次结构设计模式的正确方法是什么?

PS If I'm misunderstanding something about the REST architecture, please provide examples on how I can make this better. PS如果我误解了有关REST架构的一些内容,请提供有关如何使其更好的示例。 There's way too many people who love to say "REST is not CRUD" and "REST is not RPC", then provide absolutely no clarifications or examples of good RESTful design. 有太多人喜欢说“REST不是CRUD”和“REST不是RPC”,然后绝对没有提供良好RESTful设计的澄清或示例。

I've noted 2 approaches to RESTful URI design: hierarchical & filtered 我已经注意到RESTful URI设计的两种方法: 分层和过滤

I feel hierarchical is overly verbose, has the potential for redundant endpoints (not DRY) and disguises in what resource's state you're really interested (after all, REST = representational state transfer). 我认为层次结构过于冗长,有可能存在冗余端点(而不是DRY),并且伪装成您真正感兴趣的资源状态(毕竟,REST = 代表性状态转移)。

I favor Simple URIs 我赞成简单的URI

Simple is elegant. 简单优雅。 I'd choose a URI structure like 我会选择像这样的URI结构

GET http://server/products/789

because I am interested in the state of the product resource. 因为我对产品资源的状态感兴趣。

If I wanted all products that belonged to a specific shelf at a specific store, then I would do 如果我想要所有属于特定商店特定货架的产品,那么我会这样做

GET http://server/products?store=123&shelf=456

If I wanted to create a product at a specific store on a specific shelf then I'd post 如果我想在特定货架上的特定商店创建产品,那么我会发布

{
    product: {
        store: 123,
        shelf: 456,
        name: "test product"
    }
}

via 通过

POST http://server/products

Ultimately, it's tomayto, tomahto 最终,它是tomayto,tomahto

REST doesn't require one over the other. REST不需要一个在另一个上。 However, in my own experience, it is more efficient to consume a RESTful API that maps single entities to single endpoints (eg: RestKit object mappings on iOS) instead of having an entity map to many different endpoints based on what parameters are passed. 但是,根据我自己的经验,使用将单个实体映射到单个端点的RESTful API(例如:iOS上的RestKit对象映射)而不是根据传递的参数将实体映射到许多不同的端点更有效。

About REST 关于REST

As far as REST, it is not a protocol and has no RFC. 就REST而言,它不是协议,也没有RFC。 It is tightly related to the HTTP/1.1 RFC as a way to implement its CRUD actions, but many software engineers will posit that REST does not depend on HTTP. 它与HTTP / 1.1 RFC紧密相关,作为实现其CRUD操作的一种方式,但许多软件工程师会认为REST不依赖于HTTP。 I disagree and consider such as conjecture, because the original dissertation by UCI's Roy Fielding ( http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm ) explains the deep rooted connection of REST and HTTP/1.1. 我不同意并考虑诸如猜想,因为UCI的Roy Fielding的原始论文( http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm )解释了REST和HTTP /的深层次连接1.1。 You may also enjoy Roy's opinion on the topic: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven . 您也可以享受Roy对该主题的看法: http//roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

The principles defined by REST can be applied to other protocols, but REST was built for the internet and HTTP is the protocol for the world wide web. REST定义的原则可以应用于其他协议,但REST是为互联网构建的,而HTTP是万维网协议。

REST vs RPC REST与RPC

RPC is all about making calls to remote functions and is verb-centric . RPC就是要调用远程函数,而且是以动词为中心的

REST is all about using the CRUD convention to act on data depending on how the CRUD operation applies to a given data type and is noun-centric . REST就是使用CRUD约定来处理数据,具体取决于CRUD操作如何应用于给定的数据类型并且是以名词为中心的

You can accomplish the same things with REST or RPC, but REST follows DRY principles because for every URI you can perform 4 actions whereas RPC requires an endpoint for each action. 您可以使用REST或RPC完成相同的操作,但REST遵循DRY原则,因为对于每个URI,您可以执行4个操作,而RPC需要每个操作的端点。

PS PS

Much of this is my opinion and based on my experiences, but I hope it sheds some light on how you could most efficiently design a RESTful URI schema. 这很大程度上是我的看法,并且基于我的经验,但我希望它能说明如何最有效地设计RESTful URI模式。 As always, your specific goals and needs will affect your choices, but simplicity is always a good target for which to aim. 与往常一样,您的具体目标和需求将影响您的选择,但简单性始终是目标的良好目标。

Creating a product should just be a POST to 创建产品应该只是一个POST

http://server/product

Updating a product should just be a PUT to 更新产品应该只是一个PUT

http://server/product/$id

Getting a product should just be a GET to 获得产品应该只是一个GET

http://server/product/$id

Deleting a product should just be a DELETE to 删除产品应该只是一个删除

http://server/product/$id

You should use the http methods that are there for you to get more functionality out of a simpler uri structure. 您应该使用那里的http方法从更简单的uri结构中获取更多功能。 If creating a product requires a passing in a store and shelf as a requirement, then those should get passed in the body of your POST (or PUT if you're changing shelves). 如果创建产品需要传递商店和货架作为要求,那么这些应该在POST的主体中传递(或者如果您要更换货架,则传递PUT)。

When someone does a GET to http://server/product/$id , they will get back some kind of xml/json response, right? 当有人对http://server/product/$id进行GET时,他们会得到某种xml / json响应,对吧? What does that look like? 那是什么样的? The incoming data for a create or update should be POSTed or PUT the same way in the body of the request. 创建或更新的传入数据应在请求正文中以相同的方式进行POST或PUT。 That is how you pass in the store and shelf, not via the uri. 这就是你如何通过商店和货架,而不是通过uri。 The uri should be as simple as possible and just point to the resource (product), using the http verbs to differentiate functionality. uri应该尽可能简单,只需指向资源(产品),使用http动词来区分功能。

If you want to be able to get the contents of shelf 23, you do a GET to 如果你想获得货架23的内容,你可以去GET

http://server/shelf/23

When you do, you get back a json / xml / custom media type document that has the shelf data and a collection of product elements with links back to their product uri. 当您这样做时,您将获得一个json / xml / custom媒体类型文档,其中包含货架数据和一组产品元素,其中包含返回其产品uri的链接。

If you want to be able to move product 23 from one shelf to another, you do a PUT to 如果您希望能够将产品23从一个架子移动到另一个架子,那么您需要进行PUT操作

http://server/product/23 

In the body of the PUT you have the product in the representation of your choice, but with the updated shelf. 在PUT的主体中,您可以选择代表您的产品,但使用更新的货架。

It's a weird mode of thinking at first, because you're not dealing with functionality across the entire system, but instead focusing on the resources (product, shelf, store) and using the http verbs to expose them to the universe. 一开始这是一种奇怪的思维模式,因为你不是在处理整个系统的功能,而是专注于资源(产品,货架,商店)并使用http动词将它们暴露给宇宙。

Since products may be in several stores or several shelves (categories?), I'd have each product have a unique number regardless of its position in the hierarchy. 由于产品可能在几个商店或几个货架(类别?),我会让每个产品都有一个唯一的数字,无论它在层次结构中的位置如何。 Then use the flat product number. 然后使用扁平产品编号。 That makes the API more stable when some products are for instance moved in your store. 这使得API在您的商店中移动某些产品时更加稳定。

In short, don't add unneeded redundancy to your API. 简而言之,不要在API中添加不必要的冗余。 To get a shelve list a store ID is enough, for a product list a shelve ID is enough... etc. 要获得货架清单商店ID就足够了,对于产品清单,货架ID就够了......等等。

Don't design a REST api based on an URL structure. 不要基于URL结构设计REST api。 Here is how I think you should go about designing a REST api. 以下是我认为您应该如何设计REST API。

Trying to define a REST interface without discussing what links will be contained in what resources is like discussing an RPC interface and ignoring parameters and return values. 尝试定义REST接口而不讨论哪些链接将包含在哪些资源中,就像讨论RPC接口并忽略参数和返回值一样。

it seems like you are trying to build many different use cases, but everything is getting built into one super service. 看起来你正在尝试构建许多不同的用例,但所有内容都被构建到一个超级服务中。 It would be better to break it out. 打破它会更好。

http://server/product_info/123123 or http://server/product_info?product=123123
http://server/product_inventory?store=123&shelf=345

then you can also support: 那么你也可以支持:

http://server/product_inventory?store=123

then PUT and DELETE makes sense for changing inventory or adding a new product. 然后PUT和DELETE对于更改库存或添加新产品有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 根据 url 示例,axios 的参数应该如何 - How should the parameters for axios look like according to the url example 与Windows路径名相对应的文件:URI应该是什么样的? - How should a file: URI corresponding to a Windows path name look like? ASP .NET MVC 如何使 Url 看起来像 POST 而不是 GET - ASP .NET MVC How to make Url that look like POST not GET 使String在TableModel中看起来像url - Make String look like url in TableModel 如何使URL看起来像“ / lobby / 1”而不是“ /lobby.php?id=1”? - How do I make a URL to look like “/lobby/1” instead of “/lobby.php?id=1”? blogpost的rss提供的分页网址是什么样的? - What does blogpost's rss feed pagination url look like? 在为我们的应用程序形成REST URL时,如何区分与同一对象相关的两个服务? - While forming a REST URL for our application, how should we differentiate two services related to the same object? Using Django, should I implement two different url mapping logics in my REST API and web application, and how? - Using Django, should I implement two different url mapping logics in my REST API and web application, and how? 使用虚拟主机和URL重写时,请求的URL外观如何? - How will the URL requested look when using vhost and url rewriting? 如何在 Django 应用程序中处理 URL 模式中的参数 - How to deal with params in URL schema in Django application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM