.. _pairs: Request Responses Pairs ======================= Hoverfly simulates APIs by matching **incoming requests** from the client to **stored requests**. Stored requests have an associated **stored response** which is returned to the client if the match is successful. The matching logic that Hoverfly uses to compare incoming requests with stored requests can be configured using **Request Matchers**. .. _matchers: Request Matchers ---------------- When Hoverfly captures a request, it creates a Request Matcher for each field in the request. A Request Matcher consists of the request field name, the type of match which will be used to compare the field in the incoming request to the field in the stored request, and the request field value. By default, Hoverfly will set the type of match to :code:`exact` for each field. .. seealso:: There are many types of Request Matcher. Please refer to :ref:`request_matchers` for a list of the types available, and examples of how to use them. There alse are two different matching strategies: **strongest match** (default) and **first match** (legacy). Please refer to :ref:`matching` for more information. An example Request Matcher Set might look like this: +-------------+-------------+------------------------------------+ | Field | Matcher Type| Value | +=============+=============+====================================+ | scheme | exact | "https" | +-------------+-------------+------------------------------------+ | method | exact | "GET" | +-------------+-------------+------------------------------------+ | destination | exact | "docs.hoverfly.io" | +-------------+-------------+------------------------------------+ | path | exact | "/pages/keyconcepts/templates.html"| +-------------+-------------+------------------------------------+ | query | exact | "query=true" | +-------------+-------------+------------------------------------+ | body | exact | "" | +-------------+-------------+------------------------------------+ | headers | exact | | +-------------+-------------+------------------------------------+ In the Hoverfly simulation JSON file, this Request Matcher Set would be represented like this: .. literalinclude:: ../../simulations/basic-simulation.json :lines: 5-44 :linenos: :language: javascript :ref:`View entire simulation file ` The matching logic that Hoverfly uses to compare an incoming request to a stored request can be changed by editing the Request Matchers in the simulation JSON file. It is not necessary to have a Request Matcher for every request field. By omitting Request Matchers, it is possible to implement **partial matching** - meaning that Hoverfly will return one stored response for multiple incoming requests. For example, this Request Matcher will match any incoming request to the :code:`docs.hoverfly.io` destination: .. literalinclude:: ../../simulations/all-matchers-simulation.json :lines: 6-11 :linenos: :language: javascript :ref:`View entire simulation file ` In the example below, the :code:`globMatch` Request Matcher type is used to match any subdomain of :code:`hoverfly.io`: .. literalinclude:: ../../simulations/all-matchers-simulation.json :lines: 27-32 :linenos: :language: javascript :ref:`View entire simulation file ` It is also possible to use more than one Request Matcher for each field. In the example below, a :code:`regexMatch` **and** a :code:`globMatch` are used on the :code:`destination` field. This will match on any subdomain of :code:`hoverfly.io` which begins with the letter :code:`d`. This means that incoming requests to :code:`docs.hoverfly.io` and :code:`dogs.hoverfly.io` will be matched, but requests to :code:`cats.hoverfly.io` will not be matched. .. literalinclude:: ../../simulations/all-matchers-simulation.json :lines: 48-57 :linenos: :language: javascript :ref:`View entire simulation file ` .. seealso:: There are many types of Request Matcher. Please refer to :ref:`request_matchers` for a list of the types available, and examples of how to use them. For a practical example of how to use a Request Matcher, please refer to :ref:`loosematching` in the tutorials section. There alse are two different matching strategies: **strongest match** (default) and **first match** (legacy). Please refer to :ref:`matching` for more information. Responses --------- Each Request Matcher Set has a response associated with is. If the request match is successful, Hoverfly will return the response to the client. .. literalinclude:: ../../simulations/basic-simulation.json :lines: 45-55 :linenos: :language: javascript :ref:`View entire simulation file ` Editing the fields in response, combined with editing the Request Matcher set, makes it possible to configure complex request/response logic. Binary data in responses ~~~~~~~~~~~~~~~~~~~~~~~~ JSON is a text-based file format so it has no intrinsic support for binary data. Therefore if Hoverfly a response body contains binary data (images, gzipped, etc), the response body will be base64 encoded and the `encodedBody` field set to true. .. literalinclude:: ../../simulations/basic-encoded-simulation.json :lines: 47-48 :linenos: :language: javascript :ref:`View entire simulation file ` Serving response bodies from files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Starting from version **1.3.0** hoverfly can return response body from a specific file: .. code:: json "response": { "status": 200, "encodedBody": false, "templated": false, "bodyFile": "responses/200-success.json" } **response/200-success.json** is resolved against the directory specified in :code:`-response-body-files-path` which is your `current working directory `_ by default. When both :code:`body` and :code:`bodyFile` are specified, :code:`body` takes precedence. :code:`bodyFile` is read into memory only on simulation import, not in runtime. Reading response bodies sometimes might not be comfortable. Imagine a developer team that needs a single updating "files provider". Syncing to this provider can be a challenge and that's why hoverfly supports downloading response bodies from external urls: .. code:: json "response": { "status": 200, "encodedBody": false, "templated": false, "bodyFile": "https://raw.githubusercontent.com/SpectoLabs/hoverfly/master/core/handlers/v2/schema.json" } Like local files, this feature is supported only on simulation import. To escape security issues there's another mandatory option to specify :code:`-response-body-files-allow-origin` that lets you explicitly set the collections of urls to allow body files to be downloaded from. For the above to work you need to run hoverfly like this: .. code:: bash hoverfly -response-body-files-allow-origin="https://raw.githubusercontent.com/"