如何创build没有动词的RESTurl?

我正在努力确定如何devise宁静的url。 我是所有的使用URL名词的宁静的方式,而不是动词不明白如何做到这一点。

我们正在创build一个服务来实现一个金融计算器。 计算器需要一些参数,我们将通过CSVfile upload。 用例包括:

  1. 上传新的参数
  2. 获取最新的参数
  3. 获取给定业务date的参数
  4. 使一组参数处于活动状态
  5. validation一组参数

我收集宁静的方法将是有以下types的url:

/parameters /parameters/12-23-2009 

您可以通过以下方式实现前三个用例:

  1. POST请求中包含参数文件的位置
  2. 获取第一个url
  3. 获取第二个url

但是,你如何做第四和第五个没有动词的用例呢? 你不需要像这样的url:

 /parameters/ID/activate /parameters/ID/validate 

??

也许是这样的:

 PUT /parameters/activation HTTP/1.1 Content-Type: application/json; encoding=UTF-8 Content-Length: 18 { "active": true } 

好的URIdevise的一般原则:

  • 不要使用查询参数来改变状态
  • 如果可以帮助的话, 不要使用混合path。 小写是最好的
  • 不要在URI中使用特定于实现的扩展(.php,.py,.pl等)
  • 不要使用您的URI进入RPC
  • 尽可能限制你的URI空间
  • 请保持path短
  • 首选/resource/resource/ ; 从你不使用的那个创build301redirect
  • 使用查询参数来进行资源的子select。 即分页,search查询
  • 将东西移出应该位于HTTP标头或正文中的URI

(注:我没有说“RESTful URIdevise”; URI在REST中本质上是不透明的。)

HTTP方法select的一般原则:

  • 永远不要使用GET来改变状态; 这是让Googlebot毁了你一天的好方法
  • 除非你正在更新整个资源,否则不要使用PUT
  • 不要使用PUT,除非你也可以在同一个URI上合法地做一个GET
  • 不要使用POST检索长寿命或可能合理caching的信息
  • 不要执行与PUT不等幂的操作
  • 尽可能使用GET
  • 如有疑问,请优先使用POST
  • 当你必须做一些感觉类似于RPC的事情时,请使用POST
  • 对于较大或分层的资源类,请使用PUT
  • 使用DELETE优先于POST来删除资源
  • 除非你的input很大,否则使用GET来计算,在这种情况下使用POST

使用HTTP进行Web服务devise的一般原则:

  • 不要将元数据放在应该在标题中的响应的正文中
  • 不要将元数据放在单独的资源中,除非包含它会造成重大的开销
  • 使用适当的状态码
    • 201 Created资源后创build; 资源必须在发送响应时存在
    • 202 Accepted成功执行操作或asynchronous创build资源后202 Accepted
    • 当有人对显然是虚假的数据进行操作时, 400 Bad Request ; 对于你的应用程序,这可能是一个validation错误; 一般为未捕获的exception保留500个
    • 401 Unauthorized当有人访问您的API时401 Unauthorized而未提供必要的Authorization标头或Authorization内的凭证无效; 如果您不希望通过Authorization标头获得凭据,请不要使用此响应代码。
    • 403 Forbidden当某人以恶意或未经授权访问您的API时被禁止
    • 405 Method Not Allowed有人使用POST时应该使用PUT等
    • 413 Request Entity Too Large当有人试图向您发送一个不可接受的大文件
    • 当试图用茶壶冲泡咖啡时, 418 I'm a teapot 一个茶壶
  • 尽可能使用caching标题
    • 当您可以轻松地将资源减less到散列值时, ETag头是很好的
    • Last-Modified应该告诉你,保持资源更新的时间戳是个好主意
    • Cache-ControlExpires应该被赋予合理的值
  • 尽你所能地在一个请求中声明caching标题( If-None-ModifiedIf-Modified-Since
  • 有意义时使用redirect,但这些对于Web服务来说应该是罕见的

关于你的具体问题,POST应该用于#4和#5。 这些操作属于上述“类RPC”指导方针。 对于#5,请记住,POST不一定必须使用Content-Type: application/x-www-form-urlencoded 。 这可以很容易地是一个JSON或CSV有效载荷。

只要看起来你需要一个新的动词,考虑把这个动词变成一个名词来代替。 例如,将“激活”转为“激活”,将“validation”转换为“validation”。

但是从你写的东西我会说你的应用程序有更大的问题。

任何时候提出一个名为“参数”的资源,都应该在每个项目组成员的头脑中发出红旗。 '参数'可以从字面上适用于任何资源; 这不够具体。

“参数”究竟代表什么? 可能有许多不同的东西,每个东西都应该有一个独立的资源。

解决这个问题的另一种方法是,当你和最终用户讨论你的应用时(那些对编程知之甚less的人)他们自己反复使用的词是什么?

这些是你应该围绕你的应用程序devise的词汇。

如果您还没有与潜在用户进行这种转换,请立即停止所有操作,直到您完成后再写一行代码! 只有这样,你的团队才能明白需要build立什么。

我对财务软件一无所知,但如果我不得不猜测,我会说一些资源可能会通过名称,如“报告”,“付款”,“转账”,“货币”。

在软件devise过程的这一部分有许多好书。 我可以推荐两个域驱动devise和分析模式 。

您的url的devise与您的应用程序是否为RESTful无关。 因此短语“RESTful URL”是无稽之谈。

我认为你应该多做一些REST实际上的阅读。 REST将URL视为不透明的,因此不知道它们是什么,不pipe是动词还是名词,或者其他什么。 你可能仍然想要devise你的URL,但这是关于UI,而不是REST。

这就是说,让我们来看看你的问题:最后两种情况是不是RESTful,不适合任何一种宁静的scheme。 这些就是你可能称之为RPC的东西。 如果你认真对待REST,你将不得不重新思考你的应用程序是如何工作的。 要么,要么放弃REST,只是做你的应用程序作为一个RPC应用程序。

Hrmmm可能不是。

这里的想法是,你必须把所有的东西当作一个资源来处理,所以一旦一组参数有一个你可以参考的URL,你只需要添加

获取[parametersurl] / validationresults

后[paramatersurl]

body:{command:“activate”}

但是,再次激活的东西是RPC,而不是REST。

激活和validation要求是您尝试更改资源状态的情况。 订单“完成”或其他一些“提交”请求也不例外。 有许多方法可以模拟这种状态变化,但是我发现经常工作的方法是为相同状态的资源创build集合资源,然后在集合之间移动资源以影响状态。

例如创build一些资源,

 /ActiveParameters /ValidatedParameters 

如果要使一组参数处于活动状态,请将该设置添加到ActiveParameters集合中。 您可以将参数集作为实体正文传递,也可以将url作为查询parameter passing,如下所示:

 POST /ActiveParameters?parameter=/Parameters/{Id} 

/ ValidatedParameters可以做同样的事情。 如果参数无效,则服务器可以向请求添加“错误请求”,以将参数添加到已validation参数的集合中。

我会build议下面的元资源和方法。

使参数激活和/或validation它们:

 > PUT /parameters/<id>/meta HTTP/1.1 > Host: example.com > Content-Type: application/json > Connection: close > > {'active': true, 'require-valid': true} > < HTTP/1.1 200 OK < Connection: close < 

检查参数是否有效且有效:

 > GET /parameters/<id>/meta HTTP/1.1 > Host: example.com > Connection: close > < HTTP/1.1 200 OK < Content-Type: application/json < Connection: close < < { < 'active': true, < 'require-valid': true, < 'valid': {'status': false, 'reason': '...'} < } < 

在REST环境中,每个URL都是唯一的资源。 你有什么资源? 金融计算器确实没有任何明显的资源。 您需要深入了解您所调用的参数并提取资源。 例如,贷款的摊销日历可能是一种资源。 日历的URL可能包括start_date,term(以月份或年份),period(当利息被复合时),利率和初始原则。 所有这些值都有一个特定的付款日历:

 http://example.com/amort_cal/2009-10-20/30yrsfixed/monthly/5.00/200000 

现在,我不知道你在计算什么,但是你的参数列表的概念听起来不是RESTful。 正如别人所说,你的要求听起来更XMLRPC。 如果你正在尝试REST,你需要名词。 计算不是名词,它们是对名词起作用的动词。 你需要把它翻过来把名词拉出你的计算。

编辑:确实,URI将阻止GET请求保持幂等。


然而,对于validation,使用HTTP状态代码来通知请求的有效性(创build新的或修改现有的'参数')将适合于Restful模型。

如果提交的数据无效并且请求必须在重新提交之前被更改( HTTP / 1.1状态码 ),则返回400 Bad Request状态码。

这依赖于在提交时确认,而不是像在你的用例那样推迟。 其他答案对这种情况有适当的解决scheme。