dream_http_client/recording

Recording format types and JSON codecs

Defines the structure for storing HTTP request/response recordings in a custom JSON format that supports both blocking and streaming responses.

Types

A streaming chunk with timing information

Represents a single chunk of data from a streaming HTTP response, along with the delay (in milliseconds) since the previous chunk. This timing information is used during playback to recreate the original streaming behavior.

Fields

  • data: The chunk data as a BitArray
  • delay_ms: Milliseconds since the previous chunk (0 for the first chunk)

Examples

let chunk = recording.Chunk(
  data: <<"Hello, ":utf8>>,
  delay_ms: 50,  // 50ms delay before this chunk
)
pub type Chunk {
  Chunk(data: BitArray, delay_ms: Int)
}

Constructors

  • Chunk(data: BitArray, delay_ms: Int)

A recorded HTTP request

Captures all components of an HTTP request for recording and playback. This type is used internally by the recorder to match incoming requests against recorded ones.

Fields

  • method: HTTP method (GET, POST, PUT, DELETE, etc.)
  • scheme: Protocol scheme (HTTP or HTTPS)
  • host: Server hostname or IP address
  • port: Optional port number (None uses default: 80 for HTTP, 443 for HTTPS)
  • path: Request path (e.g., “/api/users/123”)
  • query: Optional query string without the leading “?” (e.g., “page=1&limit=10”)
  • headers: List of header name-value pairs
  • body: Request body as a string

Examples

let request = recording.RecordedRequest(
  method: http.Get,
  scheme: http.Https,
  host: "api.example.com",
  port: option.None,
  path: "/users/123",
  query: option.Some("fields=name,email"),
  headers: [#("Authorization", "Bearer token123")],
  body: "",
)
pub type RecordedRequest {
  RecordedRequest(
    method: http.Method,
    scheme: http.Scheme,
    host: String,
    port: option.Option(Int),
    path: String,
    query: option.Option(String),
    headers: List(#(String, String)),
    body: String,
  )
}

Constructors

A recorded HTTP response

Represents either a blocking (complete) response or a streaming response with chunks. This type captures the response data needed for playback.

Variants

  • BlockingResponse(status, headers, body): Complete response body received at once
  • StreamingResponse(status, headers, chunks): Response delivered in chunks with timing

Examples

// Blocking response
let blocking = recording.BlockingResponse(
  status: 200,
  headers: [#("Content-Type", "application/json")],
  body: "{\"users\": []}",
)

// Streaming response
let streaming = recording.StreamingResponse(
  status: 200,
  headers: [#("Content-Type", "text/event-stream")],
  chunks: [
    recording.Chunk(data: <<"chunk1":utf8>>, delay_ms: 100),
    recording.Chunk(data: <<"chunk2":utf8>>, delay_ms: 100),
  ],
)
pub type RecordedResponse {
  BlockingResponse(
    status: Int,
    headers: List(#(String, String)),
    body: String,
  )
  StreamingResponse(
    status: Int,
    headers: List(#(String, String)),
    chunks: List(Chunk),
  )
}

Constructors

  • BlockingResponse(
      status: Int,
      headers: List(#(String, String)),
      body: String,
    )
  • StreamingResponse(
      status: Int,
      headers: List(#(String, String)),
      chunks: List(Chunk),
    )

A complete recording entry (request + response pair)

Represents a single recorded HTTP interaction: one request and its corresponding response. Multiple Recording values are stored together in a RecordingFile.

Fields

  • request: The recorded HTTP request
  • response: The recorded HTTP response (blocking or streaming)

Examples

let recording = recording.Recording(
  request: recorded_request,
  response: recorded_response,
)
pub type Recording {
  Recording(request: RecordedRequest, response: RecordedResponse)
}

Constructors

Recording file format (versioned container)

The top-level structure for storing multiple recordings in a JSON file. Includes a version field for future format compatibility and a list of recording entries.

Fields

  • version: Format version string (currently “1.0”)
  • entries: List of recording entries (request/response pairs)

Examples

let file = recording.RecordingFile(
  version: "1.0",
  entries: [recording1, recording2, recording3],
)

Notes

  • Version field allows future format changes while maintaining backward compatibility
  • This type is primarily used internally by encode_recording_file and decode_recording_file
pub type RecordingFile {
  RecordingFile(version: String, entries: List(Recording))
}

Constructors

  • RecordingFile(version: String, entries: List(Recording))

Values

pub fn decode_recording_file(
  json_string: String,
) -> Result(RecordingFile, String)

Decode a JSON string into a RecordingFile

Parses a JSON string and decodes it into a RecordingFile value. This is the inverse of encode_recording_file() and is used by the storage module when loading recordings from disk.

Parameters

  • json_string: The JSON string to decode (typically read from a file)

Returns

  • Ok(RecordingFile): Successfully decoded recording file
  • Error(String): Human-readable error message describing why decoding failed

Examples

// Read JSON from an individual recording file
let assert Ok(json_content) = simplifile.read("mocks/GET_api.example.com_users_a3f5b2.json")

// Decode to RecordingFile (each file contains one entry)
case recording.decode_recording_file(json_content) {
  Ok(file) -> {
    io.println("Loaded " <> int.to_string(list.length(file.entries)) <> " recording(s)")
  }
  Error(reason) -> io.println_error("Failed to decode: " <> reason)
}

Notes

  • Most callers should use storage.load_recordings() instead of calling this directly
  • This function is used internally by the storage module
  • Error messages include field paths to help identify decoding issues
  • Handles both blocking and streaming response formats
pub fn encode_recording_file(file: RecordingFile) -> json.Json

Encode a RecordingFile to JSON

Converts an in-memory RecordingFile value into a json.Json tree that can be rendered to a string and written to disk. This function handles the JSON encoding of all nested types (requests, responses, chunks, etc.).

Parameters

  • file: The recording file to encode

Returns

A json.Json value representing the recording file structure, ready to be serialized with json.to_string().

Examples

let file = recording.RecordingFile(
  version: "1.0",
  entries: [recording1, recording2],
)

let json_value = recording.encode_recording_file(file)
let json_string = json.to_string(json_value)
// Now write json_string to disk

Notes

  • Most callers should use storage.save_recordings() instead of calling this directly
  • This function is used internally by the storage module
  • The JSON format includes a version field for future compatibility
Search Document