{"id":8417,"date":"2025-02-19T07:27:08","date_gmt":"2025-02-19T07:27:08","guid":{"rendered":"https:\/\/kognivera.com\/?p=8417"},"modified":"2025-03-05T13:04:35","modified_gmt":"2025-03-05T07:34:35","slug":"contract-testing-with-pact-spock-and-gradle","status":"publish","type":"post","link":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/","title":{"rendered":"Contract testing with Pact, Spock and gradle"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"8417\" class=\"elementor elementor-8417\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-72c504c e-flex e-con-boxed e-con e-parent\" data-id=\"72c504c\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-70be5ff elementor-widget elementor-widget-text-editor\" data-id=\"70be5ff\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p dir=\"auto\">Building a microservice architecture to effectively run and operate resilient distributed services is hard. Especially, when you run into a use case that needs inter-service communication. Domain Driven Design principles help in identifying clear boundaries where each microservice is responsible for a well-defined subset of business logic. But at some point, you realise that the microservice you&#8217;re building still needs to communicate with another service for data. Typically this data resides within another service and read\/write operations on this data can be performed either synchronously using REST APIs, gRPC etc. or asynchronously using message brokers.<\/p><p dir=\"auto\">When two independently deployable services within a system communicate with each other, testing the integration becomes vital before we go to production. Integration testing is a widely used testing strategy and a fundamental step in the <a href=\"https:\/\/martinfowler.com\/articles\/practical-test-pyramid.html\" rel=\"nofollow\">testing pyramid<\/a>. However, in the case of microservices, regardless of services being backward compatible, integration tests do not take into account &#8211; the changes that occur in API contracts\/definitions with changing requirements once these services are deployed to Production or even during the course of development. Enter Contract testing.<\/p><p dir=\"auto\">The key idea of contract testing is to independently test the sender (generally referred to as &#8220;provider&#8221;) and the receiver (or &#8220;consumer&#8221;) using the same contract. The contract definition can be shared by either storing it locally on the consumer and provider OR by hosting it on a server and making it available to both sides via a network.<\/p><p dir=\"auto\">The contract essentially defines how the two services communicate. It can be defined either in the provider service or in the consumer service. When a service is used by multiple unknown consumers typically in case of SaaS API, <b>provider-driven<\/b> approach is beneficial. In a microservice architecture, where all services within the domain are known and the provider needs to comply with the consumer&#8217;s requirements, <b>consumer-driven<\/b> approach is a better fit.<\/p><p dir=\"auto\">There are many popular frameworks available like Spring Cloud Contract, Hypertest, Pact for contract testing services in Java applications. In this article, we will be looking at Pact as a tool for contract testing inter-service HTTP communication in a Spring-boot microservices application. Pact is a platform-independent library that follows a consumer-driven contract testing approach.<\/p><p dir=\"auto\">Let&#8217;s consider a use case in an e-commmerce system &#8211; communication between checkout service and shipping service.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8f9e4c2 elementor-widget elementor-widget-image\" data-id=\"8f9e4c2\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"https:\/\/kognivera.com\/wp-content\/uploads\/2025\/02\/image002.jpg\" data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-title=\"e-commmerce system \u2013 communication between checkout service and shipping service\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6ODY4MiwidXJsIjoiaHR0cHM6XC9cL2tvZ25pdmVyYS5jb21cL3N0YWdpbmdcL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzAyXC9pbWFnZTAwMi5qcGcifQ%3D%3D\">\n\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"978\" height=\"439\" src=\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/image002.jpg\" class=\"attachment-full size-full wp-image-8682\" alt=\"e-commmerce system \u2013 communication between checkout service and shipping service\" srcset=\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/image002.jpg 978w, https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/image002-300x135.jpg 300w, https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/image002-768x345.jpg 768w, https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/image002-200x90.jpg 200w\" sizes=\"(max-width: 978px) 100vw, 978px\" \/>\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4fe4071 elementor-widget elementor-widget-text-editor\" data-id=\"4fe4071\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<ul><li>Shipping service is responsible for handling deliveries and calling third party shipping services based on the shipping method.<\/li><li>International Shipping to certain countries is not always available. The shipping service is also responsible for validating the incoming shipping request.<\/li><li>The checkout service, before processing the payment, calls this shipping service to validate the shipping details and get delivery details like total shipping cost and approximate delivery date.<\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e1dec86 elementor-widget elementor-widget-heading\" data-id=\"e1dec86\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\"><strong>Consumer - where the contract lives<\/strong><\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e80087e elementor-widget elementor-widget-text-editor\" data-id=\"e80087e\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>As discussed above, Pact follows a consumer-driven approach. This means that our contracts will be defined in the checkout service.<\/p><p>We start by configuring build.gradle to publish the pacts. A pact &#8220;broker&#8221; is used to store the contracts and test verification results. The &#8220;broker&#8221; is essentially a shared server accessible to both parties via network. <a href=\"https:\/\/pactflow.io\">Pactflow<\/a> is a popular\u00a0<span style=\"text-align: var(--text-align);\">cloud-based\u00a0<\/span><span style=\"font-style: inherit; text-align: var(--text-align);\">pact broker.<\/span><\/p><p>In\u00a0<span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 15.3px; white-space: break-spaces; background-color: #f5f2f0;\">build.gradle<\/span>, we configure broker details.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8edbf88 elementor-widget elementor-widget-code-highlight\" data-id=\"8edbf88\" data-element_type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-java line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-java\">\n\t\t\t\t\t<xmp>pact {\n  publish {\n    pactBrokerUrl = System.getenv('PACT_BROKER_BASE_URL')\n    pactBrokerToken = System.getenv('PACT_BROKER_TOKEN')\n    consumerBranch = getGitBranch()\n    consumerVersion = getGitHash()\n  }\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ded8994 elementor-widget elementor-widget-text-editor\" data-id=\"ded8994\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Contract tests can either be run as a separate build task OR be part of an existing integrationTest task already configured in your project.\u00a0<span style=\"font-style: inherit; text-align: var(--text-align);\">Assuming we run the contract tests as a build task of its own, configure the publishing\u00a0<\/span><span style=\"font-style: inherit; text-align: var(--text-align);\">task to run immediately after the contract testing task.<\/span><\/p><p>We run the\u00a0<span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 15.3px; white-space: break-spaces; background-color: #f5f2f0;\">pactPublish<\/span>\u00a0task followed by the\u00a0<span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 15.3px; white-space: break-spaces; background-color: #f5f2f0; text-align: var(--text-align);\">contractTest<\/span><span style=\"font-style: inherit; text-align: var(--text-align);\">\u00a0task.<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fb68f4e elementor-widget elementor-widget-code-highlight\" data-id=\"fb68f4e\" data-element_type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-java line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-java\">\n\t\t\t\t\t<xmp>if (System.getProperty('pactPublish') == 'true') {\n  contractTest.finalizedBy pactPublish\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1588f61 elementor-widget elementor-widget-text-editor\" data-id=\"1588f61\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>For testing the consumer, we first add a dependency. This includes the library APIs needed to execute the test in Spock.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e8eb90e elementor-widget elementor-widget-code-highlight\" data-id=\"e8eb90e\" data-element_type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-java line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-java\">\n\t\t\t\t\t<xmp>testImplementation 'au.com.dius.pact.consumer:groovy:4.6.15'<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-caf3d45 elementor-widget elementor-widget-text-editor\" data-id=\"caf3d45\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We now define the contract test. This is the most critical step in the entire process. The pact consumer library will generate a contract json from the tests defined in this specification and also publish it to the pact broker when the pactPublish task is run.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-308dde3 elementor-widget elementor-widget-code-highlight\" data-id=\"308dde3\" data-element_type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-java line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-java\">\n\t\t\t\t\t<xmp>class ContractSpec extends Specification {\n  .\n  .\n  .\n\n  void \"should update shipping delivery details successfully\"() {\n    given: 'a valid request is made to update shipping delivery details'\n    def shippingService = new PactBuilder()\n    shippingService {\n      serviceConsumer \"checkout-service\"\n      hasPactWith \"shipping-service\"\n      port 1234\n      uponReceiving('a request to update update shipping delivery details POST \/v1\/shipping\/$orderId')\n      withAttributes(\n          method: 'POST',\n          path: replace(\"\/v1\/shipping\/users\/$orderId\"),\n          headers: [\"Content-Type\": MediaType.APPLICATION_JSON_VALUE]\n      )\n      withBody {\n        shippingAddress {\n            country string(\"US\")\n            state string(\"NY\")\n        }\n        shippingMethod string(\"standard\")\n        weight decimal()\n        dimensions string()\n      }\n      willRespondWith(\n        status: 200,\n        headers: ['Content-Type': MediaType.APPLICATION_JSON_VALUE],\n        body: [\n          data    : [\n            shippingId    : \"<generated-uuid>\",\n            shippingTotal : \"100.00 USD\"\n            deliveryDate  : \"<generated-timestamp>\"\n            carrierCode   : \"USPS\"\n          ]\n        ]\n      )\n    }\n    when:\n    PactVerificationResult result = shippingService.runTest({ mockServer ->\n      ResponseEntity<Object> response = runTestShippingRequest(\n        mockServer.getUrl() + \"\/v1\/shipping\/users\/\" + orderId)\n      Assertions.assertEquals(HttpStatus.OK, response.getStatusCode())\n    })\n\n    then:\n    result == new PactVerificationResult.Ok()\n  }<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-09658f5 elementor-widget elementor-widget-text-editor\" data-id=\"09658f5\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Once you run this test, Pact generates a JSON file which contains the contract definition in <span class=\"code-bg\">build\/pact<\/span> directory. This file can now be copied to the provider. However, the recommended way to use this contract file is by publishing it to a pact broker and verify in the provider service.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f349adf elementor-widget elementor-widget-heading\" data-id=\"f349adf\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Provider - the verification<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5a91361 elementor-widget elementor-widget-text-editor\" data-id=\"5a91361\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Once the contracts are defined, verification becomes fairly easy on the Provider. One specification can verify contracts from all the different consumers communicating with the provider. But how does the provider get all the contracts that need to be verified? The pact broker. The broker details can be configured as environment variables: <span class=\"code-bg\">PACT_BROKER_BASE_URL<\/span>and <span class=\"code-bg\">PACT_BROKER_TOKEN<\/span>.<\/p><p>Add the following dependency in provider project:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-22937d4 elementor-widget elementor-widget-code-highlight\" data-id=\"22937d4\" data-element_type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-java line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-java\">\n\t\t\t\t\t<xmp>testImplementation 'au.com.dius.pact.provider:junit5spring:4.6.15'<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-eabf408 elementor-widget elementor-widget-text-editor\" data-id=\"eabf408\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The Spock provider test class that verifies the contracts published to the Pact broker\u00a0<span style=\"text-align: var(--text-align);\">by the consumer<\/span><span style=\"font-style: inherit; text-align: var(--text-align);\">.<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7f75eaa elementor-widget elementor-widget-code-highlight\" data-id=\"7f75eaa\" data-element_type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-java line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-java\">\n\t\t\t\t\t<xmp>@SpringBootTest(webEnvironment = RANDOM_PORT)\nclass ContractVerificationSpec extends Specification {\n\n    @LocalServerPort\n    private int port\n\n    @Shared\n    ProviderInfo serviceProvider\n\n    ProviderVerifier verifier\n\n    def setupSpec() {\n        String packBrokerUrl = System.getenv(\"PACT_BROKER_BASE_URL\")\n        String packBrokerToken = System.getenv(\"PACT_BROKER_TOKEN\")\n        if (packBrokerUrl != null && packBrokerToken != null) {\n            serviceProvider = new ProviderInfo(\"shipping-service\")\n            serviceProvider.hasPactsFromPactBroker(packBrokerUrl, authentication: ['Bearer', packBrokerToken])\n        }\n    }\n\n    def setup() {\n        verifier = new ProviderVerifier()\n        serviceProvider.port = port\n    }\n\n    @Unroll\n    void 'verify contract with #consumer'() {\n        expect:\n        verifyConsumerPact(consumer) instanceof VerificationResult.Ok\n\n        where:\n        consumer << serviceProvider.consumers\n    }\n\n    private VerificationResult verifyConsumerPact(ConsumerInfo consumer) {\n        verifier.initialiseReporters(serviceProvider)\n        def testResult = verifier.runVerificationForConsumer([:], serviceProvider, consumer)\n\n        if (testResult instanceof VerificationResult.Failed) {\n            verifier.displayFailures([testResult])\n        }\n        testResult\n    }\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-38974a7 elementor-widget elementor-widget-text-editor\" data-id=\"38974a7\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>A common requirement in inter-service communication or any API call for that matter, is <em>API authorization<\/em>.&nbsp;<span style=\"font-style: inherit; text-align: var(--text-align);\">You may want to send an auth token to the API to be verified.&nbsp;<\/span><span style=\"font-style: inherit; text-align: var(--text-align);\">This can be done using the <\/span><span class=\"code-bg\" style=\"font-style: inherit; text-align: var(--text-align);\">setRequestFilter<\/span><span style=\"font-style: inherit; text-align: var(--text-align);\"> method in the <\/span><span class=\"code-bg\" style=\"font-style: inherit; text-align: var(--text-align);\">setupSpec()<\/span><span style=\"font-style: inherit; text-align: var(--text-align);\"> method of the provider test class.<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c1c34e9 elementor-widget elementor-widget-code-highlight\" data-id=\"c1c34e9\" data-element_type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-java line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-java\">\n\t\t\t\t\t<xmp>def setupSpec() {\n       .\n       .\n       .\n            serviceProvider.hasPactsFromPactBroker(packBrokerUrl, authentication: ['Bearer', packBrokerToken])\n\n            serviceProvider.setRequestFilter((Consumer<HttpRequest>) (httpRequest) -> {\n                httpRequest.setHeader(\"Authorization\", \"Bearer \" +\n                    getSignedJwt(false, [], parseUserIdFromPath(httpRequest.getPath())))\n            })\n        .\n        .\n    }<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0116caa elementor-widget elementor-widget-text-editor\" data-id=\"0116caa\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Another responsibility of the provider service is to publish the verification results to the pact broker. A pact broker maintains the published results of all verification operations with a unique version (typically the git commit checksum) which makes it easier to track them in the broker&#8217;s admin UI.<\/p><p>This publishing configuration is done in provider&#8217;s <span class=\"code-bg\">build.gradle<\/span> using <span class=\"code-bg\">pact.verifier.publishResults<\/span> property. The contract verification task can be run along with the other integration tests.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d49fe65 elementor-widget elementor-widget-code-highlight\" data-id=\"d49fe65\" data-element_type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-java line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-java\">\n\t\t\t\t\t<xmp>integrationTest() {\n  useJUnitPlatform()\n  if (System.getProperty('pactPublishResults') == 'true') {\n    systemProperty 'pact.provider.branch', getGitBranch()\n    systemProperty 'pact.provider.version', getGitHash()\n    systemProperty 'pact.verifier.publishResults', 'true'\n  }\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a1a9995 elementor-widget elementor-widget-text-editor\" data-id=\"a1a9995\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The verification runs on the developer&#8217;s machine. But publishing the results at this point is not needed. We can control this using a system property <span class=\"code-bg\">pactPublishResults<\/span>. This flag can be set to <span class=\"code-bg\">true<\/span> on the CI server.<\/p><p>Hope this helps you in getting started with Contract testing with Pact. In part 2 of this series, we will look at the <em>Pactflow<\/em>\u00a0pact broker web application UI and setting up contract testing as part of your CICD pipeline.<\/p><p>\u00a0<\/p><hr \/><p>\u00a0<\/p><p>We&#8217;re hiring! Kognivera is building a team of developers to drive innovation in the retail space and help some of the world&#8217;s largest retailers in their digital transformation journey. <a href=\"https:\/\/kognivera.com\/careers\/\">Join us!<\/a><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Building a microservice architecture to effectively run and operate resilient distributed services is hard. Especially, when you run into a use case that needs inter-service communication. Domain Driven Design principles help in identifying clear boundaries where each microservice is responsible for a well-defined subset of business logic. But at some point, you realise that the [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":8746,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"default","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[33],"tags":[25,30,31,32,28,29,27],"class_list":["post-8417","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microservices","tag-contract-testing","tag-gradle","tag-junit","tag-microservices","tag-pact","tag-spock","tag-test-pyramid"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Contract testing with Pact, Spock and gradle - KogniVera<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Contract testing with Pact, Spock and gradle - KogniVera\" \/>\n<meta property=\"og:description\" content=\"Building a microservice architecture to effectively run and operate resilient distributed services is hard. Especially, when you run into a use case that needs inter-service communication. Domain Driven Design principles help in identifying clear boundaries where each microservice is responsible for a well-defined subset of business logic. But at some point, you realise that the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/\" \/>\n<meta property=\"og:site_name\" content=\"KogniVera\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/profile.php?id=61555489512431\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-19T07:27:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-05T07:34:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01-1024x512.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Gopikrishna Vemula\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/03\/blog01-1536x7681-1.jpg\" \/>\n<meta name=\"twitter:creator\" content=\"@KogniVera\" \/>\n<meta name=\"twitter:site\" content=\"@KogniVera\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mihir Bellare\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/\"},\"author\":{\"name\":\"Gopikrishna Vemula\",\"@id\":\"https:\/\/kognivera.com\/#\/schema\/person\/368fe83c2b58654da8593c18c19fb1ca\"},\"headline\":\"Contract testing with Pact, Spock and gradle\",\"datePublished\":\"2025-02-19T07:27:08+00:00\",\"dateModified\":\"2025-03-05T07:34:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/\"},\"wordCount\":1027,\"publisher\":{\"@id\":\"https:\/\/kognivera.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01.png\",\"keywords\":[\"contract-testing\",\"gradle\",\"junit\",\"Microservices\",\"pact\",\"spock\",\"test-pyramid\"],\"articleSection\":[\"Microservices\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/\",\"url\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/\",\"name\":\"Contract testing with Pact, Spock and gradle - KogniVera\",\"isPartOf\":{\"@id\":\"https:\/\/kognivera.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01.png\",\"datePublished\":\"2025-02-19T07:27:08+00:00\",\"dateModified\":\"2025-03-05T07:34:35+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#primaryimage\",\"url\":\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01.png\",\"contentUrl\":\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01.png\",\"width\":6912,\"height\":3456,\"caption\":\"Contract testing with Pact, Spock and gradle | Kognivera\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kognivera.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Contract testing with Pact, Spock and gradle\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kognivera.com\/#website\",\"url\":\"https:\/\/kognivera.com\/\",\"name\":\"KogniVera\",\"description\":\"Your IT Partner\",\"publisher\":{\"@id\":\"https:\/\/kognivera.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kognivera.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kognivera.com\/#organization\",\"name\":\"KogniVera\",\"url\":\"https:\/\/kognivera.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/kognivera.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2024\/11\/updatedLogo1-1.png\",\"contentUrl\":\"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2024\/11\/updatedLogo1-1.png\",\"width\":500,\"height\":134,\"caption\":\"KogniVera\"},\"image\":{\"@id\":\"https:\/\/kognivera.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/profile.php?id=61555489512431\",\"https:\/\/x.com\/KogniVera\",\"https:\/\/www.linkedin.com\/company\/kognivera\/\",\"https:\/\/www.instagram.com\/kognivera\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/kognivera.com\/#\/schema\/person\/368fe83c2b58654da8593c18c19fb1ca\",\"name\":\"Gopikrishna Vemula\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/kognivera.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7ddf822111efa7383b1bec6cdd1f786b3685f67f3658d664d7a21033d10879e9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/7ddf822111efa7383b1bec6cdd1f786b3685f67f3658d664d7a21033d10879e9?s=96&d=mm&r=g\",\"caption\":\"Gopikrishna Vemula\"},\"url\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Contract testing with Pact, Spock and gradle - KogniVera","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/","og_locale":"en_US","og_type":"article","og_title":"Contract testing with Pact, Spock and gradle - KogniVera","og_description":"Building a microservice architecture to effectively run and operate resilient distributed services is hard. Especially, when you run into a use case that needs inter-service communication. Domain Driven Design principles help in identifying clear boundaries where each microservice is responsible for a well-defined subset of business logic. But at some point, you realise that the [&hellip;]","og_url":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/","og_site_name":"KogniVera","article_publisher":"https:\/\/www.facebook.com\/profile.php?id=61555489512431","article_published_time":"2025-02-19T07:27:08+00:00","article_modified_time":"2025-03-05T07:34:35+00:00","og_image":[{"width":1024,"height":512,"url":"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01-1024x512.png","type":"image\/png"}],"author":"Gopikrishna Vemula","twitter_card":"summary_large_image","twitter_image":"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/03\/blog01-1536x7681-1.jpg","twitter_creator":"@KogniVera","twitter_site":"@KogniVera","twitter_misc":{"Written by":"Mihir Bellare","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#article","isPartOf":{"@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/"},"author":{"name":"Gopikrishna Vemula","@id":"https:\/\/kognivera.com\/#\/schema\/person\/368fe83c2b58654da8593c18c19fb1ca"},"headline":"Contract testing with Pact, Spock and gradle","datePublished":"2025-02-19T07:27:08+00:00","dateModified":"2025-03-05T07:34:35+00:00","mainEntityOfPage":{"@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/"},"wordCount":1027,"publisher":{"@id":"https:\/\/kognivera.com\/#organization"},"image":{"@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#primaryimage"},"thumbnailUrl":"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01.png","keywords":["contract-testing","gradle","junit","Microservices","pact","spock","test-pyramid"],"articleSection":["Microservices"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/","url":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/","name":"Contract testing with Pact, Spock and gradle - KogniVera","isPartOf":{"@id":"https:\/\/kognivera.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#primaryimage"},"image":{"@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#primaryimage"},"thumbnailUrl":"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01.png","datePublished":"2025-02-19T07:27:08+00:00","dateModified":"2025-03-05T07:34:35+00:00","breadcrumb":{"@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#primaryimage","url":"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01.png","contentUrl":"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2025\/02\/blog01.png","width":6912,"height":3456,"caption":"Contract testing with Pact, Spock and gradle | Kognivera"},{"@type":"BreadcrumbList","@id":"https:\/\/kognivera.com\/staging\/blog\/contract-testing-with-pact-spock-and-gradle\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kognivera.com\/"},{"@type":"ListItem","position":2,"name":"Contract testing with Pact, Spock and gradle"}]},{"@type":"WebSite","@id":"https:\/\/kognivera.com\/#website","url":"https:\/\/kognivera.com\/","name":"KogniVera","description":"Your IT Partner","publisher":{"@id":"https:\/\/kognivera.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kognivera.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/kognivera.com\/#organization","name":"KogniVera","url":"https:\/\/kognivera.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/kognivera.com\/#\/schema\/logo\/image\/","url":"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2024\/11\/updatedLogo1-1.png","contentUrl":"https:\/\/kognivera.com\/staging\/wp-content\/uploads\/2024\/11\/updatedLogo1-1.png","width":500,"height":134,"caption":"KogniVera"},"image":{"@id":"https:\/\/kognivera.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/profile.php?id=61555489512431","https:\/\/x.com\/KogniVera","https:\/\/www.linkedin.com\/company\/kognivera\/","https:\/\/www.instagram.com\/kognivera\/"]},{"@type":"Person","@id":"https:\/\/kognivera.com\/#\/schema\/person\/368fe83c2b58654da8593c18c19fb1ca","name":"Gopikrishna Vemula","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/kognivera.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/7ddf822111efa7383b1bec6cdd1f786b3685f67f3658d664d7a21033d10879e9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7ddf822111efa7383b1bec6cdd1f786b3685f67f3658d664d7a21033d10879e9?s=96&d=mm&r=g","caption":"Gopikrishna Vemula"},"url":""}]}},"_links":{"self":[{"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/posts\/8417","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/comments?post=8417"}],"version-history":[{"count":159,"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/posts\/8417\/revisions"}],"predecessor-version":[{"id":9530,"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/posts\/8417\/revisions\/9530"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/media\/8746"}],"wp:attachment":[{"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/media?parent=8417"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/categories?post=8417"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kognivera.com\/staging\/wp-json\/wp\/v2\/tags?post=8417"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}