0

我们正在运行一个微服务架构,并希望在我们的项目中设置合约测试。我们的消费者不知道哪个请求由哪个微服务处理。我们希望我们的微服务从他们应该参与的契约中选择交互。

例子:

  • 消费者 A 编写了一个正在测试的测试POST /users
  • POST /users消费者 A使用不同的参数编写第二个测试。
  • 消费者 A 为GET /users/$userId.
  • 消费者 A 为GET /articles/$articleId.
  • 微服务 A 处理所有POST /users请求。
  • 微服务 B 处理所有GET /users/$userId请求。
  • 微服务 C 处理所有GET /articles/$articleId请求。
  • 所有的消费者测试在他们的交互中只有一个请求。

我们希望将提供者测试放在微服务旁边。每个微服务应该只测试它能够处理的端点。在这种情况下,微服务 A 将测试所有POST /users合约。微服务 B 会选择GET /users/$userId合约等等。

有没有办法使用 pactflow.io 和 nodejs 绑定 pact ?

编辑:添加了架构图: 架构图

4

2 回答 2

1

不,Pact 中没有这样的内置功能支持该用例。

我们已经讨论了以这种方式发布消息预期的可能性,但不是 HTTP(因为这有点不寻常,不像 Kafka 这样的消息队列通常有更多的间接性)。

您是否使用某种形式的动态 API 网关之类的?

您将面临的一个挑战是以可靠的方式对请求本身进行逆向工程。

想法

我唯一的建议是在提供者端测试上有一个代理,它知道不同的端点,并将请求重定向到正确的提供者。但随后状态处理变得困难。

当然,您也可以手动获取契约并拆分它们,但您会失去契约所具有的很多价值。

我不确定消费者不了解提供者是否更多是哲学上的事情,实际的事情或其他,但显然最简单的解决方案可能是让消费者了解他们的提供者。

提出功能请求

也许更清楚地说明您的用例并在https://pact.canny.io/上请求一个功能可能是值得的,以了解您的用例与更广泛的社区的相关性以及是否值得实施。

于 2021-06-29T11:48:48.687 回答
0

我们找到了解决我们特定问题的方法:

  • 消费者不知道哪个服务充当提供者,但它知道它调用的(HTTP 方法,URL)元组。
  • 微服务知道它负责的每一个(HTTP 方法、URL)。

我们将提供者定义为元组(HTTP 方法,URL)。结果,消费者包含许多提供者的许多测试,而微服务也包含许多提供者的许多测试。

在 node.js 中为消费者提供这样的东西:

const consumer = "MyConsumer";

const providerGetArticles = new Pact({ consumer, provider: 'GET-articles', ...  });

const providerGetArticlesArticleId = new Pact({ consumer, provider: 'GET-articles-:articleId', ...  });

const providerPostUsers = new Pact({ consumer, provider: 'POST-users', ...  });

const providerGetUsers = new Pact({ consumer, provider: 'GET-users', ...  });

const providerGetUsersUserId = new Pact({ consumer, provider: 'GET-users-:userId', ...  });

providerGetArticles.setup().then(() => {
  providerGetArticles.addInteraction(
    {
      withRequest: { method: 'GET', path: '/articles' },
      ...


providerGetArticlesArticleId.setup().then(() => {
  providerGetArticlesArticleId.addInteraction(
    {
      withRequest: { method: 'GET', path: '/articles/12345' },
      ...

providerPostUsers.setup().then(() => {
  providerPostUsers.addInteraction(
    {
      withRequest: { method: 'POST', path: '/users' },
      ...

像这样处理GET /articles和处理的微服务GET /articles/:articleId

new Verifier({ provider: 'GET-articles', ... }).verifyProvider()...

new Verifier({ provider: 'GET-articles-:articleId', ... }).verifyProvider()...

我们现在可以单独启动单个微服务并运行提供程序测试。

于 2021-07-01T09:35:32.067 回答