【问题标题】:How to post multiple items in one request to an API in a REST(ful) way?如何以 REST(ful) 方式在一个请求中将多个项目发布到 API?
【发布时间】:2015-09-18 07:47:56
【问题描述】:

这是一个更具概念性的问题,所以我认为使用的框架并不重要。我仍然在用 Node & Express 和 Angular 构建一个 API。

场景

用户将有关一本书的信息输入到一个表单中。然后将其提交给 API 进行验证(除了前端验证之外)并保存到数据库中。

表格包含数据库中几个模型的信息:

  • 书籍:标题、描述等
  • 作者:很多作者都有很多书
  • 出版商:一个出版商有很多书

如果数据库中已经存在作者或出版商,它将被链接而不是创建。

问题:

我想在一个请求中实现这一目标。

  • 正确的方法是什么?
  • 我是否应该将表单数据发布到/api/books 并使用我的 ORM 以及创建/链接作者和出版商的图书模型上的某种生命周期回调来解决后端的复杂性?
  • 我的 API 路由是否应该以任何方式反映这一点?
  • 我是否应该创建某种虚拟模型(例如BookCollection)来反映书籍、作者和出版商的组合?
  • 在调用GET /api/books/:id 时是否可以同时检索所有三个?
  • 是否有经过验证的方法来处理多个对象的验证?

感谢您的意见!有什么帮助!

【问题讨论】:

  • 传递模型BookCollection 会更容易,因为您只需发送一个对象。我认为这必须在后端处理。前端返回的对象将为您提供有关发生的事情的信息,并由您决定通知用户已完成的操作

标签: angularjs node.js rest post


【解决方案1】:

以下是我对此的看法:

  1. 尽可能保持 API 干净。在不久的将来,弄乱 API 会带来麻烦。因此,我建议将 api 设置为 /api/books。
  2. 您的图书条目表应该包含作者和出版商字段,对吗?我认为您希望与现有的作者和出版商有一个下拉/预先输入,用户输入书籍详细信息将从中选择 1 个(或更多),对吗?在这种情况下,您的图书模型应该有作者和出版商的 ID。这可以。本书的定义要求您拥有这些跨职能领域(但只有 Id)。因此,您应该为所有这些设置 3 个端点:/api/books、/api/authors 和 /api/publishers。
  3. 当您在页面上显示图书详细信息(可能是显示图书)时,您必须决定是通过复杂的 API 在一次调用中获取作者和出版商详细信息,还是进行三次调用以获取相关数据.后一种选择更简洁,更可扩展,我会选择它。您可以在服务器端组装所有这些数据,它会更快,但是您正在构建庞大的不可重用 API,它仅用于您的特定目的(以后可能会更改)。因此,总结一下,在展示图书时,调用 3 个 API 来获取图书详细信息,然后根据从图书 api 收到的 id 再调用两个 API 来获取作者和出版商详细信息。
  4. 让我们采用两种情况:第一种情况是图书的作者/出版商在您的数据库中。在这种情况下,用户可以从预输入中选择它们并保存 id。第二,当用户没有从预输入中选择任何作者/出版商时。在这种情况下,您的模型会将 publisherId 和 authorId 设为 null。当您在 /api/books 收到此请求时,您可以开始创建作者和出版商,并使用它们的 id 更新 db 中的图书对象。
  5. 请注意,这样做不会阻止您在服务器上实施验证。您仍然可以在服务器端进行验证,但它使您的客户端架构更加简洁。此外,您的 API 是模块化的,足以供多个消费者使用。

【讨论】:

  • 谢谢。关于表格:不,下拉不是一个选项。必须可以只输入名称。然后我对其进行规范化、查找并创建或链接作者。书籍/作者只是一个理论示例,在我的情况下,我处理其他数据,不会有两个同名的“作者”。关于验证:我必须验证所有三个模型。假设这本书的细节很好,我创建它然后去找作者。但作者无效。我现在有一本没有作者的书,可能很难将有意义的错误消息返回给用户,而不是最终陷入数据地狱。
  • 好的。我的第一个建议是认真考虑这里的 angular typeahead 组件 - angular-ui.github.io/bootstrap/#/typeahead。它的作用是向您显示一个绑定到列表的文本框,当您键入它时,它会为您提供列表中的匹配值。这正是您所需要的。这样,用户将不会键入您的数据库中不存在的作者/发布者(如果您想要该功能,那么您仍然可以使用 typeahead 并以不同的方式处理这种情况)。
  • 此外,预输入将使您无需对作者和出版商对象执行繁琐的验证。
  • 正如我所说,我希望用户能够输入不存在的作者。这就是重点。
  • 我不同意验证。仅在前端进行验证不是一种选择。 Angular 只是发布到这个 api 的一种方式。将来可能还有其他人。仅在前端进行验证是不好的做法。还是我误解了你的建议?
【解决方案2】:

创建一个新模型BookCollection 是一个很好的解决方案(对我来说)。您必须在服务器端生成一个新路由:/api/bookcollection

但是,您应该避免在服务器上重复所有数据操作。你应该重用/api/book的代码来存储书籍,使用/api/authors的代码来存储作者等等。否则你很快就会遇到维护重复代码的大问题。

/api/bookcollection 应该在添加每个数据之前检查所有数据是否正确。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多