Vladimir Dyuzhev, author of MockMotor

Vladimir Dyuzhev
MockMotor Creator

How to Record REST Traffic with MockMotor

When recording a REST call, MockMotor automatically finds parameters in the request URL. Tweet This

REST traffic is not very different from HTTP traffic. This is not a surprise since REST is HTTP.

However, in a REST service call, the URL can contain segments that are actual parameters. What in HTTP would pass as http://service?account=100500, in “pure” REST can be http://service/account/100500.

This is not a dogma, and a REST service can use the query string, just as an HTTP service can have parameters in the URL.

MockMotor doesn’t make a difference between REST and HTTP traffic when recording. However, it tries to find parameters in URL components and assign them reasonable names.

Let’s see how MockMotor records REST.

Goal: Recording a REST Service

Our goal for this post is to record a live REST service.

The REST service, unlike an HTTP one, should take some parameters as URL components.

Our recording will:

  • Intercept calls with parameters, including those in URL components
  • Forward these calls to the live backend
  • Record the responses as mocks
  • Configure those mocks to match the original requests
  • The recorded mocks should be put into action right away, without any human intervention or fiddling with them.

    The Backend: US National Library of Medicine’s RxNorm

    RxNorm is a service for medical applications. It allows for obtaining tonnes of special information about medications presented on the US market. See for yourself.

    For us, however, it has two useful properties:

  • It’s free to call
  • The request URLs contain parameters
  • A typical request looks like this:

    https://rxnav.nlm.nih.gov/REST/rxcui/18600/allProperties.json?prop=all
    

    Here 18600 is a RxCUI code for azatadine.

    The response is a rather large JSON payload that contains all properties for this substance:

    {"propConceptGroup": {"propConcept": [
        {
            "propCategory": "ATTRIBUTES",
            "propName": "TTY",
            "propValue": "IN"
        },
        {
            "propCategory": "ATTRIBUTES",
            "propName": "PRESCRIBABLE",
            "propValue": "Y"
        },
        {
            "propCategory": "CODES",
            "propName": "RxCUI",
            "propValue": "18600"
        },
        {
            "propCategory": "CODES",
            "propName": "NUI",
            "propValue": "N0000007088"
        },
    ...
    

    Needless to say, the responses for /rxcui/18600/ and say /rxcui/7052/ (morphine) are very different. When recording mocks for this backend, we should create two different mocks - one matching 18600 and another matching 7052 (and then maybe dozens more matching other substances used in test runs).

    Let’s proceed.

    Create a Service

    First let’s create a test service that is going to mock RxNorm.

    Nothing special is required. We assign it a relative URL of /RxNorm, and the full mock service URL is seen at the top of the page:

    Create a Forward Response

    Now its time to add a forwarding/recording response to the service.

  • It should match GET HTTP operation (all RxNorm calls use GET)
  • It should match any operation.
  • It should have RxNorm service URL base set in the Forward field - https://rxnav.nlm.nih.gov/REST/
  • It should have Recording enabled.
  • It should activate the recorded mock immediately.
  • Below is the forward response. Not important properties are hidden.

    Note that the Scripting setting is not in effect for recording.

    MockMotor detects the payload type (XML or JSON) and decides on used scripting automatically. Here we left it set to XQuery while the response is JSON. MockMotor creates the mocks with JavaScript to match the response payload type.

    The same forwarding response looks like this in the responses list:

    Call the Mock Service

    Let’s run a few test cases that get information for RxCUIs via our mock service.

    A call for Azatadine:

    http://127.0.0.1:7080/ExamplesForBlog/RxNorm/rxcui/18600/allProperties.json?prop=all
    

    Since we do not have any local mocks yet, the request is handled by the forwarding mock response. It sends the request to the actual RxNorm backend. When the backend responds, MockMotor records the response properties as a new mock.

    MockMotor sees that the request payload is not XML (in fact, the payload is missing because it is an HTTP GET) and decides it must be an HTTP/REST call.

    For the HTTP part, it finds the prop=all HTTP query parameter and adds it to the match script as http.parameter.prop=="all".

    For the REST part, MockMotor analyzes the URL trying to find any sequence that looks like a name/value pair. It is not always easy, but for our URL the /rxcui/18600 sequence is very likely a key and a value. MockMotor hence defines the relative URL as rxcui/{rxcui}/allProperties.json so the REST parameter rxcui gets its value from the URL component.

    Lastly, MockMotor adds a condition rest.parameter.rxcui=="18600" to the matching script so that only requests for 18600 match this new response.

    Let’s execute two more requests:

    Morphine:

    http://127.0.0.1:7080/ExamplesForBlog/RxNorm/rxcui/7052/allProperties.json?prop=all
    

    Zithromax 500 MG Injection:

    http://127.0.0.1:7080/ExamplesForBlog/RxNorm/rxcui/1668240/allProperties.json?prop=all
    

    Review the Recorded Responses

    Let’s take a look at the service’s responses again:

    You can see that the forward mock has created three mock responses.

    Each of the recorded mocks has its own version of the match script, containing its own specific values of RxCUI value, e.g.:

    http.parameters.prop=="all" && rest.parameters.rxcui=="18600"

    In addition to the response payload and the match script, MockMotor recorded:

  • HTTP operation GET
  • Relative URL rxcui/{rxcui}/allProperties.json
  • HTTP status 200
  • Content-Type application/json
  • The response payload for this RxCUI
  • Response time 134ms
  • Test The Recorded Mocks

    The newly recorded mocks are now handling the matching requests. Let’s test it by repeating the same requests again.

    Now, looking at the response headers, calls counters or the execution log, we can see that the RxNorm backend wasn’t called.

    Once we collect all the responses we need for our test scenarios, we do not need to call the actual backend at all. When the backend has to be leased to a team, this can mean large savings.

    You can see the complete service on the demo MockMotor instance.

    Please Share

    Was this post useful? Then please share! Tweet This