REST 操作和 URL API 设计注意事项

我正在构建一个库存管理系统,我正忙于设计(思考) API 和 REST 实现。

我有以下资源,在这些资源上你可以执行许多操作。 每个操作都会修改资源,在某些情况下还会创建新资源,并创建历史记录或事务。

我正在寻找一些关于 URL 和资源设计的可用性和可接受性方面的专家意见。陷阱和现实世界的例子,任何意见或批评欢迎。

我担心的是,整个应用程序可能是围绕这一大型资源开发的? 我的后端堆栈将是 C # 和服务堆栈框架,对于前端,我将使用 HTML 和 AngularJS。不过也没什么区别。

场景1。 典型操作包括:

POST /inventory/{id}/move
POST /inventory/{id}/scrap
PUT  /inventory/{id}/takeon
POST /inventory/{id}/pick
PUT  /inventory/{id}/receive
POST /inventory/{id}/hold
POST /inventory/{id}/release
POST /inventory/{id}/transfer
POST /inventory/{id}/return
POST /inventory/{id}/adjustment




{
"userID": "",       //who is doing the actions (all)
"tolocationID": "", //new location for inventory (move/takeon/pick/receive/transfer/return)
"qty": "",          //qty (pick/receive/takeon/transfer/return)
"comment": "",      //optional for transaction (all)
"serial": "",       //(takeon/receive)
"batch": "",        //(takeon/receive)
"expirydate": "",   //(takeon/receive)
"itemCode": "",     //(takeon/receive)
"documentID": "",   //(pick/receive/return/transfer)
"reference" :"",    //(all)
"UOM" :"",          //(all)
"reference" :"",    //(all)
}

就标准而言,这是可以接受的吗。 另一种方法可能是。

场景2。

POST /inventory/{id}/move
POST /inventory/{id}/scrap
PUT  /inventory/{id}/takeon
POST /document/{id}/pick     //**document**
PUT  /document/{id}/receive  //**document**
POST /inventory/{id}/hold
POST /inventory/{id}/release
POST /document/{id}/transfer  //**document**
POST /document/{id}/return    //**document**
POST /inventory/{id}/adjustment

然后改变资源。

第三种情况,我认为是错误的

POST /transaction/move/{...}
POST /transaction/scrap/{...}
PUT  /transaction/takeon/{...}
POST /transaction/pick/{...}
PUT  /transaction/receive/{...}
POST /transaction/hold/{...}
POST /transaction/release/{...}
POST /transaction/transfer/{...}
POST /transaction/return/{...}
POST /transaction/adjustment/{...}

欢迎任何意见,不寻求答案,但更多的意见设计考虑?

感谢您花时间阅读这篇文章!

65835 次浏览

我有以下资源和资源,你可以执行 每个操作都会修改资源和 在某些情况下,创建一个新的资源,也创建历史或 交易。

REST 体系结构模式的基本思想是使用 HTTP 谓词作为惟一的谓词,而不在 URL 中包含谓词。如果我是你,我会考虑重新设计你的系统去掉动词。在不知道任何一个动词的意思的情况下,很难提出一个设计方案,但也许可以更接近于:

GET /inventory/{id}
PUT /inventory/{id} -- update with new location
PUT /inventory/{id} -- update with new status (scrapped)

etc .. That's a more RESTful approach. Many of these actions look like they're really just PUTs that update multiple properties of the resource, such as location, quantity, comment field, etc. And perhaps scrap is DELETE? Hard to tell.

另一种选择是使用 POST,其中正文包括关于如何操作库存物品的说明:

POST /inventory-transactions/{id}
{
"action": "takeon",
"newLocationId": 12345,
...
}

这为您提供了很多可跟踪性,因为现在可以将每个操作作为资源进行跟踪。缺点是端点周围的复杂性很大。

您还可以将一些“动词”操作划分为资源:

POST /returned-inventory
{
"inventoryId": 12345,
"documentId": 67890,
"comment": "Busted up",
...
}

这使您可以根据库存物品的状态轻松地查看它们,这可能有帮助,也可能没有帮助。例如,可以调用 GET /returned-inventory?documentId=67890从同一文档中返回所有返回的项。

希望里面有值得深思的东西。如果没有更详细地了解您的业务需求,任何人都不可能告诉您“正确”的事情。

“ RESTful Objects”定义了一个 RESTful API,声明操作是有效的。

可用操作可以被发现、启用/禁用,并且可以提供“禁用原因”反馈。

使用 GET (查询)、 PUT (幂等)或 POST (非幂等)“调用”操作

Restful Object Spec (页 C-125)

简短的回答 :

使用 URL 末尾的操作更改状态。

Github 是这样做的: PUT/gists/: gist _ id/star

这里有解释 Https://developer.github.com/v3/gists/#star-a-gist

详细回答 :

您的目标是让您的应用程序不费吹灰之力地使用一个直观的。你的用户应该以最简单的方式使用你的应用程序。您的用户不应该受到所使用技术的限制或硬性指导。

因此,操作和操作本质上不是资源,而是超越资源的操作。因此,它们不会像 REST 那样响应“资源到 URI 映射”。

但是您可以结合使用 REST 的最佳特性和 URI 的最佳特性。

记住:

技术应该为你工作,而不是你为技术工作。

如果你成为技术的奴隶,你将最终创建不可用的应用程序或使用丑陋的技术,如 XML 或 Java 家庭和远程接口,所以你最终写5个文件,以创建一个 hello world 应用程序。

小心“闪亮物体综合症”,谷歌一下。

不是因为一项技术是新的或者是“新的做事方式”,而是意味着这是一项好的技术,或者你需要分心,放弃所有其他的技术来屈服于 REST。

从技术中获取你所需要的,然后让技术为你工作。

使用 REST api 并不意味着您需要放弃 URL 和 URI 技术的功能。

参考文献: Https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful

我对下面这个例子的考虑:

POST /inventory/{id}/move
  1. “移动”一词可以看作是“移动请求”的缩写。
  2. 在这种情况下,用户发布一个 请求来移动库存。
  3. 当接受时,请求将触发相应的服务器操作。
  4. 请求是某种类型的资源 ,它甚至可以被服务器用于历史目的持久化,或者如果不立即执行的话触发异步任务。

这就是为什么我认为动词可以在 URI 的末尾使用而不违反任何 REST 准则的主要原因。

另一个考虑因素是:

  1. 确保只有在没有可以发布或放置的简单资源的情况下才使用这种“请求抽象”。
  2. PUT inventory/{id}/manager是一种比 POST inventory/{id}/set-manager更好的方法,除非您的请求需要一些不属于 Manager 属性的参数。
  3. 如果您的参数不适合一个实体/value 对象属性,那么建议使用 POST inventory/{id}/manager-update,这显然是一种资源。

最后... 大多数 REST 指南示例只涵盖 CRUD 应用程序。比起仅仅使用来自域实体或值对象的简单名词,更丰富的域需要更具表现力的抽象。