---
title: "request matching"
author: "Scott Chamberlain"
date: "`r Sys.Date()`"
output:
  html_document:
    toc: true
    toc_float: true
    theme: readable
vignette: >
  %\VignetteIndexEntry{3. request matching}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r echo=FALSE}
knitr::opts_chunk$set(
    comment = "#>",
    collapse = TRUE,
    warning = FALSE,
    message = FALSE
)
```

Request matching
================

To match previously recorded requests, `vcr` has to try to match new 
HTTP requests to a previously recorded one. By default, we match on 
HTTP method (e.g., `GET`) and URI (e.g., `http://foo.com`), following 
Ruby's VCR gem.

You can customize how we match requests with one or more of the 
following options, some of which are on by default, some of
which can be used together, and some alone.

* `method`: Use the **method** request matcher to match requests on the HTTP method
(i.e. GET, POST, PUT, DELETE, etc). You will generally want to use
this matcher. The **method** matcher is used (along with the **uri** matcher)
by default if you do not specify how requests should match.
* `uri`: Use the **uri** request matcher to match requests on the request URI. The
**uri** matcher is used (along with the **method** matcher) by default
if you do not specify how requests should match.
* `host`: Use the **host** request matcher to match requests on the request host.
You can use this (alone, or in combination with **path**) as an
alternative to **uri** so that non-deterministic portions of the URI
are not considered as part of the request matching.
* `path`: Use the **path** request matcher to match requests on the path portion
of the request URI. You can use this (alone, or in combination with **host**)
as an alternative to **uri** so that non-deterministic portions of the URI
* `query`: Use the **query** request matcher to match requests on the query string
portion of the request URI. You can use this (alone, or in combination with
others) as an alternative to **uri** so that non-deterministic portions of
the URI are not considered as part of the request matching.
* `body`: Use the **body** request matcher to match requests on the request body.
* `headers`: Use the **headers** request matcher to match requests on the request headers.

You can set your own options by tweaking the `match_requests_on` parameter in 
`use_cassette()`:

```{r}
library(vcr)
```


```{r echo=FALSE, eval=FALSE}
unlink(file.path(cassette_path(), "foo_bar.yml"))
```

```{r eval = FALSE}
use_cassette(name = "foo_bar", {
    cli$post("post", body = list(a = 5))
  }, 
  match_requests_on = c('method', 'headers', 'body')
)
```

```{r echo=FALSE, eval=FALSE}
unlink(file.path(cassette_path(), "foo_bar.yml"))
```

## Matching

### headers

```{r echo=FALSE, eval=FALSE}
unlink(file.path(cassette_path(), "nothing_new.yml"))
```

```{r eval = FALSE}
library(crul)
library(vcr)
cli <- crul::HttpClient$new("https://httpbin.org/get", 
  headers = list(foo = "bar"))
use_cassette(name = "nothing_new", {
    one <- cli$get()
  }, 
  match_requests_on = 'headers'
)
cli$headers$foo <- "stuff"
use_cassette(name = "nothing_new", {
    two <- cli$get()
  }, 
  match_requests_on = 'headers'
)
one$request_headers
two$request_headers
```

```{r echo=FALSE, eval=FALSE}
unlink(file.path(cassette_path(), "nothing_new.yml"))
```


## More documentation

Check out the [http testing book](https://books.ropensci.org/http-testing/) for a lot more documentation on `vcr`, `webmockr`, and `crul`

