<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kaustav 🏳️‍🌈</title>
    <description>The latest articles on DEV Community by Kaustav 🏳️‍🌈 (@kaustavdm).</description>
    <link>https://dev.to/kaustavdm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F129515%2F467771c1-dc4f-4fa9-99df-0c1bf84fa068.jpg</url>
      <title>DEV Community: Kaustav 🏳️‍🌈</title>
      <link>https://dev.to/kaustavdm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kaustavdm"/>
    <language>en</language>
    <item>
      <title>APIOps: The art of mixing APIs</title>
      <dc:creator>Kaustav 🏳️‍🌈</dc:creator>
      <pubDate>Tue, 28 May 2019 15:33:23 +0000</pubDate>
      <link>https://dev.to/kaustavdm/apiops-the-art-of-mixing-apis-4lck</link>
      <guid>https://dev.to/kaustavdm/apiops-the-art-of-mixing-apis-4lck</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Good APIs encapsulate domain knowledge.&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;You may use Twilio to embed multi-channel in-app communications, Stripe to process payments and AWS to host your applications. When you use an API, you let domain experts take care of the nitty-gritties while you get your work done. Much of our daily tasks today depend on calling multiple endpoints across different services in a single workflow.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In this article we will look at what involves APIOps and how you can do it with Postman. I will cover some of the lesser known features of Postman that will upgrade your APIOps game.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  API-first Ops is for everyone
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;APIOps&lt;/em&gt;&lt;/strong&gt; is a nice little term for performing tasks that involve APIs. It becomes significant in API-first organisations. DevOps teams need to spend more time and effort working with APIs to keep systems up and running. Testers need to work with API testing tools to ensure their APIs behave as expected. APIOps is not limited to engineering functions. It can span the entirety of an organisation — in sales, marketing, devrel, success, support. You name it.&lt;/p&gt;

&lt;p&gt;Think of it in this way: &lt;em&gt;If you use APIs to get things done, you are doing APIOps.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  At Postman, we’re (web)hooked to Slack
&lt;/h3&gt;

&lt;p&gt;The Postman team relies &lt;em&gt;a lot&lt;/em&gt; on Slack for internal communications. Just like any organisation of our size and scale, we use an array of tools to get different tasks done. We use JIRA and Aha! for project management, Bitbucket to host code, AWS to host our platform, Sentry to track errors, Zendesk for support, Strikedeck for customer success, Salesforce to keep the sales pipelines alive and Looker for data science. The list goes on. Each function has its own needs and the right tools for the job.&lt;/p&gt;

&lt;p&gt;Among all these tools, Slack is the one where everyone in the organisation is present. Slack has organically emerged as the de-facto medium for consuming reports at Postman, made possible by &lt;a href="https://api.slack.com/incoming-webhooks"&gt;Slack API’s webhooks&lt;/a&gt;. It is almost a custom now for a new team member’s first &lt;a href="https://learning.getpostman.com/docs/postman/collections/intro_to_collections"&gt;Postman Collection&lt;/a&gt; to push the end result to Slack. If we were to run a scan to find the most common request across all of the collections that the Postman team creates, “Post to Slack” will definitely rank the first.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Protip: Postman’s growing collection of &lt;a href="https://blog.getpostman.com/2018/11/02/created-a-killer-collection-share-it-with-postmans-5-million-developers-via-a-template/"&gt;Templates&lt;/a&gt; has some interesting use cases for APIOps.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wr6CiAHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AYVxpaAChFGHVAii5-PzDww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wr6CiAHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AYVxpaAChFGHVAii5-PzDww.png" alt=""&gt;&lt;/a&gt;Searching for “Slack” in the Templates listing inside the app shows templates that do &lt;em&gt;something&lt;/em&gt; with Slack. You can access this by Clicking “New” → “Templates” and typing in “Slack” in the search bar.&lt;/p&gt;

&lt;p&gt;This practice has resulted in a rich set of collections that we use internally. We polish and publish some of those as templates in Postman for you to remix and reuse. We have collections which scan &lt;a href="https://medium.com/better-practices/auditing-identity-access-management-iam-systems-at-postman-using-postman-8e7549237813"&gt;AWS IAM for security audit&lt;/a&gt; and send those results to Slack. We have a collection that posts every new comment from &lt;a href="https://github.com/postmanlabs/postman-app-support/"&gt;Postman’s GitHub issue queue&lt;/a&gt; to a Slack channel for everyone to see. We have another collection that alerts us of topics that have received no reply in our &lt;a href="https://community.getpostman.com"&gt;Discourse community forum&lt;/a&gt;. Among the fun ones, we have a collection that scans for nearest Sushi places using the Google Maps API and posts the findings as a Twitter DM.&lt;/p&gt;

&lt;p&gt;The best part? All of these are programmable. You can hack on them. Remix them. Adapt them to your use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four aspects of APIOps
&lt;/h2&gt;

&lt;p&gt;Whether your task at hand is to deploy an application, react to new entries, or to find the nearest Sushi bar, there are few aspects common to workflows involving HTTP APIs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Interact with multiple APIs.&lt;/strong&gt; Mix and match APIs across different services to fulfil a business requirement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chain API calls.&lt;/strong&gt; You will want to trigger a group of HTTP requests one after the other. You will need to share data across these requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trigger conditional workflows.&lt;/strong&gt; Change execution order of requests based on responses. For example, you may want to call a webhook 10 times if you receive an array of 10 items from a previous request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make end result consumable.&lt;/strong&gt; Send and compile reports of each execution to places where they can be consumed by others. This can be a Slack channel, an Airtable base, a remote database or an analytics system.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, if you find yourself increasingly using APIs in your daily work, how will Postman help you? Postman today packs a lot more power than the simple HTTP client that it started off as. Let us dig in.&lt;/p&gt;

&lt;h2&gt;
  
  
  APIOps with Postman
&lt;/h2&gt;

&lt;p&gt;Doing APIOps using Postman consists of a few common tasks. At a high level, you create a collection in Postman to send requests to the endpoints that you need; use environments to manage variable data; add scripts to the requests to perform the computations; use some other endpoint to send results to respective services.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Protip: If you are new to Postman, you would want to read through &lt;a href="https://learning.getpostman.com/docs/postman/environments_and_globals/intro_to_environments_and_globals/"&gt;environments&lt;/a&gt; in Postman, &lt;a href="https://learning.getpostman.com/docs/postman/environments_and_globals/variables/#variable-scopes"&gt;variable scopes&lt;/a&gt;, &lt;a href="https://learning.getpostman.com/docs/postman/scripts/intro_to_scripts"&gt;scripting&lt;/a&gt;, &lt;a href="https://learning.getpostman.com/docs/postman/scripts/pre_request_scripts"&gt;pre-request scripts&lt;/a&gt;, &lt;a href="https://learning.getpostman.com/docs/postman/scripts/test_scripts"&gt;tests&lt;/a&gt;, &lt;a href="https://learning.getpostman.com/docs/postman/collection_runs/intro_to_collection_runs"&gt;running collections&lt;/a&gt; and &lt;a href="https://learning.getpostman.com/docs/postman/monitors/intro_monitors"&gt;monitors&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  A template for TL;DR
&lt;/h3&gt;

&lt;p&gt;To make things simpler, I have created a collection called &lt;a href="https://documenter.getpostman.com/view/4946945/S1Lr4WKg"&gt;&lt;strong&gt;“APIOps 101”&lt;/strong&gt;&lt;/a&gt; that covers all the features you need to know to do the 4 steps mentioned above, with a few examples thrown in. You can directly download the &lt;strong&gt;APIOPS 101&lt;/strong&gt; collection if you have the Postman app installed by clicking the button below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.getpostman.com/run-collection/d9998be8d58b3906cb82#?env%5BAPIOps%20101%5D=W3sia2V5IjoibG9vcEl0ZW1zIiwidmFsdWUiOiJbMSwyLDMsNCw1LDYsNyw4LDksMTBdIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJzbGFja1VybCIsInZhbHVlIjoiaHR0cHM6Ly9ob29rcy5zbGFjay5jb20vc2VydmljZXMveHh4eC94eHh4L3h4eHgiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImFpcnRhYmxlVXJsIiwidmFsdWUiOiI8eW91ci1haXJ0YWJsZS1hcGktdXJsPiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYWlydGFibGVLZXkiLCJ2YWx1ZSI6Ijx5b3VyLWFpcnRhYmxlLWtleT4iLCJlbmFibGVkIjp0cnVlfV0="&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V37vEqA7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://run.pstmn.io/button.svg" alt="Run in Postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v93k5e24--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AJYctBXZqozV5G3p5MPeNnA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v93k5e24--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AJYctBXZqozV5G3p5MPeNnA.png" alt=""&gt;&lt;/a&gt;Documentation for the &lt;a href="https://documenter.getpostman.com/view/4946945/S1Lr4WKg"&gt;APIOps 101 collection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The remaining sections of the article will elaborate on the tips and tricks mentioned in this template. You can download it and follow along, or just continue reading.&lt;/p&gt;

&lt;h4&gt;
  
  
  Collections — running and sharing them
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://learning.getpostman.com/docs/postman/collections/creating_collections"&gt;Postman collections&lt;/a&gt; let you reuse workflows. You can add and organise requests in folders and subfolders within a collection. Creating a collection is the first stage of any APIOps you may do in Postman.&lt;/p&gt;

&lt;p&gt;When you combine your requests in a collection, you build a workflow that can interact with different APIs. Each collection typically represents one workflow. Each folder in the collection represents a unit of the workflow. Think of it as building recipes for your favourite cuisines.&lt;/p&gt;

&lt;p&gt;Collections are executable. When you run a collection, Postman triggers the requests in the collection one by one. This is the base of the automation you need for APIOps, allowing you to mix calls across APIs and chain those calls. You can run a collection from the Postman app or in CLI (using &lt;a href="http://&amp;lt;https://learning.getpostman.com/docs/postman/collection_runs/command_line_integration_with_newman"&gt;newman&lt;/a&gt;) or on a schedule using &lt;a href="https://learning.getpostman.com/docs/postman/monitors/intro_monitors"&gt;Monitors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once you have a few collections, you can collaboratively work on them by sharing them with your team members in team &lt;a href="https://learning.getpostman.com/docs/postman/workspaces/intro_to_workspaces"&gt;workspaces&lt;/a&gt;. That way, your collections (and, your API workflows) never go out of sync.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Protip: For more information on collections and how to run them, you can follow guided lessons in the app. Click the “Bootcamp” icon in the bottom bar of your Postman app to start a guided lesson.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nwq8-EF7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AJPlE1k2OlzYKvpksmPEWWQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nwq8-EF7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AJPlE1k2OlzYKvpksmPEWWQ.png" alt=""&gt;&lt;/a&gt;Bootcamp is an in-built learning tool built into the Postman app. The left sidebar in the image shows the collections organised in the current workspace.&lt;/p&gt;

&lt;h4&gt;
  
  
  Variables and their scopes
&lt;/h4&gt;

&lt;p&gt;The next thing to know are &lt;a href="https://learning.getpostman.com/docs/postman/environments_and_globals/variables/"&gt;variable scopes&lt;/a&gt;. Variables are the foundation of dynamic behaviour in Postman. You can use variables in requests, environment, collection and global scopes. In requests, variables use a double braces syntax. For example, &lt;code&gt;{{url}}&lt;/code&gt; is a variable which you can substitute by declaring their value at any of the scopes. You can also edit them programmatically using scripts.&lt;/p&gt;

&lt;p&gt;Variable scopes in Postman are resolved outside in. If you look at the diagram below, local variables have the highest precedence. Global variables have the least. Let’s look at them in brief:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dy0J3sL4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/928/1%2AVh6fU7yeaNCI2Idyk4BFWQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dy0J3sL4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/928/1%2AVh6fU7yeaNCI2Idyk4BFWQ.png" alt=""&gt;&lt;/a&gt;Variable scopes in Postman&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Global variables are valid for the entire Postman instance, multiple collections can share a single global variable.&lt;/li&gt;
&lt;li&gt;Collection variables apply to all the requests in that collection. The same variable set at a collection level will override the global variable, and will be available only for the scope of that collection.&lt;/li&gt;
&lt;li&gt;Environment variables are unique here. They override collection variables, but you can carry around an environment. Think of environments as a shareable container of variables that you can apply to multiple collections. You use pm.environment.get('key') and pm.environment.set('key', 'value') to get and set them through scripts.&lt;/li&gt;
&lt;li&gt;Local variables apply to a single request or to a single collection run. They override environment variables. You use pm.variables.get('key') to retrieve them and pm.variables.set('key', 'value') to set them through scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use local variables to transfer data between requests
&lt;/h4&gt;

&lt;p&gt;Local variables come in very handy when you are building workflows using requests. You can transfer data between requests using either environment or local variables. The upside of using local variables in this context is that you don’t have to worry about your environments bloating up, since these variables will be reset after each run. It is also a more secure alternative to share sensitive data between requests.&lt;/p&gt;

&lt;p&gt;The typical flow here is to process the response using scripts in the “Tests” tab of a request, set the required data as a local variable using pm.variables.set() and access it in next requests.&lt;/p&gt;

&lt;p&gt;For example, your collection may have a request to fetch an authentication key and then use that same authentication key in subsequent requests. In this case, the first request can set the variable in the “Tests” section using something like pm.variables.set('authKey', authkey) (assuming authKey is the variable in your scripts). Subsequent requests can use the &lt;code&gt;{{authKey}}&lt;/code&gt; variable in their headers or query params, wherever needed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Protip: Variables can only store strings, so a common practice here is to JSON.stringify() the data before setting the variable. You can then use JSON.parse() after getting the variable later on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another common use case for local variables is to calculate values at runtime to add dynamic behaviour in a request. For example, you can use the following script to set the structure of a request to post data to Slack in the pre-request tab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Prepare the body for the Slack message&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slackBody&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;*Title here&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mrkdwn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;attachments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Field name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Some value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Another field name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Some more value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slackBody&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slackBody&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can then set the body of the same request to &lt;code&gt;{{slackBody}}&lt;/code&gt;. Like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KvP9BmJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/659/1%2AeCxax_kyYGm8HVeaAl4YVQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KvP9BmJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/659/1%2AeCxax_kyYGm8HVeaAl4YVQ.png" alt=""&gt;&lt;/a&gt;Setting the &lt;code&gt;{{slackBody}}&lt;/code&gt; variable in the body of the request&lt;/p&gt;

&lt;h4&gt;
  
  
  Use environment with Postman API to store states
&lt;/h4&gt;

&lt;p&gt;You would often need to save states across collection runs. Collections runs are stateless. But, you can use environments to store data that you would need in subsequent runs. A common example of this is in processing lists of data, like parsing an RSS feed and sending new entries to Slack. You may need to remember which entries you have already processed so that you don’t trigger a notification for the existing one.&lt;/p&gt;

&lt;p&gt;A quick and easy solution for this is to attach an environment to your collection runs and update the environment variables using pm.environment.set(). But, Monitors don't persist environment across monitor runs. This is where the &lt;a href="https://api.getpostman.com"&gt;Postman API&lt;/a&gt; comes handy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lJcOKoTF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ArqYxe09BhFDh-Xwkr-lwPA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lJcOKoTF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ArqYxe09BhFDh-Xwkr-lwPA.png" alt=""&gt;&lt;/a&gt;Postman API documentation page showing the “Update Environment” endpoint.&lt;/p&gt;

&lt;p&gt;You can use the “Update Environment” endpoint of the Postman API to update an environment with latest data. This can be a final request in your collection to save any relevant state by calling the Postman API. You can access the environment UID by switching to “Browse” view and opening the environment in the web dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ga7-uJs_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/659/1%2A84ah0BWM4LX4k5tAEXzD1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ga7-uJs_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/659/1%2A84ah0BWM4LX4k5tAEXzD1A.png" alt=""&gt;&lt;/a&gt;A pre-request script to convert the current environment keys into the data structure that the Postman API will accept for the “Update Environment” endpoint.&lt;/p&gt;

&lt;p&gt;This way, your collections remain portable across Monitors, in-app collection runner and newman.&lt;/p&gt;

&lt;h4&gt;
  
  
  Control execution order with postman.setNextRequest()
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://learning.getpostman.com/docs/postman/scripts/branching_and_looping"&gt;postman.setNextRequest() method&lt;/a&gt; is one of the lesser used, but incredibly useful API that the Postman Sandbox exposes. You can use it in your script to branch out your execution order based on responses. This method takes one argument, the name of a request to execute after the current one.&lt;/p&gt;

&lt;p&gt;Here are three very interesting things you can do with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Loop on the same request&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can pass the current request name as argument to the method to loop on the same request. Like, postman.setNextRequest("Process response array") where your current request name is "Process response array". You will need to ensure that you have some terminating condition to break out of the loop. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Assuming "results" in a stringified array&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;results&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Get the last item of the array&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;currentResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... perform your action&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// If there are more entries, loop on the same request.&lt;/span&gt;
&lt;span class="c1"&gt;// This is the terminating condition.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Stringify the remaining array items&lt;/span&gt;
  &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;results&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="c1"&gt;// Set the next request to the current one&lt;/span&gt;
  &lt;span class="nx"&gt;postman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setNextRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Post to Airtable&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Dynamically iterate on input data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Extending the previous point, you can loop on the same request to parse &lt;a href="https://learning.getpostman.com/docs/postman/collection_runs/working_with_data_files"&gt;JSON or CSV inputs&lt;/a&gt;. &lt;a href="https://twitter.com/ambertests"&gt;Amber Race&lt;/a&gt; has written a nice article describing how you can &lt;a href="https://ambertests.com/2019/01/28/postman-how-to-dynamic-iteration-within-a-collection/"&gt;loop on the same request to process CSV data inputs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Stop executing further requests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can stop executing next requests by passing null as argument to postman.setNextRequest(). Taking the previous example about parsing an RSS feed, you won't want to trigger a notification if there are no new items. In that case, the request that parses the RSS feed can set postman.setNextRequest(null), if there are no new entries. If the request to post to Slack is present after the current request, Postman will not stop execution and not trigger that request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Assuming `postsForSlack` is an array of entries,&lt;/span&gt;
&lt;span class="c1"&gt;// if there are any new posts to notify via Slack,&lt;/span&gt;
&lt;span class="c1"&gt;// call the next request, otherwise terminate collection run&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;postsForSlack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;postman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setNextRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No new articles found.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Write tests and set expectations
&lt;/h3&gt;

&lt;p&gt;Finally, you would want to automate expectations. So, write as many tests as you need in the Tests tab of your requests and assert on the responses. That way, you will be able to ensure that all your responses and data structures are as you expect. You can read through the &lt;a href="https://learning.getpostman.com/docs/postman/scripts/test_scripts"&gt;test scripts documentation&lt;/a&gt;, or try the quick snippets in the Postman app, or try the Bootcamp for automated testing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r7Nocl0W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AVQs4KsMx_tiHW1qHrxm1Sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r7Nocl0W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AVQs4KsMx_tiHW1qHrxm1Sw.png" alt=""&gt;&lt;/a&gt;Expectations in tests using pm.test() and pm.expect() methods, with snippets on the right.&lt;/p&gt;




&lt;p&gt;With these tools in your toolkit, you will now be able to mix and mash APIs together as you wish. Go ahead and explore it! If you end up building something interesting, share those collections as templates for the rest of the community to remix. Happy APIOps-ing!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover Photo by &lt;a href="https://unsplash.com/@barnimages"&gt;Barn Images&lt;/a&gt; on &lt;a href="https://unsplash.com"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>agile</category>
      <category>slack</category>
      <category>devops</category>
    </item>
    <item>
      <title>Consumer-driven Contract Testing using Postman</title>
      <dc:creator>Kaustav 🏳️‍🌈</dc:creator>
      <pubDate>Fri, 24 May 2019 10:15:37 +0000</pubDate>
      <link>https://dev.to/kaustavdm/consumer-driven-contract-testing-using-postman-npm</link>
      <guid>https://dev.to/kaustavdm/consumer-driven-contract-testing-using-postman-npm</guid>
      <description>&lt;p&gt;API behavior is typically described in documentation pages which list available endpoints, request data structures and expected response data structures, along with sample query and responses. These documentation are then used by people building systems that consume those APIs.&lt;/p&gt;

&lt;p&gt;But, documentation written separately do not shield the consumers of the APIs from changes in the API. API producers may need to change the response data structure or rename an endpoint altogether to keep up with business requirements.&lt;/p&gt;

&lt;p&gt;The onus of incorporating these changes then falls on the consumers of those APIs who have to keep checking the documentation for any changes. This model does not scale well. Consumers often end up with unexpected bugs because the response they were expecting had changed.&lt;/p&gt;

&lt;p&gt;This is where having consumers assert on API contracts become useful. Instead of having API producers build a specification on their own, consumers of those APIs can set expectations by letting the producers know what data they want from the API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rybta4vV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1200/1%2AI8DFC8EMPeVcuLqrto7U0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rybta4vV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1200/1%2AI8DFC8EMPeVcuLqrto7U0w.png" alt="An example scenario documenting steps that are usually taken in building consumer-driven contracts for microservices"&gt;&lt;/a&gt;An example scenario documenting steps that are usually taken in building consumer-driven contracts for microservices&lt;/p&gt;

&lt;p&gt;API design then turns into a negotiation between what the consumers need and what the providers can give.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make API contracts explicit and executable
&lt;/h2&gt;

&lt;p&gt;Postman &lt;a href="https://www.getpostman.com/infographics/postman-community-survey-2018.pdf"&gt;conducted a survey&lt;/a&gt; in 2018 which showed that the majority of business APIs are internal. These are teams building services within an organization which comes together to build a larger, user-facing product. In such contexts, ensuring that there are no differences between the expectations of the consumers and the data delivered by the API becomes a vital part of the organization’s workflow. Having explicit, shareable and executable contracts shield from much of this confusion and frustration.&lt;/p&gt;

&lt;p&gt;Instead of documenting API behavior in a static page, producers can start by creating a specification for their API with any of the popular tools on the market, like RAML, API Blueprint, OpenAPI, Pact or &lt;a href="http://blog.getpostman.com/2018/03/08/the-good-collection/"&gt;Postman Collections&lt;/a&gt;. The last two, Pact and Postman let you implement consumer-driven contracts as a first-class concept. Pact further focuses exclusively on contract testing, while the Postman ecosystem packs a lot more power beyond that.&lt;/p&gt;

&lt;p&gt;All of these formats allow you to specify details about your API’s behavior. They let you convey the &lt;em&gt;intent&lt;/em&gt; of the API through endpoint names, descriptions, data types and data structure for requests and responses. They also support adding examples to each endpoint.&lt;/p&gt;

&lt;p&gt;Once you have your specification in these formats, you can run tools that generate test code or directly send requests to a given service using the structure of endpoints described in the spec. The degree of flexibility you get varies with the toolset you use.&lt;/p&gt;

&lt;p&gt;These specifications form the source of contracts for your service — the agreement between what the producer provides and what the consumers can expect. The underlying value of each of these toolsets is that they make your API structure explicit to those collaborating to build the service as well as to the service’s consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test contracts against multiple consumers
&lt;/h2&gt;

&lt;p&gt;If you are a consumer, having such a specification handy will let you figure out exactly what data you want to fetch from the API. You can write your tests to set expectations and assert on the data that your service will use. There are two major benefits to this approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can run your test suite whenever there is a change in the specification and respond to changes in the API specification proactively, and,&lt;/li&gt;
&lt;li&gt;You can participate in the design process of the API as a consumer and let your needs be known before a contract is formalized.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In consumer-driven contract testing, the contracts are written and managed explicitly by the consumers. If the producer needs to make some changes to their service, like implementing a new feature, producers will get to know which consumers they broke just by looking at which consumer’s contract tests have failed. This frees API providers from worrying about accidentally breaking consumer apps or services every time they make some change to their service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Independent service testing
&lt;/h2&gt;

&lt;p&gt;This reduces the need to perform end-to-end testing of services. If all the contract tests pass, the API producer can be reasonably certain that their service performs as expected when integrated with other services. This is a huge respite from the complexity of doing end-to-end tests in a microservice environment.&lt;/p&gt;

&lt;p&gt;End-to-end tests can be expensive and cumbersome to do for every change to the API. Producers and consumers can move at their own pace, have their own roadmaps and continuously deploy their changes. Consumer teams need to worry only when there is a failure in the contract tests. Coupling this with an updated documentation, generated automatically from the specification, make failures quick to detect without building up complex setups required to run end-to-end tests.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using Postman for consumer-driven contracts
&lt;/h1&gt;

&lt;p&gt;Postman has all the tools you need in place to start implementing contract testing in your organization. Postman Collections are executable specifications of an API. You can run a collection either on your local machine using the Postman app, on the command line and CI systems using &lt;a href="https://www.getpostman.com/docs/v6/postman/collection_runs/command_line_integration_with_newman"&gt;newman&lt;/a&gt; and in the cloud using &lt;a href="https://www.getpostman.com/docs/v6/postman/monitors/intro_monitors"&gt;Monitors&lt;/a&gt;. In either case, requests in your collection are executed sequentially.&lt;/p&gt;

&lt;p&gt;Further, you can add dynamic behavior to your requests with pre-request scripts and assert on responses with tests. The article on &lt;a href="https://medium.com/postman-engineering/from-manual-to-automated-testing-the-roadblocks-and-the-journey-6333dfacc5ae"&gt;transitioning from manual to automated API testing&lt;/a&gt; in Postman runs you through details of these steps.&lt;/p&gt;

&lt;p&gt;Couple all of these with &lt;a href="https://medium.com/postman-engineering/how-to-dissolve-communication-barriers-in-your-api-development-organization-3347179b4ecc"&gt;Workspaces in Postman&lt;/a&gt; and you have executable, shared and collaborative contract collections ready for your entire team. You don’t need to manually share these details with your team members.&lt;/p&gt;

&lt;p&gt;Let me run you through an example use case on how these come together to implement consumer-driven contracts.&lt;/p&gt;

&lt;h2&gt;
  
  
  A sample use case: Simple log retrieval service
&lt;/h2&gt;

&lt;p&gt;Let’s say we need to build a hypothetical service that returns a list of log entries from some centralized log storage. This service exposes only one endpoint (for simplicity’s sake) that returns latest 5 log entries, with the name of the service that created the entry, timestamp of the entry and a description string describing the entry.&lt;/p&gt;

&lt;p&gt;The endpoint resides at &lt;code&gt;/api/v1/logs&lt;/code&gt;. Sending a &lt;code&gt;GET&lt;/code&gt; request to this endpoint is supposed to return JSON data in this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;entries&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;entries&lt;/code&gt; array will contain an object for each log entry. Their data structure will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serviceName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Blueprint
&lt;/h2&gt;

&lt;p&gt;First, we create a blueprint collection. A blueprint collection lays down the API structure. This is created by the producer of the service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can access the blueprint collection for this example by clicking the button below:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.getpostman.com/run-collection/9eef1b9b397c143b143f"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V37vEqA7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://run.pstmn.io/button.svg" alt="Run in Postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SW4Qicav--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A7p0fisGQeTheC2WNcR5h1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SW4Qicav--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A7p0fisGQeTheC2WNcR5h1A.png" alt="Sample blueprint collection"&gt;&lt;/a&gt;Sample blueprint collection&lt;/p&gt;

&lt;p&gt;Then, we add &lt;a href="https://www.getpostman.com/docs/v6/postman/collections/examples"&gt;examples for the request&lt;/a&gt;. I had already added an example. Examples allow such blueprint collections to describe response data. They show up in documentation generated by Postman. Here is an example of response data for the default output of this service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;entries&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serviceName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1540206226229&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Received foo request from user 100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serviceName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1540206226121&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sent email to user 99&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serviceName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;154020622502&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Received foo request from user 10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serviceName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;baz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1540206223230&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Activated user 101&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serviceName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1540206222126&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error sending email to user 10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Each example has a name and specific request path. This is how it looks in the Postman app:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PvgfGW9k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AMbv-RFbLIF5RRMLtT6Ab8Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PvgfGW9k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AMbv-RFbLIF5RRMLtT6Ab8Q.png" alt="Adding example to sample blueprint collection’s request"&gt;&lt;/a&gt;Adding example to sample blueprint collection’s request&lt;/p&gt;

&lt;p&gt;With these in place, Postman generates web-based documentation for the blueprint automatically. Below is a screenshot of how the published documentation looks like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i841kyy9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AAg9cm5sxkftWzuRKWaDoKA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i841kyy9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AAg9cm5sxkftWzuRKWaDoKA.png" alt="Published documentation generated by Postman from the sample blueprint collection"&gt;&lt;/a&gt;Published documentation generated by Postman from the sample blueprint collection&lt;/p&gt;

&lt;p&gt;All members who are part of the workspace in which this collection was created can view the documentation and access the collection, making it an excellent way of collaborating with other members. The service owners can then create a mock server in Postman based on this collection. The examples added in the request are sent as part of the mock server response.&lt;/p&gt;

&lt;p&gt;Once a mock server is created in Postman, you can make requests to the mock service by using the same endpoint after the mock server URL that Postman generates for you. So, making a request to &lt;code&gt;https://&amp;lt;mock-server-id&amp;gt;.pstmn.io/api/v1/logs&lt;/code&gt; will return the following response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vpuNAM5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AGiPQ5S4jhDePvj32jNgJGQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vpuNAM5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AGiPQ5S4jhDePvj32jNgJGQ.png" alt="Response returned from mock server created from sample collection"&gt;&lt;/a&gt;Response returned from mock server created from sample collection&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing contract collections
&lt;/h2&gt;

&lt;p&gt;Consumers of the service can build their contract collections based on the blueprint and the mock. Postman tests allow you to assert on every aspect of the response — including response headers, body and response time. So, contracts can make use of all of them and build robust tests.&lt;/p&gt;

&lt;p&gt;For this example, let us assume there is only one consumer of this service. To keep things simple, our contract collection example will also have one request and it will assert only on the response data structure. A real-world contract would assert on the data structure as well as the data received in the response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5QcQNsSp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AZgFFwoBEitJ7kgYqlocFOA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5QcQNsSp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AZgFFwoBEitJ7kgYqlocFOA.png" alt="Consumer contract collection using tests to assert on response data"&gt;&lt;/a&gt;Consumer contract collection using tests to assert on response data&lt;/p&gt;

&lt;p&gt;Here is the test script that the contract collection can use to test the data structure mentioned above. It uses the &lt;code&gt;tv4&lt;/code&gt; library, which is shipped as part of the &lt;a href="https://www.getpostman.com/docs/postman/scripts/postman_sandbox"&gt;Postman Sandbox&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define the schema expected in response&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;responseSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;properties&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;entries&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;array&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;items&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;properties&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serverName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Get response data as JSON&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Test for response data structure&lt;/span&gt;
&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ensure expected response structure&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;validation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tv4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseSchema&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You can download the contract collection by clicking the button below:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.getpostman.com/run-collection/cd78233f590dbd250abc"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V37vEqA7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://run.pstmn.io/button.svg" alt="Run in Postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the use of the &lt;code&gt;{{url}}&lt;/code&gt; variable placeholder in the contract collection. &lt;strong&gt;When the service is in its early phase, consumers can use the mock server URL to make the requests. When the service has been built, the environment variable can be switched to point to a hosted instance of the service.&lt;/strong&gt; This way, development of the consumer apps or services can happen in parallel without remaining blocked for the upstream service to be built.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous testing
&lt;/h2&gt;

&lt;p&gt;Contracts need to be continuously tested to ensure they are valid over time. There are two ways this can be achieved.&lt;/p&gt;

&lt;p&gt;If you have an existing continuous integration system: You can export collection files and environments from Postman and run them from the &lt;a href="https://www.getpostman.com/docs/v6/postman/collection_runs/command_line_integration_with_newman"&gt;command-line using newman&lt;/a&gt;. Refer to newman’s documentation for steps to set up continuous builds for &lt;a href="https://www.getpostman.com/docs/v6/postman/collection_runs/integration_with_jenkins"&gt;Jenkins&lt;/a&gt; and &lt;a href="https://www.getpostman.com/docs/v6/postman/collection_runs/integration_with_travis"&gt;Travis CI&lt;/a&gt;. Your build pipelines can be triggered every time there is a change in the specification or a new version of the upstream service.&lt;/p&gt;

&lt;p&gt;Along with that, you can also run contract collections using Postman Monitors. Monitors can run periodically, making it an excellent tool to get a long-term overview of contract breakages.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Read more about &lt;a href="https://medium.com/better-practices/continuous-testing-of-apis-5294552d65ce"&gt;Continuous Testing of APIs with Postman&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Organizing contract tests
&lt;/h2&gt;

&lt;p&gt;Real-world tests have setup and teardown phases. Contract tests are no different. A common use case for contract tests is to populate the system being tested with some data, then perform operations on it and finally remove those test data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A neat pattern of emulating this in Postman is to have a &lt;code&gt;Setup&lt;/code&gt; folder as the first folder in the collection and a &lt;code&gt;Teardown&lt;/code&gt; folder as the last folder of your collection.&lt;/strong&gt; All contract tests then go as folders in between the &lt;code&gt;Setup&lt;/code&gt; and &lt;code&gt;Teardown&lt;/code&gt; folders. This will ensure that Postman will always run the requests in the &lt;code&gt;Setup&lt;/code&gt; folder in the beginning of a collection run, then run the requests performing actual testing, and end with running all the requests in the &lt;code&gt;Teardown&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;We make use of this pattern heavily when writing the internal contracts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N0deyZs5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Amwz39KbtJ8XRnEDkjis4bw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N0deyZs5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Amwz39KbtJ8XRnEDkjis4bw.png" alt="Setup and Teardown folders in an actual contract collection used by the Postman engineering team."&gt;&lt;/a&gt;Setup and Teardown folders in an actual contract collection used by the Postman engineering team.&lt;/p&gt;

&lt;p&gt;This helps in grouping and organizing your tests neatly by abstracting out repetitive tasks in the first and last folders. Ideally, the API producer should provide a collection with the &lt;code&gt;Setup&lt;/code&gt; and &lt;code&gt;Teardown&lt;/code&gt; requests. Consumers can create a duplicate of that collection and add their contract tests.&lt;/p&gt;




&lt;p&gt;The complexity of your contract tests will depend on your business case. One of the extra benefits of writing consumer-driven contract tests is that you can easily spot when a service gets too big or has too many dependencies by looking at the number of consumer contract collections that service has.&lt;/p&gt;

&lt;p&gt;Overall, consumer-driven contracts help keep the surface area for testing microservices and negotiating changes to a controllable size.&lt;/p&gt;

&lt;p&gt;Happy testing!&lt;/p&gt;




&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;a href="http://consumer-driven%20contracts:%20A%20Service%20Evolution%20Pattern/"&gt;Consumer-Driven Contracts: A Service Evolution Pattern&lt;/a&gt;&lt;/em&gt; by Ian Robinson&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;a href="https://books.google.com/books?id=jjl4BgAAQBAJ"&gt;Building Microservices: Designing fine-grained systems&lt;/a&gt;&lt;/em&gt; by Sam Newman&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;a href="https://books.google.co.in/books?id=4YOxDQAAQBAJ"&gt;Microservices From Day One&lt;/a&gt;&lt;/em&gt; by Cloves Carneiro Jr., Tim Schmelmer&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;a href="https://www.infoq.com/articles/microservices-consumer-driven-contracts-pact-docker"&gt;How to be Confident That Your Microservices Can Still Communicate in Production with Pact and Docker&lt;/a&gt;&lt;/em&gt; by Harry Winser&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published as &lt;a href="https://medium.com/better-practices/consumer-driven-contract-testing-using-postman-f3580dba5370"&gt;Consumer-driven Contract Testing using Postman&lt;/a&gt; in &lt;a href="https://medium.com/better-practices"&gt;Better Practices&lt;/a&gt; on Oct 24, 2018.&lt;/em&gt; &lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>microservices</category>
      <category>postman</category>
    </item>
    <item>
      <title>Continuous Testing of APIs</title>
      <dc:creator>Kaustav 🏳️‍🌈</dc:creator>
      <pubDate>Mon, 06 May 2019 11:50:34 +0000</pubDate>
      <link>https://dev.to/kaustavdm/continuous-testing-of-apis-3e5f</link>
      <guid>https://dev.to/kaustavdm/continuous-testing-of-apis-3e5f</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;A strategy to ensure all of your APIs are tested, all the time.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Software composition is increasingly moving towards an API-driven world.&lt;/em&gt; If you follow what we write and talk about at &lt;a href="https://www.getpostman.com"&gt;Postman&lt;/a&gt;, you have probably come across this statement multiple times. We cannot emphasize this enough.&lt;/p&gt;

&lt;p&gt;APIs are the building blocks of large software systems that are being built today. More and more companies are moving towards an API-first approach. Building systems as APIs is becoming a business decision, instead of only a technology decision. Ensuring stability, security, performance, and availability are high priorities in this scenario. These shifts have made API testing a first-class objective when building and shipping APIs.&lt;/p&gt;

&lt;p&gt;At Postman, we have a unique view of this evolving landscape, thanks to our lovely community. We see API testing strategy becoming a necessary part of the API design lifecycle. Just as designing the interface for a service or product’s API is not an afterthought for an API-first organization like us, so is the need to design a resilient testing system for those APIs. My colleague, &lt;a href="https://twitter.com/PetuniaGray"&gt;Joyce&lt;/a&gt;, and I have been talking about this topic since January of 2019 and it is high time that we actually write about it.&lt;/p&gt;

&lt;h3&gt;
  
  
  A collection of strategies
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://medium.com/better-practices"&gt;Better Practices&lt;/a&gt; publication already contains quite a few articles on test automation of APIs. I have talked about how &lt;a href="https://dev.to/kaustavdm/integrating-in-an-api-first-world-235m-temp-slug-2752213"&gt;integration testing of APIs&lt;/a&gt; changes in the context of a service-oriented architecture. We followed that up with how Postman sets you up on the &lt;a href="https://medium.com/better-practices/from-manual-to-automated-testing-the-roadblocks-and-the-journey-6333dfacc5ae"&gt;path to better automation&lt;/a&gt;. We have dived into &lt;a href="https://medium.com/better-practices/consumer-driven-contract-testing-using-postman-f3580dba5370"&gt;consumer-driven contracts&lt;/a&gt; and how they can help you &lt;a href="https://medium.com/better-practices/conquering-the-microservices-dependency-hell-at-postman-with-postman-part-1-introduction-a1ae019bb934"&gt;get over microservice dependency hell&lt;/a&gt;. We have also written about how &lt;a href="https://medium.com/better-practices/snapshot-testing-for-apis-using-postman-7f9f26295d6b"&gt;snapshot testing&lt;/a&gt; improves reliability guarantees of APIs.&lt;/p&gt;

&lt;p&gt;There are a few practices common to all of these solutions. At their core, they are workflows around a set of tools, which when used in a certain way solve a set of problems that API producers and consumers face regularly. Each of these testing patterns are not very useful without rigor.&lt;/p&gt;

&lt;p&gt;APIs represent business domain requirements. They change as requirements evolve. The evolution of an API’s lifecycle needs to be in harmony with other systems that depend on it and with the systems that it depends on. APIs have to be flexible and still not break things as they grow and scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Need for a tight feedback loop
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://medium.com/better-practices/api-first-software-development-for-modern-organizations-fdbfba9a66d3"&gt;Building APIs with an API-first model&lt;/a&gt; in mind takes care of the design aspect of a distributed system. This is especially relevant in the context of microservices. These design and development need to be supported with a resilient testing system that allows you to react to changes in code or business requirements for your APIs.&lt;/p&gt;

&lt;p&gt;You need to know when your APIs fail, why they failed, and you need a tight feedback loop to alert you as soon as possible. So, how do you go about building an API testing pipeline that satisfies all these requirements?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your API testing pipeline needs 3 key stages:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Well-defined tests for your APIs.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ability to run your tests on-demand and on a schedule.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Report back passes and failures to alerting and analytics systems.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Writing good tests
&lt;/h4&gt;

&lt;p&gt;A testing system is as good as the tests. Everything begins with well-written tests. When it comes to testing APIs, you need to assert on the responses sent by the application.&lt;/p&gt;

&lt;p&gt;You can test for the response data-structure, presence (or absence) of specific parameters in the response, response timing, response headers, cookies and response status. If your API is not over HTTP, these semantics may vary. That is a larger discussion, but the core things you would test in a response would still remain the same.&lt;/p&gt;

&lt;p&gt;All of these need good test cases. These test cases should map to business requirements. These can be user stories, user journeys or end-to-end workflows. You can have test cases documented as a BDD specs or as epics/stories in your product management platform or Postman Collections.&lt;/p&gt;

&lt;p&gt;You can pick any tool of your choice as long as you are able to author such tests, preferably collaboratively, and execute those tests when you need.&lt;/p&gt;

&lt;h4&gt;
  
  
  Run your tests on-demand or on schedule
&lt;/h4&gt;

&lt;p&gt;This is the key to continuous testing. To get to this phase, you need to have a continuous integration (CI) pipeline in place. Assuming you have one, you will want to run some of your API tests at build time, and some of your tests on a regular schedule. The cadence will vary based on the scale of your systems and the frequency with which code changes are committed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On-demand runs:&lt;/strong&gt; You would run contract tests, integration tests and end-to-end tests in your build system. Code changes, merges and release flows are the typical sources that trigger build pipelines. Depending on how your build pipelines are set up, each stage of tests can be run only after the previous stages pass. The illustration below shows how Postman’s continuous deployment pipelines are set up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g80dOGcA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A_o0P_rzcrmd6mxsH2QH3uQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g80dOGcA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A_o0P_rzcrmd6mxsH2QH3uQ.png" alt=""&gt;&lt;/a&gt;An overview of Postman’s deployment pipeline. Source: &lt;a href="https://medium.com/better-practices/continuous-deployment-with-postman-collections-e2fb0b5d2235"&gt;Continuous Deployment with Postman Collections&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scheduled runs:&lt;/strong&gt; You would then want to run some tests at regular intervals against your staging and production deployments to ensure everything works as expected. This is where you would run API health checks, DNS checks, security checks, and any infrastructure related checks. For example, you may test that an upstream dependency API responds with the proper data structure, or, your &lt;a href="https://medium.com/better-practices/auditing-identity-access-management-iam-systems-at-postman-using-postman-8e7549237813"&gt;cloud security permissions are in place&lt;/a&gt;. You can even test for something as simple as the response time of your API endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Combining the power of the two:&lt;/strong&gt; When you do both scheduled and on-demand tests on your APIs, you end up getting complete test coverage of your APIs. On-demand tests prevent broken APIs from shipping out. Scheduled runs ensure they still remain performant and retain quality after being integrated with the larger system or in production.&lt;/p&gt;

&lt;h4&gt;
  
  
  Analytics and alerting
&lt;/h4&gt;

&lt;p&gt;Now that you have some data generated from the tests, you would want to make use of it. The 3rd stage towards a resilient API testing pipeline is connecting it with alerting and analytics systems.&lt;/p&gt;

&lt;p&gt;Alerting systems will let your stakeholders know the moment a system fails — in this case, these should be failed tests. You can use services like Pagerduty or BigPanda here. If you use Slack at work, you can also push notifications to Slack.&lt;/p&gt;

&lt;p&gt;Analytics systems give you a view of system health, performance, stability, resiliency, quality and agility over time. If you follow a maturity model for your services, these data will feed there as well. These data can enrich the product design and product management roadmap by giving important metrics on what works and what doesn’t. Piping this data back to product management closes that feedback loop that I mentioned earlier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Continous Testing with Postman
&lt;/h3&gt;

&lt;p&gt;The philosophy of continuous testing is tool agnostic. But, if you were to implement continuous testing in your organization with Postman, this is how you would go about it. Let’s map the three key stages of an API testing pipeline that I mentioned above to the features Postman gives you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Writing good tests — &lt;em&gt;Collections&lt;/em&gt;:&lt;/strong&gt; This is where &lt;a href="https://learning.getpostman.com/docs/postman/collections/intro_to_collections/"&gt;Postman Collections&lt;/a&gt; come in. A collection is a group of API requests that can be executed at a go. You can &lt;a href="https://learning.getpostman.com/docs/postman/scripts/test_scripts"&gt;write tests for each request&lt;/a&gt; and for group of requests. Postman tells you how many of these tests pass or fail when you &lt;a href="https://learning.getpostman.com/docs/postman/collection_runs/intro_to_collection_runs"&gt;run the collection&lt;/a&gt;. You would have collections for each of your test suites. For example, you would have a collection that runs contract tests of a given consumer’s expectations against a producer, and you would have a separate collection that runs health checks for that service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Running tests — &lt;em&gt;newman and Monitors&lt;/em&gt;:&lt;/strong&gt; You would integrate &lt;a href="https://learning.getpostman.com/docs/postman/collection_runs/command_line_integration_with_newman"&gt;newman&lt;/a&gt;, Postman’s command-line collection runner, in your CI systems and run your collections on-demand as part of your CI pipeline. These run on your setup. On the other hand, &lt;a href="https://learning.getpostman.com/docs/postman/monitors/intro_monitors"&gt;Monitors in Postman&lt;/a&gt; let you schedule collection runs on pre-defined intervals. Monitors can run across multiple regions worldwide. These run on the Postman’s hosted cloud infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics and alerting — &lt;em&gt;Integrations &amp;amp; custom requests&lt;/em&gt;:&lt;/strong&gt; Postman has &lt;a href="https://learning.getpostman.com/docs/postman_pro/integrations/intro_integrations"&gt;pre-defined integrations&lt;/a&gt; with external services. Your monitor runs can integrate with analytics systems and keep a tab of the runs over a period of time. There are also integrations with notification systems which can alert you whenever monitor runs fail. Beyond these, you can always include requests in your collection that push data to 3rd party services. This is useful when you are running your collections on your own infrastructure using newman.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This workflow will enable you to get the rigor that I alluded to earlier. You will have a strong pipeline and a resilient process that will ensure all the systems in your services function well with each other.&lt;/p&gt;

&lt;p&gt;Finally, here is a rather large and poster-worthy illustration showing how these items fit in place conceptually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rH_QJqh3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AgecAV1T_zE7VpYoUEPhE9g%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rH_QJqh3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AgecAV1T_zE7VpYoUEPhE9g%402x.png" alt=""&gt;&lt;/a&gt;Flows that can be used to perform continuous tests of APIs with Postman Monitoring and the Newman CLI tool. Image credits: &lt;a href="https://twitter.com/PetuniaGray"&gt;Joyce Lin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Cover Image credits: Photo by &lt;a href="https://unsplash.com/@brookelark?utm_source=medium&amp;amp;utm_medium=referral"&gt;Brooke Lark&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>api</category>
      <category>testing</category>
      <category>postman</category>
    </item>
  </channel>
</rss>
