如何设计用于兑换优惠券的RESTful API?

时间:2019-04-22 13:34:07

标签: rest api-design restful-url

我正在设计一个RESTful api来兑换优惠券。 每个优惠券只能兑换一次,兑换后的优惠券将不再有效。

(POST) /coupons/{couponCode}/redeem

似乎违反了RESTful准则,因为redeem是动词。 我可以将redeem更改为redemption吗? 或者我可以只使用

(POST) /coupons/{couponCode}

顺便说一句,我不太确定为什么使用POST而不是PATCH,是因为PATCH是幂等而POST不是吗?我的意思是,当第一次兑换优惠券时,它将在数据库中标记为redeemed,但是一旦完成,相同的请求将不再更新此值。

2 个答案:

答案 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)