Tutorial 3: Create a service and simulation by capturing real API traffic

In this walkthrough you will capture then virtualize a currency exchange API which exposes one endpoint that returns currency exchange rate information.

  • In the first few parts you will create a simulation file by recording a set of real requests and their resultant responses that you will make to the real API.

  • You will then take the recorded request/response pairs and manipulate them to create an API simulation that behaves like the real thing but returns synthetic data.

Part 1. Explore the API we will capture and then simulate

Follow these steps:

  1. Using your API client or browser, make a call to the following (fictitious) API to get the exchange rates between USD and other major currencies:

    https://8fkvh431u4.execute-api.eu-west-2.amazonaws.com/api/currencies?currency=USD

  2. The data returned shows the (fictitious) conversion rates between the provided querystring parameter (USD) and other currencies, as well as the time that the call was made:

{
    "exchangerates": [
        {
            "name": "GBP",
            "rate": 1.2731
        },
        {
            "name": "EUR",
            "rate": 1.0928
        },
        {
            "name": "USD",
            "rate": 1
        },
        {
            "name": "JPY",
            "rate": 0.007
        },
        {
            "name": "CHF",
            "rate": 1.1131
        },
        {
            "name": "CAD",
            "rate": 0.7558
        },
        {
            "name": "AUD",
            "rate": 0.6768
        },
        {
            "name": "NZD",
            "rate": 0.6168
        },
        {
            "name": "RUB",
            "rate": 0.0118
        },
        {
            "name": "ZAR",
            "rate": 0.0545
        },
        {
            "name": "MXN",
            "rate": 0.0582
        },
        {
            "name": "AED",
            "rate": 0.2723
        }
    ],
    "timeofquote": "2023-07-05T08:38:07"
}
  1. Note that this data is not current, but for the purposes of this walkthrough, we will pretend this is a real currency API with real data.

  2. The API works with the following values for currency: GBP,EUR,USD,JPY,CHF,CAD,AUD,NZD,RUB,ZAR,MXN,AED, if you try and pass in anything else you will get a response something like {"exchangerates":null,"timeofquote":"2023-07-05T10:39:07"}

Part 2. Start up a Hoverfly instance as a proxy to the real API

Follow these steps:

  1. To create a Simulation by recording the behaviour of the API, navigate to the Dashboard and click +Add under Services to add a new service.

  2. Leave Simulation blank as we don't yet have one. We are going to create a new simulation by capturing the activity of the real API with our service in capture mode.

  3. Enter "currencies" as the Name of the service. You will notice that this will show you what the new simulated service endpoint will be, something like https://currencies-xxxxxxx.hoverfly.io

  4. Leave the cluster size at 1 pod

  5. Check Enable proxying:

    • For the Target URL enter the scheme and hostname, but leave off the path of the API URL that we want to capture. In this case it is: https://8fkvh431u4.execute-api.eu-west-2.amazonaws.com

    • If the API used a port other than 443 or 80 we would need to add it to the end, e.g. :8080

    • For Mode, select "capture"

    • Leave the rest of the checkboxes unchecked and click Confirm

  6. You are returned to the Dashboard and your new service will be blinking as it starts up a Hoverfly instance which will be listening for requests at the address you can find under the URL column for the Service.

Part 3. Capture a request/response pair from the real API

Follow these steps:

  1. Call the Hoverfly instance in the same way that you called the real API in part 1 of this walkthrough, however now we are calling Hoverfly, and it will capture and then pass the request on to the real API, which will pass the response back through Hoverfly which will again capture the response before passing back to us:

    • Append /api/currencies?currency=USD to the URL copied from the list of Services and execute it from your API client or browser. It will be something like: https://currencies-xxxxxx.hoverfly.io/api/currencies?currency=USD

    • (replace the xxxxxx in the subdomain with your accounts unique string)

  2. The data returned will be exactly as it was from the real API, however it has passed through Hoverfly and created a Simulation.

  3. Change the Mode from "capture" to "simulate" in the dropdown for your currencies service from the dashboard, and execute that same end point again:

    • https://currencies-xxxxxx.hoverfly.io/api/currencies?currency=USD (replace the xxxxxx in the subdomain with your accounts unique string)

    • The exact same results will be returned, however they are now being returned from Hoverfly, and the real API is no longer being hit.

Part 4. Explore the newly created Simulation

Follow these steps:

  1. From the Dashboard, click the link that says (unsaved) under Simulation for your currencies Service in the service list.

  2. You will be taken to the simulation editor for your running currencies service.

  3. On the left you will see each of the endpoints generated from Hoverfly when it was in capture mode.

  4. There will be a GET /api/currencies endpoint

    • If you sent the request from your browser, you may also see a /favicon.ico request. You can delete that.

  5. Highlight the GET /api/currencies endpoint and on the right you will see the various settings that can be configured for this Request/Response pair, they are:

    1. Stateful settings

      • These allow you to create a simulation that keeps state between requests and can respond differently to identical requests depending on the state

    2. Request Matchers

      • Hoverfly will try to match requests sent to it, in order to find the best matched response to return.

      • In this case, while your Hoverfly service was in capture mode earlier, it recorded all of these values:

        • the method was a GET

        • the destination was exactly "8fkvh431u4.execute-api.eu-west-2.amazonaws.com"

        • the path was exactly "/api/currencies"

        • the query string contained one parameter called currency and the simulation has configured this matcher to look for values exactly equal to USD.

        • There was no header or body recorded in the request.

      • All of these values in the Request matcher, can be manipulated to configure Hoverfly to match requests based on combinations of exact values, Glob (*) matches, or regular expressions

    3. Response

      • This is the HTTP response that Hoverfly will return if the configuration of the Request matchers (above) are satisfied. Here you can modify the Response including:

        • the status code

        • header keys and values

        • the response body

      • You can also make it return synthesized data, or data taken from parts of the Request, by using Templating.

Part 5. Change the Request matcher to play back the same response no matter what currency is passed in

Follow these steps:

  1. Currently the simulation only works if USD is passed in as a currency. If you try and pass in anything else you will get a matching error, as it is only configured to respond to USD.

  2. Let's change that so that it always returns a response no matter what value is passed in for currency.

  3. In the Request matchers section, under Query where is one parameter - currency:

    • Change the matcher type from "Exact match" to "Glob match"

    • Change the value from USD to *

    • Click Apply changes at the top of the page.

  4. Now if you re-hit the endpoint but instead use a currency of "monopolymoney", you will still get the same response.

Part 6. Change the Response to provide random synthesized data

Follow these steps:

  1. Navigate to the (unsaved) simulation.

  2. Scroll down to the very bottom and check the "Enable templating" checkbox in the Response section.

  3. Now replace the existing Response Body consisting of static exchange rates with the following which will generate random exchange rates and return the current date and time:

{
    "exchangerates": [
      {
        "name": "GBP",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "EUR",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "USD",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "JPY",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "CHF",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "CAD",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "AUD",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "NZD",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "RUB",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "ZAR",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "MXN",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      },
      {
        "name": "AED",
        "rate": {{ randomFloatRange 0.1 1.3 }}
      }
    ],
    "timeofquote": "{{ now '' '' }}"
  }
  
  1. Apply the changes, you will get a warning that your changes will create inconsistencies between the Content-Length header and the response body. For now remove the Content-Length header.

  2. Now try hitting the endpoint a few times over in the browser or from your API client, and you will see random data being returned from the simulation.

Part 7. Save the captured and edited simulation as a shareable Simulation

Follow these steps:

  1. So far we have captured a request/response to and from the API using Hoverfly Cloud in capture mode, and after editing it a bit we played it back in Simulation mode.

  2. This simulation is however local to the service in which it is running. You will have noticed that under the Simulation column on the dashboard, there is the word (Unsaved). In order to create a shareable copy of the simulation, we need to save it as a new Simulation whereafter it will appear in the Simulations area and can be copied and reused by other services as required.

  3. Navigate to the simulation editor for this service by clicking on (Unsaved).

  4. Now open the menu under the Apply changes button and select "Export simulation as new" and give it a name like "currencies-sim"

  5. After saving it you will be able to find the simulation in the Simulations section of the website.

  6. It is important to note that if you create a new service and have it use this newly created simulation, the service will make itself a copy of the master simulation. Changes made to the copy need to be explicitly synched back to the master if that is required. This is in order to allow different teams, developers or testers, to make their own personalised changes to simulations as required.

Part 8. Remove the service and simulation

Follow these steps:

  1. Unless you want to keep the service and simulation, they can be deleted.

  2. To delete the service and it's copy of the simulation navigate to the Dashboard, open the ellipse to the right of the product service that you created, and select Delete.

  3. To delete the master simulation, navigate to the Simulations page, locate the simulation you created, and click the corresponding x at the right of page.

Congratulations! You have completed this Tutorial, "Create a service and simulation by capturing real API traffic."

Last updated