如何处理REST API中的更新?

时间:2018-01-03 23:16:44

标签: rest api

我想了解一些使用RESTful API执行写入的方法。对于此示例,假设为Person对象:

{
    "id": 1,
    "name": "Example Person",
    "addresses": [
        {
            "id": 11,
        }
    ],
    "friends": [
        {
            "id": 21,
            "name": "John"
        }
    ]    }

有一个/ people API可以提供像这样的对象。你可以GET / people / 123来检索上面的例子。不过,我关心的是写作。传统上,通过REST API更新这样的对象是通过使用对象的新状态向/ people / 123发送PATCH或PUT来完成的。但是,您可能会在更新中执行一项或多项操作:

  • 更改此人的姓名
  • 更新现有地址
  • 添加新地址
  • 删除地址
  • 更新现有朋友
  • 将现有人添加为新朋友
  • 不要与某人交朋友

这些中的每一个都是不同的动作,可能具有与之相关的不同逻辑。例如,如果有人将您添加为朋友,则应该收到有关它的通知,而添加地址不应生成任何类型的通知。

与REST API进行通信时,是否有必要发送要采取的操作列表,而不仅仅是发送对象的新状态,并要求API根据具体情况确定用户要执行的操作? / p>

5 个答案:

答案 0 :(得分:2)

您的意思是业务规则,必须放在业务逻辑层中,客户端必须不关心/了解必须对某些请求执行的操作。我假设您应该做的是在BusinessLogic层创建一些检查机制,该属性正在被更改,然后根据此检查采取一些操作(如果您需要执行不同的操作,无论您是否与某人/更改名称/等)。

答案 1 :(得分:2)

您的对象包含其他对象的列表。从技术上讲,您处理许多对象,而不是单个对象。因此,您的JSON结果不是RESTful。 REST基于资源(您称之为对象),并且通常在它们不是复合时将它们隔离。所以当你打电话时

GET /people/123应该提供您提供的示例。它应该提供这样的东西:

{ "id"   : 123,
  "name" : "Example Person" }

这是一个适当的人力资源,仅此而已。朋友和地址将被设计为子资源,应该通过他们自己的API访问,例如:

GET /people/{id}/addresses
GET /people/{id}/friends

当有人将您添加为朋友时,您自然会有一个明确的资源调用。这是一个例子:

POST /people/{id}/friends

POST在正文中包含一位朋友的ID,仅此而已。

旁注:当您稍后返回朋友列表时,您只会获得朋友ID列表,他们的详细信息(如姓名)。原因是朋友是你要求的关系,而不是人的细节。如果您需要此人详细信息,则必须转到人力资源,例如:

GET /people/{friend-id}         [request for one friend]
GET /people?is-friend-of={id}   [request for all friends]

所有朋友的更新将如下所示:

PUT /people/{id}/friends

PUT在正文中包含所有朋友ID的列表。

您需要实施的业务逻辑可以非常轻松地与这些单GETPOSTPUT个请求相关联。这应该使您的业务逻辑地狱变得清晰和容易。您甚至可能发现不再需要PATCH了。我已经学会了尽可能避免它,因为它造成的麻烦比帮助更多。 RESTful指南在详细级别上过于模糊地处理PATCH动词。

我建议你详细了解RESTful的含义,一旦你拥有一个实际上是REST的API,你就会发现很容易处理你的业务逻辑。良好的开端:StackOverflow:What is RESTful programming?

答案 2 :(得分:1)

REST是分布式系统中与协议无关的设计技术,用于将客户端与服务器分离。虽然通常人们会调用通过HTTP公开的基于JSON的Web API,这些Web API部分遵循已定义操作的语义为RESTful(在您的情况下确定如此)。这里的问题是,只有在REST架构所施加的所有约束都得到正确处理的情况下,解耦才会起作用。这些基于JSON的Web API通常返回基于application/json的简单文档,这些文档实际上不包含任何一方的语义,因此需要有关如何处理此类文档的带外信息(或先验知识)。当然,HAL JSON或基于XML的Atom specification有助于进一步支持这种架构中的对等体,尽管文档可能仍然是通用的,以完成任务。

遵循REST体系结构的对等体理想地事先就该表示进行协商,并以约定的格式向另一方请求/发送数据。 mime-type是交付文档的语法和语义的人类可读的纯文本规范,由客户端/服务器的开发人员将这些知识集成到自己的应用程序中(即通过插件机制或通过导入的库建立支持。)

因此,您有2个选项IMO:

  • 将资源的一部分分成自己的资源(如@QualityCatalyst所示),并可能使用JSON HAL(如_embedded字段)将附加信息附加到文档
  • 为您交换的文件定义自己的媒体类型,其中还包含有关更改特定数据的语义的说明

后一个建议肯定是一个开销最大的建议,但这实际上可以实现长期解耦。当然,仍然存在某种耦合,尽管耦合从客户端和服务器转移到媒体类型的中介。只要双方支持mime-type,他们就可以用该表示交换文档,并且可以依赖于mime类型定义的概述语义。

但是,前者更容易实现,因此在不久的将来更可取。您可以从分离资源开始,然后围绕这些来构建自己的媒体类型。

答案 3 :(得分:0)

这种功能通常由API网关(外观设计模式)执行,客户端将请求发送到网关API调用,网关将调用每个微服务API

答案 4 :(得分:0)

前端不应该关心更新数据的作用。它只是注意到变化。这就是解耦层架构的想法。因此,如果更新应该触发发送电子邮件,例如,这需要由后端本身完成。

你认为REST API不应该包含更多的业务逻辑,而且通常是正确的。因此,为了分离您的API,您可以提供CRUD内容,并通知所有已注册的听众,然后发送更改,然后发送电子邮件。