Hi everyone, this would be my first post on medium and I’m so excited to help you with simplifying service virtualization with Hoverfly. If you are new to service virtualizations, you can check here to help you understand the concepts of service virtualization is and why it is important in software development.
With all the great benefits Microservice architecture provides agile teams irrespective of the size, is the need to develop or prototype fast and produce shippable products at the end of each sprint. But many things may go wrong.
During the development phase, you’d agree with me that there are many instances where development can be stalled because of one or more of these issues:
- Your company network is totally down, so you cannot get resources from external services either due to network or firewall restrictions.
- External servers with resources are inaccessible and you cannot get responses for your use.
- Rate limiting is applied on your external APIs you are working with. (Your team may be on a tight budget or you want to maximize your budget). I have worked with an API that allows only two calls per day. Weird right?
- There’s no endpoint to start with. The architectural design may have been done already. You just want to prototype your APIs and do a proof of concept.
These issues can be so frustrating, you’d agree with me yeah? These and many more use cases are reasons why you may consider using Hoverfly in your next project.
Among the numerous benefit service virtualization tool hoverfly provides, here are some of the nice features you get for using Hoverfly
- Its capability and robustness in mocking the behaviors of backend systems.
- Simulate how your system responds to high latency and other performance issues.
- Its use as a proxy between your application and a backend application to capture both the request and responses for caching. You can then simulate your backend system by matching your requests to saved responses.
- Its ability to intercept and modify requests and responses.
This tutorial aim to get you started with Hoverfly. This tutorial will be language agnostic for now, as it will introduce us to the concept of mocking on Hoverfly.
I will be guiding you through setting up hoverfly on our host machines and capturing our requests and responses for subsequent offline use.
Quick introduction of Hoverfly
Hoverfly is a lightweight, open source API simulation tool created by @spectolabs . Using Hoverfly, you can create realistic simulations of the APIs your application depends on. You can check out more about Hoverfly here.
Hoverfly can either function as a proxy server, orchestrating our requests or a web server, responding as the main backend system
Being a proxy server, it acts as an intermediary between you and the real service, recording and caching your request and response for later use. With that ability, it means that it can also modify requests and responses. The requests and responses can be exported as simulation files.
When set as a web server, it assumes the role of the backend service, serving us the responses it cached during capture of requests and responses, without a need to communicate with the original service to handle your request.
Let me quickly introduce the modes Hoverfly can run in before we dive into mocking our User Service.
- Capture: In this mode, Hoverfly acts as a proxy server, saving the requests and responses that goes through it. The requests and responses can be exported as JSON formatted simulation files.
- Simulate: The simulation files exported in the capture mode are then replayed with hoverfly acting as a web server, responding to our requests.
- Spy: Hoverfly searches for the request in the cached response (usually in the Simulation file). If it doesn’t find it, it forwards the request to the real service, then returns back the response to the client.
- Synthesize: Hoverfly does not check for the request in the simulation data, it instead runs the provided executable file usually called the middleware to generate the response. You can use this mode if the API is difficult to simulate, where state is required to successfully mock the API.
- Modify: Requests are sent to middleware before forwarding it to the destination. Responses will also be passed to executable file before being returned to the client.
- Diff: Hoverfly forwards a request to external service, then compare the new response with the cached response. If different, the cache is updated with the difference. Then the response is returned to the client.
What we will be doing
Having understood the various modes available, We will build our Books microservice by the end of these series, where we can add a new book to our catalogue of books, edit a book’s information, search a book by author’s name or ISBN number and other Book related activities. But before any operation can be carried out on our service, we will need to authorize our users.
Authorization or Creation of new users is clearly not our responsibility. For this purpose, we will mock a User microservice, delegated with the creation of new users, and overall User management. ( https://reqres.in/ will be our Micro-service for the sake of this demo). We will call the Create a user, Update a user, Get a User, Get all Users and delete a user endpoints.
Because we are not sure if our User Microservice will always be available and don’t want to get stuck in developing our own Books microservice while waiting for the User service to come back online(just kidding. https://reqres.in/ promises 99.99% uptime), we will mock the endpoints using Hoverfly.
In order to follow through with this tutorial, there are basic assumptions I will be making about you.
- You understand the basics of REST APIs.
- You have tested an endpoint, at least with one API Client (We’d be using Postman for this purpose. You can download Postman here if you do not have it installed on your local dev machine).
- Understand the difference between proxy and web servers.
Check out this page to set your environment to start recording and simulating on hoverfly.
- Start Hoverfly with path to your hoverctl executable added as an environment variable. Run the below command to see if it is properly configured. The image below should be similar to what gets printed to your terminal.
hoverctl - version
- Find the Postman collection here. Save the page as a JSON file, then import into your Postman as a collection.
With your Postman collection imported and Hoverfly set up on your local machine, start up the hoverfly instance with
Since we will be capturing the request first, we set Hoverfly mode to capture
hoverctl mode capture
- Set Postman to use hoverfly as a proxy
- Choose the Hoverfly Tutorial Collection to run
- Click on the Runner Button
- The imported collection will be seen, Click the Start Run button.
This step will run all the requests in the collection, proxying through Hoverfly.
- When it completes, export the captured requests and responses into a simulation.json file using the command
hoverctl export simulation.json
You can find your exported simulation file in the C:\Users\<username> directory for windows users.
A quick peek into the simulation file shows the JSON structure containing the captured data and metadata of the simulation. The data consist of pairs of Objects, each object representing a single request and its response.
Each request has a
- body and
- query, which are all typical for a standard HTTP request.
When you run Hoverfly as a webserver, it matches the incoming request based on different matching strategies defined in this file. You can read here about request matchers available in Hoverfly.
The file also contains the response body, which is usually a JSON string and encodedBody set to false, or Base64 encoded string, and the encodedBody field set to true when the response contains characters that cannot be preserved in the JSON file or if the response header has a Content-Encoding set to gzip. It also contains the HTTP status returned and response headers. This file can be modified.
N.B: By default, Postman adds Accept-Encoding to the request automatically, with value set as “gzip deflate”. When this is set, Hoverfly automatically encode the request the body of the request if the server responds with Content Encoding as “gzip”. In order for us to do this particular example, we do not want our response to be encoded, so we overwrite the Accept Encoding value passed by Postman to “identity”.
See a sample of the captured request and response.
Creating our Users.
Since we will be creating new users, we will modify the Simulation file to return whatever we pass as our response. Hoverfly uses templating to build dynamic responses. Checkout here to see the list of templating functions we have at our disposal.
Modifying the Create and Update User endpoints.
We will change the matching type of our body from json to jsonpath because we would be creating dynamic names and job. We cannot use the json matcher because it will transform both the matcher value and string to match into JSON objects and then evaluates their equality. Because we’d be creating for different users, the equality of what we have captured request to subsequent requests will fail.
We will be using Jsonpath to match the request. This will validate true only if the subsequent requests contains properties already captured, without checking the value. You can evaluate your jsonpath match here
We will be changing from the request matcher for the Create User Endpoint
And the response body from
You can also do the same for the Update Endpoint.
Save the new changes then set hoverfly to run in a web-server mode with
hoverctl mode simulate
Import the newly edited file
hoverctl import simulation.json
Subsequent calls to those captured endpoints will not go to the real servers. Rather, they will be served from our cached responses. Hoverfly will however throw 502 errors when it fails to match request with this file.
If we intend to let hoverfly check the remote server when it cannot properly match our requests, we can set it to run in the SPY mode by running
hoverctl mode spy
Your application’s requirements may be more complex than returning cached responses.
One thing we may have noticed is that we cannot persist data and hoverfly is not aware of your application’s state just yet. We will do these things in a follow up post.
- Using the Regex matcher for the Method type to match the same request and response for the create and update user endpoints. We will modify the simulation file to respond with the same cached response, since they are identical for either a POST or PUT request.
- We will look into how to implement Middlewares next time, where we would do fantastic things like looking up data before modifying the request. and also modify responses before we return to the client making the request.
- Modelling our Books endpoints.
- Simulating network latency.
- Building our solution as a Docker image.
I’m looking forward to your comments, feedbacks and questions if any. Thank you for your time reading through. You can also follow me at @tobloj for other engagements.