我正在努力确定如何设计宁静的 URL。我完全赞成使用带有名词而不是动词的 URL 的宁静方法,但我不明白如何做到这一点。

我们正在创建一项服务来实施金融计算器。该计算器需要一系列参数,我们将通过 CSV 文件上传这些参数。用例将涉及:

  1. 上传新参数
  2. 获取最新参数
  3. 获取给定业务日期的参数
  4. 激活一组参数
  5. 验证一组参数

我认为安静的方法是使用以下类型的 URL:

/parameters
/parameters/12-23-2009

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

  1. POST 在 post 请求中包含参数文件
  2. 获取第一个 URL
  3. 获取第二个 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 }

其他提示

良好 URI 设计的一般原则:

  • 使用查询参数来改变状态
  • 如果可以的话,使用大小写混合的路径;小写是最好的
  • 在 URI 中使用特定于实现的扩展(.php、.py、.pl 等)
  • 掉进 远程过程调用 与您的 URI
  • 尽可能限制您的 URI 空间
  • 保持路径段短
  • 更喜欢其中一个 /resource 或者 /resource/;从您不使用的重定向创建 301 重定向
  • 使用查询参数进行资源的子选择;IE。分页、搜索查询
  • 将应位于 HTTP 标头或正文中的内容移出 URI

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

HTTP方法选择的一般原则:

  • 曾经使用 GET 来改变状态;这是让 Googlebot 毁掉你一天的好方法
  • 除非您要更新整个资源,否则请使用 PUT
  • 使用 PUT 除非您也可以在同一 URI 上合法地执行 GET
  • 使用 POST 检索长期存在或可能适合缓存的信息
  • 执行不属于的操作 幂等的 与放置
  • 尽可能使用 GET
  • 如有疑问,请优先使用 POST 而不是 PUT
  • 每当你必须做一些类似于 RPC 的事情时,请使用 POST
  • 对更大或分层的资源类别使用 PUT
  • 优先使用 DELETE 而不是 POST 来删除资源
  • 使用 GET 进行计算等操作,除非您的输入很大,在这种情况下使用 POST

HTTP Web 服务设计的一般原则:

  • 将元数据放入应位于标头中的响应正文中
  • 将元数据放在单独的资源中,除非包含它会产生大量开销
  • 使用适当的状态代码
    • 201 Created 创建资源后;资源 必须 发送响应时存在
    • 202 Accepted 成功执行操作或异步创建资源后
    • 400 Bad Request 当有人对明显伪造的数据进行操作时;对于您的应用程序,这可能是一个验证错误;一般为未捕获的异常保留500
    • 401 Unauthorized 当有人访问你的 API 时没有提供必要的信息 Authorization 标头或当凭证内 Authorization 无效;如果您不希望通过以下方式获得凭据,请不要使用此响应代码 Authorization 标头。
    • 403 Forbidden 当有人以可能恶意的方式访问您的 API 或未经授权时
    • 405 Method Not Allowed 当有人在应该使用 PUT 时使用 POST 等
    • 413 Request Entity Too Large 当有人试图向您发送一个无法接受的大文件时
    • 418 I'm a teapot 当尝试用茶壶冲泡咖啡时
  • 尽可能使用缓存标头
    • ETag 当您可以轻松地将资源简化为哈希值时,标头是很好的选择
    • Last-Modified 应该向您表明保留资源更新时的时间戳是一个好主意
    • Cache-ControlExpires 应该给予合理的价值观
  • 尽你所能来尊重请求中的缓存标头(If-None-Modified, If-Modified-Since)
  • 在有意义时使用重定向,但对于 Web 服务来说这种情况应该很少见

关于您的具体问题,#4 和#5 应该使用 POST。这些操作属于上面的“类似 RPC”准则。对于#5,请记住 POST 不一定必须使用 Content-Type: application/x-www-form-urlencoded. 。这也可以是 JSON 或 CSV 有效负载。

每当看起来你需要一个新动词时,请考虑将该动词转换为名词。例如,将“激活”变为“激活”,将“验证”变为“验证”。

但是,根据你所写的内容,我会说你的应用程序有更大的问题。

每当提出一个名为'parameter'的资源时,它应该在每个项目团队成员的心中发出红旗。 '参数'可以逐字地应用于任何资源;它不够具体。

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

另一种解决方法 - 当你与最终用户(那些可能对编程知之甚少的人)讨论你的应用程序时,他们自己反复使用的是什么词?

这些是您应该设计应用程序的词语。

如果您尚未与潜在用户进行此转换 - 请立即停止所有操作,并且在您执行此操作之前不要编写另一行代码!只有这样,您的团队才能了解需要构建的内容。

我对财务软件一无所知,但如果我不得不猜测,我会说一些资源可能会出现在名称上,例如“报告”,“付款”,“转移”和“货币”等名称。 ;

软件设计过程的这一部分有很多好书。我可以推荐两个域驱动设计分析模式

您的网址设计与您的应用程序是否为REST是无关的。短语“RESTful URLS”因此是无稽之谈。

我认为你应该更多地了解REST究竟是什么。 REST将URL视为不透明,因此不知道它们中的内容,无论是动词还是名词或其他什么。您可能仍想设计URL,但这是关于UI而不是REST。

那就是说,让我们回答你的问题:最后两个案例不是RESTful,并且不适合任何类型的宁静方案。这些就是你所谓的RPC。如果您对REST非常认真,那么您必须重新思考应用程序的工作原理。要么是这样,要么放弃REST,只是将你的应用作为RPC应用程序。

Hrmmm也许不是。

这里的想法是你必须将所有东西视为一种资源,所以一旦一组参数有一个你可以引用的URL,你就可以添加

获取[parametersurl] / validationresults

post [paramatersurl]

body:{command:" activate"}

但同样,激活的东西是RPC,而不是REST。

激活和验证要求是您尝试更改资源状态的情况。使订单“完成”或某些其他请求“提交”并没有什么不同。有许多方法可以对这些类型的状态更改进行建模,但我发现通常可以使用的方法是为同一状态的资源创建集合资源,然后在集合之间移动资源以影响状态。

e.g。创建一些资源,例如,

/ActiveParameters
/ValidatedParameters

如果要激活一组参数,请将该组添加到ActiveParameters集合中。您可以将参数集作为实体主体传递,也可以将URL作为查询参数传递,如下所示:

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

使用/ ValidatedParameters可以完成同样的事情。如果参数无效,则服务器可以返回“错误请求”。请求将参数添加到验证参数的集合中。

我建议使用以下Meta资源和方法。

使参数生效和/或验证它们:

> 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,期限(以月或年为单位),期间(当利息复利时),利率和初始原则。对于所有这些值,您有特定的付款日历:

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

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

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


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

如果提交的数据无效且必须在重新提交之前更改请求( HTTP / 1.1状态代码)。

这依赖于在提交时验证,而不是像在用例中那样推迟验证。其他答案适用于该场景。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top