gpt4 book ai didi

json-ld - HATEOAS 和由 API 驱动的表单

转载 作者:行者123 更新时间:2023-12-01 05:50:15 25 4
gpt4 key购买 nike

我正在尝试将 HATEOAS 应用于现有应用程序,但在建模将由 API 响应驱动的表单输入时遇到问题。

该应用程序允许搜索和预订两个地方之间的连接。第一个端点允许搜索连接 GET /connections?from={lat,lon}&to={lat,lon}&departure={dateTime} 并返回以下有效负载(响应正文)。

[
{
"id": "aaa",
"carrier": "Fast Bus",
"price": 3.20,
"departure": "2019-04-05T12:30"
},
{
"id": "bbb",
"carrier": "Airport Bus",
"price": 4.60,
"departure": "2019-04-05T13:30"
},
{
"id": "ccc",
"carrier": "Slow bus",
"price": 1.60,
"departure": "2019-04-05T11:30"
}
]

为了对其中一个连接进行排序,客户端需要使用以下有效载荷之一(请求正文)发出 POST /orders 请求:

需要
  • 电子邮件

    {
    "connectionId": "aaa",
    "email": "passenger@example.org"
    }
  • 需要
  • 电子邮件和航类号(运营商仅处理 aiprot 连接)

    {
    "connectionId": "bbb",
    "email": "passenger@example.org",
    "flightNumber": "EA1234"
    }
  • 需要
  • 电话号码

    {
    "connectionId": "ccc",
    "phoneNumber": "+44 111 222 333"
    }

  • 有效载荷是不同的,因为不同的连接可能由不同的运营商处理,并且每个运营商可能需要提供一些不同的信息集。我想通知 API 客户端,创建订单时需要哪些字段。我的问题是如何使用 HATEOAS 做到这一点?

    我检查了不同的规范,这是我从阅读规范中可以看出的:
  • HAL & HAL-FORMS"_templates" 但模板本身没有 URI。假定在自链接上运行,在我的情况下是 /connections... 而不是 /orders
  • JSON-LD 我找不到有关表单或模板支持的任何信息。
  • JSON-API 我找不到有关表单或模板支持的任何信息。
  • Collection+JSON 每个文档最多有一个 "template",因此假定集合的所有元素都具有相同的字段,而在我的应用程序中并非如此。
  • Siren 看起来 "actions" 适合我的用例,但该项目似乎已死,而且没有许多主要语言的支持库。
  • CPHL 该项目似乎已死,文档很少,也没有库。
  • Ion 对表单有很好的支持,但我找不到任何支持库。看起来它现在只是一个规范。

  • 像 API 驱动的表单这样的常见问题是否仍然无法通过规范和工具解决?

    最佳答案

    在您的示例中, Connections 似乎是资源。 Orders 是否真的是资源尚不完全清楚。我猜可能是的,但是要拥有 Order ,您需要 ClientConnection 。因此,要创建 Order 您需要公开一个集合,可能来自 ClientConnection ,可能两者都有。

    我认为断开连接是因为“现在我们已经有了可用连接列表,客户端可以选择一个并创建一个 Order ”。这是完全有效的,但它是远程过程调用 (RPC) 思维,而不是 REST。客观上两者都不比另一个好,除非在一组特定的项目要求的上下文中,通常它们不应该混合在一起。

    使用 RPC 思维,定义了创建订单方法(例如使用 OpenAPI),并且任何客户端都应该使用一些带外信息来确定所需的正确形式(即通过阅读 OpenAPI 规范)。

    使用 REST/HATEOAS 思维方式,正确的方法是从 Orders 公开 Connection 集合。集合中的每个 Connection 都有一个 self 链接和一个 Order 集合(链接或对象,由应用需求定义)。 Order 的每一项都有一个 self 链接,这是指定可供性的地方。 Order 是一种已知类型(即使使用 REST/HATEOAS,客户端和服务至少必须就共享词汇表达成一致),客户端大概知道如何定义。该词汇表可以使用任何有效的机制来定义——json-ld、XSD 等。

    HATEOAS 要求结果包含客户端更新状态所需的一切。不能有带外信息(共享词汇除外)。因此,要解决您的问题,您要么需要从 Order 公开 Connection 的集合,要么需要允许通过发布到 Order 来创建 Connection 。如果后者看起来有点像黑客,那可能是。

    例如,在 HAL-Forms 中,我会执行以下操作:

    {
    "connections": [{
    "id": "aaa",
    "carrier": "Fast Bus",
    "price": 3.20,
    "departure": "2019-04-05T12:30"
    "_links": {
    "self": { ... }, // link to this connection
    "orders": {} // link to collection of orders for this connection
    }
    },
    , ...],
    "_links": {
    "self": { ... } // link to the collection
    },
    "_templates": { ... } // post/put/patch/delete connection
    }

    客户端将点击指向 orders 的链接,并从那里获得 _templates 集合,其中包含管理 Order 资源的说明。 Order POST 可能需要连接标识符和客户端信息。 HAL-Forms Spec 定义了一个正则表达式属性,可用于指定要为任何特定表单元素提供的数据类型。由于您已经通过特定连接导航到达订单,您将能够在您的 _templates 中为该订单准确指定哪些字段是必需的。例如 /orders?connectionType=aaa 将返回一组与 /orders?connectionType=bbb 不同的必需属性,但两者都使用 self 的相同 /orders?connectionType={type} 链接,您将在 POST/PUT/PATCH 上对其进行验证。

    我应该注意到 Spring-HATEOAS 超出了 HAL-Forms 规范,并允许多个 _links_templates 。见 this GitHub issue

    看起来 HATEOAS/REST 比简单的 OpenAPI/RPC API 需要更多的工作,而且确实如此。但是你在简单性方面放弃的东西,你正在获得灵活性和弹性,假设客户设计良好。哪种方法正确取决于很多因素,其中大多数不是技术因素(团队技能、预期的消费者、您对客户的控制程度、维护等)。

    关于json-ld - HATEOAS 和由 API 驱动的表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55315913/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com