我正在努力决定如何设计restful url。我完全赞成使用带有名词而不是动词的url的restful方法,我不知道如何做到这一点。
我们正在创建一个服务来实现一个金融计算器。计算器接受一堆参数,我们将通过CSV文件上传这些参数。用例包括:
上传新参数
获取最新参数
获取给定业务日期的参数
激活一组参数
验证一组参数
我收集的restful方法将有以下类型的url:
/parameters
/parameters/12-23-2009
你可以通过以下方法实现前三个用例:
在POST请求中包含参数文件
第一个URL的GET
第二个URL的GET
但是在没有动词的情况下如何完成第4和第5个用例呢?你不需要这样的url吗:
/parameters/ID/activate
/parameters/ID/validate
??
每当你需要一个新的动词时,考虑把这个动词变成一个名词。例如,将'activate'转换为'activation',将'validate'转换为'validation'。
但是从你写的内容来看,你的应用程序有更大的问题。
任何时候,当一个叫做“参数”的资源被提出时,它都应该在每个项目团队成员的脑海中发出红色信号。'parameter'可以应用于任何资源;还不够具体。
“参数”究竟代表什么?可能有很多不同的东西,每一个都应该有一个单独的资源。
另一种方法是——当您与最终用户(那些可能对编程知之甚少的人)讨论应用程序时,他们自己反复使用的词语是什么?
这些都是你应该围绕着设计你的应用程序的词。
如果您还没有与潜在用户进行这种转换,请立即停止所有工作,在完成转换之前不要再编写另一行代码!只有这样,你的团队才会知道需要构建什么。
我对财务软件一无所知,但如果我必须猜测的话,我会说一些资源可能会以“报告”、“支付”、“转账”和“货币”等名称命名。
关于软件设计过程的这一部分,有很多好书。我可以推荐两种:领域驱动设计模式和分析模式。
每当你需要一个新的动词时,考虑把这个动词变成一个名词。例如,将'activate'转换为'activation',将'validate'转换为'validation'。
但是从你写的内容来看,你的应用程序有更大的问题。
任何时候,当一个叫做“参数”的资源被提出时,它都应该在每个项目团队成员的脑海中发出红色信号。'parameter'可以应用于任何资源;还不够具体。
“参数”究竟代表什么?可能有很多不同的东西,每一个都应该有一个单独的资源。
另一种方法是——当您与最终用户(那些可能对编程知之甚少的人)讨论应用程序时,他们自己反复使用的词语是什么?
这些都是你应该围绕着设计你的应用程序的词。
如果您还没有与潜在用户进行这种转换,请立即停止所有工作,在完成转换之前不要再编写另一行代码!只有这样,你的团队才会知道需要构建什么。
我对财务软件一无所知,但如果我必须猜测的话,我会说一些资源可能会以“报告”、“支付”、“转账”和“货币”等名称命名。
关于软件设计过程的这一部分,有很多好书。我可以推荐两种:领域驱动设计模式和分析模式。
我建议使用以下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': '...'}
< }
<
激活和验证需求是试图更改资源状态的情况。将一个订单“完成”或其他一些请求“提交”是没有区别的。有许多方法可以对这种状态变化建模,但我发现最有效的一种方法是为相同状态的资源创建集合资源,然后在集合之间移动资源以影响状态。
例如:创建一些资源,例如:
/ActiveParameters
/ValidatedParameters
如果要使一组参数处于活动状态,则将该集添加到ActiveParameters集合。您可以将参数集作为实体体传递,也可以将url作为查询参数传递,如下所示:
POST /ActiveParameters?parameter=/Parameters/{Id}
同样的事情也可以用/ValidatedParameters完成。如果参数无效,则服务器可以向请求返回“Bad Request”,将参数添加到已验证参数的集合中。