Teach Your API Test Platform to Send Callbacks

I already wrote about using Prism as an API test platform but I didn't include an example with callbacks so this post is to fill that gap! If you didn't read the previous post, the tl;dr is that Prism is a nodejs open source tool that can take your OpenAPI specification and then do an impression of your live API, validating the API calls sent to it and responding with the example data described in the spec. It can also follow up the API response and send an HTTP request of its own to mock the callbacks described in your OpenAPI spec.

Describing Callbacks in OpenAPI

I'm working with the Nexmo APIs quite a bit so here's an easy example from one of their specs. It's from the "Number Insight" API - you provide a phone number and the API returns you information about that number. There's a few different levels of information (and different levels of cost for each), but the "Advanced" level is pretty unreliable if you call it synchronously - so instead Nexmo will respond to your API call, then send a followup request to the URL you specify with a payload of all the data in it.

Here's how the OpenAPI spec looks:

      - $ref: "#/components/parameters/format"
      operationId: getNumberInsightAsync
      summary: Advanced Number Insight (async)
        - $ref: "#/components/parameters/callback"
        - $ref: "#/components/parameters/number"
          description: OK
                $ref: "#/components/schemas/niResponseAsync"
              operationId: asyncCallback
              summary: Asynchronous response
              description: Contains the response to your Number Insight Advanced API request.
                      $ref: "#/components/schemas/niResponseJsonAdvanced"
                  description: OK

(if you want to see the whole thing, it's on GitHub )

The callbacks section details the incoming requests to expect as a followup to the client's API call, and what response to send. In the initial request, the callback parameter specifies where the callback will be directed to - and Prism can do that too.

Mocking The API and Callbacks

I can start up the "pretend" API with Prism like this:

prism mock number-insight.yml

Prism will output the endpoints that it got from the spec and then report its location - for me that is usually http://localhost:4010.

In order to receive the callback, I'll need to pass a URL that Prism can reach. This is one scenario where you won't need a public URL to test a webhook - because the webhook is coming from another local tool. In this case, I've got a simple webserver running on port 8080 that will simply output the data it receives so I can inspect it.

Ready? Here's my curl command to request the async endpoint from the local mock API, and gives the callback to send the data payload to:

curl "http://localhost:4010/advanced/async/json?api_key=123&api_secret=456&number=44777000777&callback=http://localhost:8080"

I get a response to my API call, containing a request_id and some other information, then (but seemingly instantly) Prism follows up by sending more example data to the callback URL I specified before.

Testing API Callbacks Locally

This setup is brilliant for a situation like this where I want to develop something to handle this callback - but I don't want to keep on hitting the live API (not to mention that I will run out of credit if I keep hitting this one!). I can work locally, regardless of whether my connectivity is great or even whether the API is up (or even exists yet).

In the future, Prism is expected (by me at least) to also have support for the new Webhooks feature that is slated for OpenAPI 3.1 - enabling us to use a local mock server to send incoming requests as well as handling our outgoing ones. I, for one, can't wait!

Instant Test API Platforms with Prism

I've been writing a bit about OpenAPI lately and I realised that I didn't share how I'm creating local, test versions of production APIs to work with while I develop new client code or test SDK features. The recipe is simple: you will need an API spec, the excellent open source tool Prism and an HTTP client. Mix it up and be ready to change your API development workflows forever. Continue reading

Relative Links with IBM Cloud API Gateway

I work quite a bit with serverless tech, particularly on IBM Cloud since I work there. At the moment I'm building a microservice using web actions. When a user creates data with a POST request, I want to redirect them to the URL of the new thing they created - but for that I need to know the URL that it was accessed with. This is a relatively new feature on API Gateway so here's a quick howto for grabbing that URL in both JavaScript and PHP. Continue reading

Slack Enterprise Grid and BotKit

I have the pleasure of using Slack Enterprise Grid on a daily basis as IBM has adopted it internally, I work there, and there are far too many of us to use a single slack instance. The main downside of Slack Enterprise Grid (apart from having about 15 slack organisations running in your client all the time) is that it returns different data when integrating with the Slack Web API and RTM (Real Time Messaging) systems. We had some bot integration that stopped working as a result, and I ended up moving to BotKit and then using a mixture of the RTM and Web API from Slack to get things to work. I won't remember how I did it so I thought I'd better write it down. Continue reading

Multiple Search Keys in CouchDB

I work quite a bit with CouchDB (Cloudant, a hosted CouchDB solution, is part of Bluemix, IBM's cloud platform - and I work for IBM so I get to use this as much as I like) and today I found a feature I hadn't seen before. I struggled to find the docs, so I thought I'd post my working example here in case anyone else is solving a similar problem: wanting to use more than one set of key ranges when filtering a CouchDB view. Continue reading

One OpenWhisk Action Calls Another

Working with openwhisk, it's easy to create many isolated actions and build them up into sequences; the output of one action is passed to the next action in the sequence. In my case, I wanted one action to spawn potentially many other actions. I had to look up how to do it and here it is so I can look it up more quickly next time! Continue reading

Alexa Project Name Generator on OpenWhisk

I'm having lots of fun with my Amazon echo and echo dots, creating skills for them. Initially I used Amazon's lambda platform since that's a very easy way to get started - but I'm an advocate for IBM and was looking for an excuse to play with OpenWhisk (an open source serverless offering that Bluemix has a hosted version of) anyway so this was a great opportunity!

Configuring Skills

There are a bunch of good resources around for setting up skills, picking the name, configuring the "invocation" which is what to say to make the code happen, and so on. I'll skip this section and instead just share a couple of tutorials that I rely on a lot:

Once your skill is configured, it's time to write the code (note: UK users need to pick English (UK) and not English (US) as otherwise your skill will mysteriously fail in your home region. Guess how I learned that??) Continue reading

cfenv for Easier NodeJS on Cloud Foundry

Now I'm working at IBM I am making extensive use of their Bluemix Platform, which is based on Cloud Foundry. The way that Cloud Foundry is set up is actually very neat, with everything you need contained in JSON structures within environment variables. Parsing out those values can be a pain however, so I thought I'd share the library that's helping me the most with this: cfenv. Continue reading

Using NPM Link to Develop Dependent Projects

Right now I'm working on a javascript project that relies on another module for some of its functionality. I'm making fairly major changes that affect both projects, and since the dependency is pulled in via npm, initially I was committing and pushing to a repo so that npm could pull in the dependency from GitHub - on every update. Well that gets tedious really quickly so I'm now using the npm link command which is pretty handy. I hadn't seen it before so this blog post is basically the cheat sheet I wrote when I started using it... Continue reading