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 aBitArraydelay_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 addressport: 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 pairsbody: 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
-
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, )
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 onceStreamingResponse(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 requestresponse: 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(request: RecordedRequest, response: RecordedResponse)
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_fileanddecode_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 fileError(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