node.jspactpact-broker

pact.io: Select specific endpoints for provider test


We are running a microservice architecture and want to set up contract testing in our project. Our consumers do not know which request is handled by which microservice. We want our microservices to select the interactions from the pacts that they should participate in.

Example:

We want to put provider tests next to the Microservices. Each microservice should only test the endpoints that it is capable of handling. In this scenario, Microservice A would test all of the POST /users contracts. Microservice B would select the GET /users/$userId contracts and so on.

Is there a way to do so with pactflow.io and nodejs bindings for pact?

Edit: Added the architecture diagram: Architecture Diagram


Solution

  • We have found a solution to our particular problem:

    We define a provider as the tuple (HTTP method, URL). As a result, a consumer contains many tests for many providers and a microservice also contains many tests for many providers.

    Something like this in node.js for the consumer:

    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' },
          ...
    

    And like this for a microservice that handles GET /articles and GET /articles/:articleId

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

    We can now start the single microservice in isolation and run the provider tests.