如何定义REST API?

时间:2018-06-19 07:32:19

标签: rest api-design url-design

我有3个模特:锦标赛锦标赛竞争对手

  • 锦标赛有很多锦标赛;
  • 锦标赛属于锦标赛;
  • 锦标赛有很多竞争对手

因此,要列出所有锦标赛的所有参赛者,网址为:

GET https://base.com/tournament/{slug}/competitors

但是为了增加竞争对手,它与冠军有关:

POST  https://base.com/championships/{id}/competitors

对于相同的模型,两个动词(GET和POST)是否有不同的URI?否则,我该怎么办?

我喜欢这样做:

POST  https://base.com/tournaments/{slug}/championships/{id}/competitors 

没有必要的字段。

2 个答案:

答案 0 :(得分:2)

  

对于同一个模型,两个动词(GETPOST)是否有不同的URI?

这可能会导致API使用者感到困惑,因此我建议您使用相同的URI。

请记住,Roy T. Fielding的论文chapter 5中描述的REST架构风格为构建于顶层的应用程序定义了一组约束。这样的架构。但它说没有关于URI必须是什么样的。

Martin Fowler撰写的popular article中所示的示例解释了Leonard Richardson定义的模型建议一个看起来友好且易于阅读的URI结构。虽然它可能需要,但它不是强制用于REST应用程序。

你可以采用很多有效的方法。如果竞争者要求锦标赛存在且锦标赛需要锦标赛存在,您可以表达{ {3}}使用:

/tournaments/{slug}
/tournaments/{slug}/championships/{id}
/tournaments/{slug}/championships/{id}/competitors/{id}

但是最后一个URI可能被认为太长而且可能难以记住。因此,您可以简单地拆分它,然后您不需要发送许多参数:

/tournaments/{slug}
/championships/{id}
/competitors/{id}

如果您需要执行任何过滤,可以使用hierarchy。例如:

/championships/{id}?tournament={slug}

答案 1 :(得分:0)

提醒:REST不在乎您的URI使用什么拼写

  

对于相同的模型,两个动词(GET和POST)具有不同的URI可以吗?否则,我该怎么办?

可以,但是有一些相关费用。

让我们回顾一下菲尔丁所说的话(2008年)

  REST适用于跨多个组织的基于网络的长期应用程序。   REST接口被设计为对于大颗粒超媒体数据传输是高效的,针对Web的常见情况进行了优化,但是导致该接口对于其他形式的体系结构交互不是最佳的。

菲尔丁在论文中指出的一种复制样式是the cache;他继续将该样式添加到他对REST

的定义中
  

为了提高网络效率,我们添加了缓存约束以形成client-cache-stateless-server样式。...缓存约束要求对请求的响应中的数据被隐式或显式标记为可缓存或不可缓存。可缓存。如果响应是可缓存的,则授予客户端缓存以将响应数据重新用于以后的等效请求的权限。

在HTTP中,缓存的语义在RFC 7234中定义;第4.4节介绍了invalidation

  

当收到非错误状态代码时,缓存必须使有效的请求URI([RFC7230]的5.5节)以及“位置”和“内容-位置”响应头字段(如果存在)中的URI无效。响应不安全的请求方法。

这意味着,通过通用客户端进行的通信(不了解协议的具体细节),可以基于请求和响应中的元数据来使它们的过时表示形式的本地副本无效。

(过去,当我们不加密所有流量时,这是一笔更大的交易;但是它仍然适用于(a)客户端的本地缓存和(b)位于域前面的缓存反向代理型号)。

就REST而言,URI是不透明的;之间没有根本的联系

/A
/A/B
/A/B/C
/A/B/D
/A/E

因此,如果缓存看到/A/B应该无效,它们可以这样做,但对其他URI则不做任何事情。

对于PUT,DELETE和PATCH,这些方法的语义非常特定于有效请求URI。

如果将相同的方法应用于POST,则将“免费”获得缓存失效。

通过一个简单的例子;想象一个我们拥有的网站

GET /superCoolResource
GET /superCoolResource/editForm

我们想在/superCoolResource中进行一些更改,因此我们加载并提交编辑表单。...

POST ...?

如果我们发布到/superCoolResource/editForm,那么我们告诉客户端,如果发布成功,则应重新加载表单的缓存副本。但这可能不是我们想要的-形式保持不变的可能性更大,而/ superCoolResource就是改变的东西。这意味着我们可能希望将/superCoolResource作为目标URI

GET /superCoolResource/editForm

200 OK

... <form action="/superCoolResource" method="POST"> ....

神奇的是,客户端的缓存,原始服务器的缓存以及所有与对话无关的中间缓存都知道在POST成功后将其旧版本的/ superCoolResource复制出去。