我正在设计一个RESTful api来兑换优惠券。 每个优惠券只能兑换一次,兑换后的优惠券将不再有效。
(POST) /coupons/{couponCode}/redeem
似乎违反了RESTful准则,因为redeem
是动词。
我可以将redeem
更改为redemption
吗?
或者我可以只使用
(POST) /coupons/{couponCode}
?
顺便说一句,我不太确定为什么使用POST而不是PATCH,是因为PATCH是幂等而POST不是吗?我的意思是,当第一次兑换优惠券时,它将在数据库中标记为redeemed
,但是一旦完成,相同的请求将不再更新此值。
答案 0 :(得分:2)
由于兑换是动词,似乎违反了RESTful准则
REST不在乎您为资源标识符使用什么拼写。
所以所有这些选择都是 fine
POST /coupons/{couponCode}/redeem
POST /coupons/{couponCode}
POST /{couponCode}/redeem
POST /i/am/a/banana
POST /4ccd2f6f-a81e-4b70-b45c-20ce9f8732b5
标识符的拼写约定类似于变量命名约定;它们的存在只是为了减轻人们的负担,并且要遵守当地的惯例。机器不在乎。
重要的是,用于更改的目标uri与要invalidate的缓存中的资源的标识符匹配。
我不确定为什么使用POST而不是PATCH,是因为PATCH是幂等而POST不是吗?
不。区别在于PATCH承诺有效载荷是补丁文件,也就是说,对“ the”资源表示形式的一组编辑表示,而POST仅表示“这是将由资源处理的消息”
(发生时POST和PATCH都不都是幂等的。)
想象一下一个文档存储,其中文档的大小约为1 TB。您可能要更改其中一个文档。自然的方法是GET
当前表示形式,进行更改,然后PUT
返回文档版本。但是,如果您所做的更改非常小,那么将有很多浪费的工作会带来文档的重复副本。
因此,我们使用PATCH,以便我们可以复制编辑的一小部分表示,而不是整个文档。
POST更笼统-它是带有正文的不安全消息,几乎可以保证。该正文可能是资源的新表示形式,或者是要应用于当前表示形式的补丁,或者是完全不同的东西。
为什么使用赎回不违反REST?不应该仅将动词作为HTTP方法吗?
由于REST是一种体系结构样式,它表示资源标识符应为URL(RFC 1738)-尽管如今通常被理解为URI(RFC 3986)- -或URN(RFC 8141)。
如果您查看RFC 3986,我认为您会发现“动词”一词未出现在文档中的任何位置。您可以查看用于解释URI的ABNF规则,那里的动词一无所有。
REST无关紧要-URI在其主要用例中只是客户端使用的不透明字节序列。
例如,尝试在浏览器中单击此链接,这样行得通吗?
https://www.dictionary.com/browse/stop
“ stop”恰好是英语中的动词这一事实并不干扰其功能。
我还看到一些RESTful设计指南建议不要使用动词
是的,网络上充斥着一些不了解主题的人的建议,或者确实了解主题并且不清楚其含义的人等等。
REST不提供强制实施任何特定的URI设计样式。
在REST中,标识符只是一个标识符,例如UUID,哈希签名或代理密钥。在HTTP消息的上下文中,它表示没有任何意义,它只是一个缓存键。消息语义来自method,而不是请求目标。
GET /A/post HTTP/1.1
POST /B/get HTTP/1.1
DELETE /C/put HTTP/1.1
PUT /D/patch HTTP/1.1
这些请求行中没有歧义,第一个令牌是定义语义的方法,第二个令牌只是一个任意标识符。机器每次都会使它们正确。
答案 1 :(得分:0)
最好在公开赎回操作的地方使用网址路由。此路由应使用POST http请求,因为您将修改服务器上的资源,并将couponCode作为参数。
(POST) /coupons/redeem/{couponCode}
我认为赎回和赎回没有区别。我认为像赎回这样的动词最好指定一个动作。
http PATCH或PUT请求也可以使用。按照惯例,在创建资源以更改其属性之一之后,我们使用PATCH或PUT更新资源。如果您愿意使用PATCH请求进行更新(假设您已创建了优惠券),则可以定义URL路由而无需执行兑换操作。请求正文将包含要针对优惠券对象更新的字段(例如,状态从“待处理”更改为“已兑换”)
(PATCH / PUT) /coupons/{couponCode}
许多使用以下约定:
GET /objects (return list of objects)
GET /objects/id (return object)
PUT /objects/id (update object)
POST /objects (add object)
DELETE /objects/id (remove object)