# Cassette format

VCR Cassettes are files that contain all of the information about the requests and corresponding responses in a human-readable/editable format. A cassette contains an array of HTTP interactions, each of which has the following:

* request
  * method
  * uri
  * body
    * encoding
    * string
  * headers
* response

  * status
    * code
    * message
  * headers
  * body
    * encoding
    * string
  * http version

  By default, VCR uses YAML to serialize this data. You can configure VCR to use a different serializer, either on a cassette-by-cassette basis, or as a default for all cassettes if you use the `default_cassette_options`.

  VCR supports the following serializers out of the box:
* `:yaml`--Uses ruby's standard library YAML. This may use psych or syck, depending on your ruby installation.
* `:syck`--Uses syck (the ruby 1.8 YAML engine). This is useful when using

  VCR on a project that must run in environments where psych is not available

  (such as on ruby 1.8), to ensure that syck is always used.
* `:psych`--Uses psych (the new ruby 1.9 YAML engine). This is useful when

  you want to ensure that psych is always used.
* `:json`--Uses [multi\_json](https://github.com/intridea/multi_json)

  to serialize the cassette data as JSON.
* `:compressed`--Wraps the default YAML serializer with Zlib, writing compressed cassettes to disk.

  You can also register a custom serializer using:

  VCR.configure do |config| config.cassette\_serializers\[:my\_custom\_serializer] = my\_serializer end

  Your serializer must implement the following methods:
* `file_extension`
* `serialize(hash)`
* `deserialize(string)`

## Request/Response data is saved to disk as YAML by default

*Given* a file named "cassette\_yaml.rb" with:

```
include_http_adapter_for("<http_lib>")

if ARGV.any?
  $server = start_sinatra_app do
    get('/:path') { ARGV[0] + ' ' + params[:path] }
  end
end

require 'vcr'

VCR.configure do |c|
  <configuration>
  c.cassette_library_dir = 'cassettes'
  c.before_record do |i|
    i.request.uri.sub!(/:\d+/, ':7777')
  end
end

VCR.use_cassette('example') do
  make_http_request(:get, "http://localhost:#{$server.port}/foo", nil, 'Accept-Encoding' => 'identity')
  make_http_request(:get, "http://localhost:#{$server.port}/bar", nil, 'Accept-Encoding' => 'identity')
end
```

*When* I successfully run `ruby cassette_yaml.rb 'Hello'`

*Then* the file "cassettes/example.yml" should contain YAML like:

```
---
http_interactions:
- request:
    method: get
    uri: http://localhost:7777/foo
    body:
      encoding: UTF-8
      string: ""
    headers:
      Accept-Encoding:
      - identity
  response:
    status:
      code: 200
      message: OK
    headers:
      Content-Type:
      - text/html;charset=utf-8
      Content-Length:
      - "9"
    body:
      encoding: UTF-8
      string: Hello foo
    http_version: "1.1"
  recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
- request:
    method: get
    uri: http://localhost:7777/bar
    body:
      encoding: UTF-8
      string: ""
    headers:
      Accept-Encoding:
      - identity
  response:
    status:
      code: 200
      message: OK
    headers:
      Content-Type:
      - text/html;charset=utf-8
      Content-Length:
      - "9"
    body:
      encoding: UTF-8
      string: Hello bar
    http_version: "1.1"
  recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
recorded_with: VCR 2.0.0
```

### Examples

| configuration          | http\_lib              |
| ---------------------- | ---------------------- |
| c.hook\_into :webmock  | net/http               |
| c.hook\_into :webmock  | httpclient             |
| c.hook\_into :webmock  | patron                 |
| c.hook\_into :webmock  | curb                   |
| c.hook\_into :webmock  | em-http-request        |
| c.hook\_into :webmock  | typhoeus               |
| c.hook\_into :typhoeus | typhoeus               |
| c.hook\_into :excon    | excon                  |
| c.hook\_into :faraday  | faraday (w/ net\_http) |

## Request/Response data can be saved as JSON

*Given* a file named "cassette\_json.rb" with:

```
include_http_adapter_for("net/http")

$server = start_sinatra_app do
  get('/:path') { ARGV[0] + ' ' + params[:path] }
end

require 'vcr'

VCR.configure do |c|
  c.hook_into :webmock
  c.cassette_library_dir = 'cassettes'
  c.before_record do |i|
    i.request.uri.sub!(/:\d+/, ':7777')
  end
  c.default_cassette_options = {
    :match_requests_on => [:method, :host, :path]
  }
end

VCR.use_cassette('example', :serialize_with => :json) do
  puts response_body_for(:get, "http://localhost:#{$server.port}/foo", nil, 'Accept-Encoding' => 'identity')
  puts response_body_for(:get, "http://localhost:#{$server.port}/bar", nil, 'Accept-Encoding' => 'identity')
end
```

*When* I run `ruby cassette_json.rb 'Hello'`

*Then* the file "cassettes/example.json" should contain JSON like:

```
{
  "http_interactions": [
    {
      "response": {
        "body": {
          "encoding": "UTF-8",
          "string": "Hello foo"
        },
        "http_version": null,
        "status": { "code": 200, "message": "OK" },
        "headers": {
          "Date": [ "Thu, 27 Oct 2011 06:16:31 GMT" ],
          "Content-Type": [ "text/html;charset=utf-8" ],
          "Content-Length": [ "9" ],
          "Server": [ "WEBrick/1.3.1 (Ruby/1.8.7/2011-06-30)" ],
          "Connection": [ "Keep-Alive" ]
        }
      },
      "request": {
        "uri": "http://localhost:7777/foo",
        "body": {
          "encoding": "UTF-8",
          "string": ""
        },
        "method": "get",
        "headers": {
          "Accept-Encoding": [ "identity" ]
        }
      },
      "recorded_at": "Tue, 01 Nov 2011 04:58:44 GMT"
    },
    {
      "response": {
        "body": {
          "encoding": "UTF-8",
          "string": "Hello bar"
        },
        "http_version": null,
        "status": { "code": 200, "message": "OK" },
        "headers": {
          "Date": [ "Thu, 27 Oct 2011 06:16:31 GMT" ],
          "Content-Type": [ "text/html;charset=utf-8" ],
          "Content-Length": [ "9" ],
          "Server": [ "WEBrick/1.3.1 (Ruby/1.8.7/2011-06-30)" ],
          "Connection": [ "Keep-Alive" ]
        }
      },
      "request": {
        "uri": "http://localhost:7777/bar",
        "body": {
          "encoding": "UTF-8",
          "string": ""
        },
        "method": "get",
        "headers": {
          "Accept-Encoding": [ "identity" ]
        }
      },
      "recorded_at": "Tue, 01 Nov 2011 04:58:44 GMT"
    }
  ],
  "recorded_with": "VCR 2.0.0"
}
```

*When* I run `ruby cassette_json.rb`

*Then* it should pass with:

```
Hello foo
Hello bar
```

## Request/Response data can be saved as compressed YAML

*Given* a file named "cassette\_compressed.rb" with:

```
include_http_adapter_for("net/http")

$server = start_sinatra_app do
  get('/:path') { ARGV[0] + ' ' + params[:path] }
end

require 'vcr'

VCR.configure do |c|
  c.hook_into :webmock
  c.cassette_library_dir = 'cassettes'
  c.before_record do |i|
    i.request.uri.sub!(/:\d+/, ':7777')
  end
  c.default_cassette_options = {
    :match_requests_on => [:method, :host, :path]
  }
end

VCR.use_cassette('example', :serialize_with => :compressed) do
  puts response_body_for(:get, "http://localhost:#{$server.port}/foo", nil, 'Accept-Encoding' => 'identity')
  puts response_body_for(:get, "http://localhost:#{$server.port}/bar", nil, 'Accept-Encoding' => 'identity')
end
```

*When* I run `ruby cassette_compressed.rb 'Hello'`

*Then* the file "cassettes/example.zz" should contain compressed YAML like:

```
---
http_interactions:
- request:
    method: get
    uri: http://localhost:7777/foo
    body:
      encoding: UTF-8
      string: ""
    headers:
      Accept-Encoding:
      - identity
  response:
    status:
      code: 200
      message: OK
    headers:
      Content-Type:
      - text/html;charset=utf-8
      Content-Length:
      - "9"
    body:
      encoding: UTF-8
      string: Hello foo
  recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
- request:
    method: get
    uri: http://localhost:7777/bar
    body:
      encoding: UTF-8
      string: ""
    headers:
      Accept-Encoding:
      - identity
  response:
    status:
      code: 200
      message: OK
    headers:
      Content-Type:
      - text/html;charset=utf-8
      Content-Length:
      - "9"
    body:
      encoding: UTF-8
      string: Hello bar
  recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
recorded_with: VCR 2.0.0
```

*When* I run `ruby cassette_compressed.rb`

*Then* it should pass with:

```
Hello foo
Hello bar
```

## Request/Response data can be saved using a custom serializer

*Given* a file named "cassette\_ruby.rb" with:

```
include_http_adapter_for("net/http")

$server = start_sinatra_app do
  get('/:path') { ARGV[0] + ' ' + params[:path] }
end

require 'vcr'

# purely for demonstration purposes; obviously, don't actually
# use ruby #inspect / #eval for your serialization...
ruby_serializer = Object.new
class << ruby_serializer
  def file_extension; "ruby"; end
  def serialize(hash); hash.inspect; end
  def deserialize(string); eval(string); end
end

VCR.configure do |c|
  c.hook_into :webmock
  c.cassette_library_dir = 'cassettes'
  c.cassette_serializers[:ruby] = ruby_serializer
  c.before_record do |i|
    i.request.uri.sub!(/:\d+/, ':7777')
  end
  c.default_cassette_options = {
    :match_requests_on => [:method, :host, :path]
  }
end

VCR.use_cassette('example', :serialize_with => :ruby) do
  puts response_body_for(:get, "http://localhost:#{$server.port}/foo", nil, 'Accept-Encoding' => 'identity')
  puts response_body_for(:get, "http://localhost:#{$server.port}/bar", nil, 'Accept-Encoding' => 'identity')
end
```

*When* I run `ruby cassette_ruby.rb 'Hello'`

*Then* the file "cassettes/example.ruby" should contain ruby like:

```
{"http_interactions"=>
  [{"request"=>
     {"method"=>"get",
      "uri"=>"http://localhost:7777/foo",
      "body"=>{"encoding"=>"UTF-8", "string"=>""},
      "headers"=>{"Accept"=>["*/*"], "Accept-Encoding"=>["identity"], "User-Agent"=>["Ruby"]}},
    "response"=>
     {"status"=>{"code"=>200, "message"=>"OK "},
      "headers"=>
       {"Content-Type"=>["text/html;charset=utf-8"],
        "Content-Length"=>["9"],
        "Connection"=>["Keep-Alive"]},
      "body"=>{"encoding"=>"UTF-8", "string"=>"Hello foo"},
      "http_version"=>nil},
    "recorded_at"=>"Tue, 01 Nov 2011 04:58:44 GMT"},
   {"request"=>
     {"method"=>"get",
      "uri"=>"http://localhost:7777/bar",
      "body"=>{"encoding"=>"UTF-8", "string"=>""},
      "headers"=>{"Accept"=>["*/*"], "Accept-Encoding"=>["identity"], "User-Agent"=>["Ruby"]}},
    "response"=>
     {"status"=>{"code"=>200, "message"=>"OK "},
      "headers"=>
       {"Content-Type"=>["text/html;charset=utf-8"],
        "Content-Length"=>["9"],
        "Connection"=>["Keep-Alive"]},
      "body"=>{"encoding"=>"UTF-8", "string"=>"Hello bar"},
      "http_version"=>nil},
    "recorded_at"=>"Tue, 01 Nov 2011 04:58:44 GMT"}],
 "recorded_with"=>"VCR 2.0.0"}
```

*When* I run `ruby cassette_ruby.rb`

*Then* it should pass with:

```
Hello foo
Hello bar
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://andrewmcodes.gitbook.io/vcr/cassettes/format.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
