As a trainer I develop my own training material. I’m always looking for ways to make it simpler, simpler in the sense that it takes me as little time as possible to make something work.
For instance, and that’s a good example, I’ve used WireMock for a number of years now running locally on our training machines to mock specific services. Some of these services will only respond with the delay of a certain number of seconds triggering an endpoint fault on a micro integrator.
Other services are mocked because they simply need to respond with the name of the service and the number, in case of a load balanced round Robin endpoint definition.
Although setting up WireMock is not that big of a deal I recently moved the installation of WireMock away from my local instances. At the API conference in London in October of this year I heard that there was a hosted version called MockLab where I could use the free tier to see if it adds value to our trainings.
The free tier gives 1000 invocations free per month if I go over that I of course need to get a subscription but in general 1000 invocations would suffice for me.
In this blog I’m going to show you how I use MockLab to mock a very simple API and how I’m going to use the Micro Integrator to hide the back-end URL as well as the required API key for this demo.
I am shielding everything from the user by letting the API flow through the Micro Integrator for a little bit of lightweight mediation, in this case adding a APIKEY in the Header and forwarding it to the endpoint. But let’s get started with MockLab!
Installation
Of course: there is none. This is a hosted service, so I simply go to the MockLab url and register myself or federate the login to Google or GitHub.
I am using GitHub and I will start by Creating a new mock API.
Creation is really simple, Click on Mock API and fill in the details.
The hostname is optional and can be used when invoking the API. Underneath there is also a random generated code as part of a URL like r1274.mocklab.io.
Afterwards we create the API called Blog and we define a context / resource before saving it by clicking the “Save” button.
We can also define security as needed to access the API. It can be User ID / Password (AKA Http Basic) or Header Match.
We can select a Header (naming it) and the Predicate, for instance Equal to 1234.
But for now keep it empty and create a stub. The stub is doing a GET on /retrieve/data (just a random context/resource), returns a 200 Status Code and a JSON body but only after a delay of 15000 milliseconds. We also add a Header to ensure that the Json response is indeed a message with Content-Type application/json. If you omit that, you will get back an octet-stream format message.
We set the timeout to 15 seconds (15000 ms).
We can test it from the Browser as it is a GET.
You will get back the dummy response in your browser window. Let’s add a Header match as security so the API is not open to everyone.
This we can also test, now from SoapUI since we can more easily see the error message.
When we add the key as a header, we can see that we get the 200 and the Response.
And get the response back rather than a 401 Status Code.
Hiding it
One of the things that you can do is that you put an intermediary stop in the API by this I mean that you’re not going to call the endpoint directly but rather go to another API that on each invocationwill call the mocked back end. The benefit of such a setup is that the end point that we’re calling in this case the one on mock lab is not known to the person who is calling the API. Furthermore, they do not see the API key being added as a header in the flow. This is the solution that you can use when you have the requirement to add something like a header to the API flow but do not want to do it in the API definition or in case that you want to obscure the actual address endpoint that is being called.
So, in this case what we need to do is, we need to create an API and in a very simple flow add the header to the API call. Which we will then forward to call to the original endpoint on MockLab.
I’m not going to describe the entire setup of the micro integrator and integration studio as it would take too much space in this blog. however, you can look at one of these blogs if you have questions on how to install it. One of the things that I’m going to describe it’s the setup and, in this case, I’m going to use integration studio 8.1 that has an embedded micro integrated 4.1. That makes it very easy since I do not have to install any additional software other than integration studio.
Normally I would install this on a Linux environment but for this blog I will use windows. For the simple reason that the WSO2 products as well as integration studio run on the major platforms: Windows, Linux and Macintosh.
Starting Integration Studio
Starting integration studio, it’s as simple as clicking on the icon in the directory where you installed it.
I’ve created a new workspace (which, as you can see, is just pointing at a directory) and will create a new Integration Project in that directory.
We are currently in the Getting Started view of integration studio.
Clicking on an New Integration Project will open the wizard that creates the project structure for us with a composite exporter as well as a configure project to store are artifacts. I’m going to call it MockLabProject.
The wizard will suffix the project name with configs and composite exporter in order to create the subdirectories. We will keep all of the settings as they are and click on finish.
Integration studio now switches to the ESB view where we can open up the newly created project and take a look at the configs subdirectory.
Here we can create a new API. Select the api subdirectory, right click on that, and select New / REST API.
Keep it simple, enter MockAPI and /mock as the Name and Context. Press Finish.
To make it simple we are going to copy the source code over and replace the default API definition.
Click on Source and copy this code.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/mock" name="MockAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET">
<inSequence>
<header name="APIKEY" scope="transport" value="1234"/>
<call>
<endpoint>
<http method="get" uri-template="https://yenloblog.mocklab.io/retrieve/data">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<property name="ContentType" scope="axis2" type="STRING" value="application/json"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Save with CTRL-S. Switch to design mode and you will see this setup.
Open the Pom of the Composite Exporter and Select the API. Save with CTRL-S.
Select Window-Show View – Other…
Type or Select Servers and Click Open.
On the Server tab, right Click on Micro Integrator Server (the top rectangular box(obscured)) and Select Add and Remove,
Select, Add and Finish.
Start the server, again Right Click on Micro Integrator Server and select Start as shown in the image before this one.
The console shows the deployed API.
Now open the Rest Project in SoapUI again. Create a new REST Project on the exposed API (http://localhost:8290/mock).
Missing header
It must be said that in the first setup, I forgot to set the header as I assumed the json body with also include a correct header. However, you need to set it manually, otherwise the message comes in as application/octet-stream rather than application/json (as we defined a json response in MockLab).
As a workaround we set the content-type to application/json. Setting the messageType to application/json would create a response like this: {“binary”: “eyJQYXRpZW50cyI6IjEwMSJ9”}, which is a base64 encoded version of the above message.
This can be decoded of course. In that case we take the incoming body of the message
<?xml version="1.0" encoding="UTF-8"?>
<api context="/mock" name="MockAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET">
<inSequence>
<header name="APIKEY" scope="transport" value="1234"/>
<call>
<endpoint>
<http method="get" uri-template="https://yenloblog.mocklab.io/retrieve/data">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<property expression="$body/*" name="messageBody" scope="default" type="STRING"/>
<payloadFactory media-type="json">
<format>$1</format>
<args>
<arg evaluator="xml" expression="base64Decode(get-property('messageBody'))"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
We need to copy the body to a variable since the payloadFactory initializes the body as it will create a new one. In that case you will see the decoded json payload in the response.
Abstract
Sometimes you just need a service to mock something. It could be that you want to try out something but you cannot develop a service just yet or the service is not available.
In that case, look at Mocklab as a quick way of creating an API that you can use. In this blog I showed you how easy Mocklab is by defining an API and using WSO2 Micro Integrator in conjunction with WSO2 Integration Studio to test the setup by send a simple message to the API. Even adding the requirement to add a Header with a key that Mocklab will check and only respond if the header is there, and it is correct.