RESTful API设计:用于创建多对多关系的PUT或POST?

时间:2015-09-29 12:21:50

标签: api rest http

为了设计和创建RESTful API,会出现以下问题:

API支持GET(用于查询),POST(用于创建),PUT(用于更新)和DELETE(用于删除)。

让我们假设在数据库中我们已经存在文章商店

现在我们需要一个休息调用来将文章实例链接到商店实例。以下哪种解决方案是最佳/最干净的REST设计:

  1. / shop / id / article / id / - >用POST
  2. / shop / id / article / id / - >与PUT
  3. / shoparticlerelation / - > POST(带有身体中的ID的对象)
  4. / shoparticlerelation / - >与PUT(身体中有ids的对象)
  5. 如果没有明确的答案或所有解决方案都同样好,如果有明确的论证原因,这也可能是一个有效的答案。

2 个答案:

答案 0 :(得分:3)

我认为在这种情况下你已经拥有了shop的集合和article的集合,你只想将两个链接在一起。

一种选择是公开更像数据库的资源'提供此链接,并具有

之类的操作
POST /shopArticleLinks HTTP/1.1

{ "shop"  : xxx,
  "article: YYY
}

我个人希望将它作为商店和/或物品的财产以更自然的庄园展示,例如

PUT /shop/<ID> HTTP/1.1

{ /* existing details */
  "articles": [ /* list of articles */ ]
}

我在那里使用过JSON,但当然使用你想要使用的格式。我也按照你的说法坚持使用PUT,但请记住,使用PUT你应该发送一个完全替换新的修改版本,PATCH可以用来发送部分更新,但是你需要考虑你如何想要这样做,可能像

PATCH /shops/<ID>/articleLinks HTTP/1.1

{ "add"   : [],
  "remove : []
}

不要忘记服务器端,你可以看看articles被裁判的内容,并确保他们有一个正确的后退指针。

其他想法

关于第二种方法,您将链接公开为shop和/或article资源的属性。请记住,当您更新给定shop中的链接时,相应的articles中的链接也会更新,这是完全可以接受的(在这种情况下相当合适)。

答案 1 :(得分:2)

  

<!DOCTYPE html> <html> <head> <base href="https://polygit.org"> <script src="/components/webcomponentsjs/webcomponents-lite.min.js"></script> <link rel="import" href="/components/polymer/polymer.html"> </head> <body> <my-element id="myElement" verbose></my-element> </body> <script> (function() { 'use strict'; // Behavior (ES5) var myBehaviors = myBehaviors || {}; myBehaviors.VerboseBehavior = { properties: { verbose: { type: Boolean, value: false } }, log: function(msg) { if (!this.verbose) { return; } if (this.id) { console.log(this.localName + ' (#' + this.id + '): ' + msg); } else { console.log(this.localName + ': ' + msg); } } }; // Element (ES6) class myElement { beforeRegister() { this.is = 'my-element'; this.behaviors = [ myBehaviors.VerboseBehavior ]; this.properties = { hello: { type: String, value: 'world' } }; } ready() { this.log('ready'); // error TypeError: this.log is not a function } attached() { this.say(); } say() { console.log(this.hello); } }; Polymer(myElement); })(); </script> </html>

你不能使用它,因为在你想要链接它们时,这个端点不存在(或者至少不应该存在)。将它们链接在一起应该定义此端点。

  

/shop/id/article/id/

您不应该使用此项,因为/shoparticlerelation/不是资源/实体。通常使用rest,每个命名的url段代表一个可以CRUD的资源。 shoparticlerelation是一个很好的例子,/shops也是如此,但这个不是。

我建议如下:

定义以下端点

/articles用于发布新店铺 /shops在一家商店经营 /shops/id用于发布新文章
/articles用于操作单篇文章

然后将它们链接在一起,您可以执行所谓的PATCH请求,更新商店的文章或文章的商店:

/articles/id

PATCH /shops/1 HTTP/1.1

{
    "attribute": "articles",
    "operation": "add",
    "value": "8" // the article id
}

根据您的评论,我假设文章模型将商店列表作为属性,反之亦然,使此方法有效。

PATCH请求用于通过指定更新方式和内容来修改现有资源。这与PUT不同,因为PUT用请求中的值替换整个资源,但PATCH仅用于修改(而不是替换)资源。