在 HATEOAS 中向消费者建议行动
Suggesting an action to consumer in HATEOAS
我正在使用 HATEOAS REST 表示法开发 Web 服务 API。
我的客户可以创建一个项目(例如博客存根post):
POST /item
204 Created
Content-Type: application/vnd.foo.item+json
{
"id": 42,
"title": "Lorem Ipsum",
"status": "STUB",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"activate": {
"href": "/item/42/activate"
},
}
}
之后,客户可以激活 activate
link 之后的项目(例如使用 post 上线)。所以它再次调用 API:
POST /item/42/activate
200 Ok
Content-Type: application/vnd.foo.item+json
{
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
}
}
}
到这里为止还好。但问题是我正在寻找一种方法来告诉客户关于下一步操作的建议(这是后端业务逻辑)。
在我的情况下可能是:
- 将用户带到 permalink
之后的 post 页面
- 将用户带到购物车以购买 post 额外功能(可见性、更多图像、主页位置等...)
- 告诉用户 post 正在等待内容审核
我不知道如何将这些信息封装在 HATEOAS 中。
我在想类似的东西:
POST /item/42/activate
200 Ok
Content-Type: application/json
{
"suggested-action": "check-censure-panel",
"censure-reason": "censored (gambling)",
"_embedded": {
"foo.item": {
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
}
}
}
}
但问题是每个建议的操作对于额外的属性都是异构的,另一个例子可能是:
"suggested-action": "go-to-checkout",
"product-order": 424242100,
它们没有通用接口,所以我无法制作 vnd.foo.suggestedAction+json
类型。
设计此响应的最佳方式是什么?
下一个动作是状态转换,您似乎在使用 HAL,因此任何状态转换都应显示为 HAL。
您应用的客户端需要对您的应用提供的状态转换做出反应。因此,您可以做的一件非常简单的事情就是将 Location header 发送到应用程序应该呈现的下一个资源。您甚至可以将它们 302 重定向到那里,而不是使用更新后的资源对它们进行 200 重定向。
您可以将下一个操作提供为 link...而不一定是 HAL link。您可以将其作为 Link header (https://www.rfc-editor.org/rfc/rfc5988),但我认为这很奇怪,我只是提出它来说明您的应用需要告诉您的客户关于link.
您似乎想使用自定义媒体类型,但您可以使用配置文件 links (https://www.rfc-editor.org/rfc/rfc6906) 并将配置文件混合到您的 vnd.foo 类型中。您可以坚持您的 vnd.foo 类型,只定义它有一个可选的 suggested-action link 关系。你的例子中的问题是你用数据字段定义它,但是使用 link:
{
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
},
"x:suggested-action" : {
"href" : "/path/to/best/action"
}
}
客户端可以关注 link,向用户提供选择关注 link 或忽略它的选项。在中间情况下,如果您的应用程序为用户提供一些上下文,例如标题字段,那就太好了:
"x:suggested-action" : {
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel"
}
您还可以提示应用可以期待的资源:
"x:suggested-action" : {
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel",
"type" : "vnd.censure.panel/json"
}
我个人不喜欢这样做,因为我喜欢我的客户对我发送给他们的任何内容做出反应,但是当您提供多项建议操作时,这很有用:
"x:suggested-action" : [
{
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel",
"type" : "vnd.censure.panel/json"
},
{
"href" : "http://path/to/checkout",
"title" : "Start Checkout",
"type" : "vnd.checkout/json"
}
]
现在应用程序可以根据明确定义的媒体类型来决定要执行、呈现或忽略哪些建议操作。
我正在使用 HATEOAS REST 表示法开发 Web 服务 API。
我的客户可以创建一个项目(例如博客存根post):
POST /item
204 Created
Content-Type: application/vnd.foo.item+json
{
"id": 42,
"title": "Lorem Ipsum",
"status": "STUB",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"activate": {
"href": "/item/42/activate"
},
}
}
之后,客户可以激活 activate
link 之后的项目(例如使用 post 上线)。所以它再次调用 API:
POST /item/42/activate
200 Ok
Content-Type: application/vnd.foo.item+json
{
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
}
}
}
到这里为止还好。但问题是我正在寻找一种方法来告诉客户关于下一步操作的建议(这是后端业务逻辑)。
在我的情况下可能是:
- 将用户带到 permalink 之后的 post 页面
- 将用户带到购物车以购买 post 额外功能(可见性、更多图像、主页位置等...)
- 告诉用户 post 正在等待内容审核
我不知道如何将这些信息封装在 HATEOAS 中。 我在想类似的东西:
POST /item/42/activate
200 Ok
Content-Type: application/json
{
"suggested-action": "check-censure-panel",
"censure-reason": "censored (gambling)",
"_embedded": {
"foo.item": {
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
}
}
}
}
但问题是每个建议的操作对于额外的属性都是异构的,另一个例子可能是:
"suggested-action": "go-to-checkout",
"product-order": 424242100,
它们没有通用接口,所以我无法制作 vnd.foo.suggestedAction+json
类型。
设计此响应的最佳方式是什么?
下一个动作是状态转换,您似乎在使用 HAL,因此任何状态转换都应显示为 HAL。
您应用的客户端需要对您的应用提供的状态转换做出反应。因此,您可以做的一件非常简单的事情就是将 Location header 发送到应用程序应该呈现的下一个资源。您甚至可以将它们 302 重定向到那里,而不是使用更新后的资源对它们进行 200 重定向。
您可以将下一个操作提供为 link...而不一定是 HAL link。您可以将其作为 Link header (https://www.rfc-editor.org/rfc/rfc5988),但我认为这很奇怪,我只是提出它来说明您的应用需要告诉您的客户关于link.
您似乎想使用自定义媒体类型,但您可以使用配置文件 links (https://www.rfc-editor.org/rfc/rfc6906) 并将配置文件混合到您的 vnd.foo 类型中。您可以坚持您的 vnd.foo 类型,只定义它有一个可选的 suggested-action link 关系。你的例子中的问题是你用数据字段定义它,但是使用 link:
{
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
},
"x:suggested-action" : {
"href" : "/path/to/best/action"
}
}
客户端可以关注 link,向用户提供选择关注 link 或忽略它的选项。在中间情况下,如果您的应用程序为用户提供一些上下文,例如标题字段,那就太好了:
"x:suggested-action" : {
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel"
}
您还可以提示应用可以期待的资源:
"x:suggested-action" : {
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel",
"type" : "vnd.censure.panel/json"
}
我个人不喜欢这样做,因为我喜欢我的客户对我发送给他们的任何内容做出反应,但是当您提供多项建议操作时,这很有用:
"x:suggested-action" : [
{
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel",
"type" : "vnd.censure.panel/json"
},
{
"href" : "http://path/to/checkout",
"title" : "Start Checkout",
"type" : "vnd.checkout/json"
}
]
现在应用程序可以根据明确定义的媒体类型来决定要执行、呈现或忽略哪些建议操作。