dream/http/request

HTTP request types and utilities

Core request types and functions for working with HTTP requests in Dream. Includes request methods, path parameters, query parameters, and request inspection.

Quick Example

import dream/http/request.{type Request}

pub fn show_user(request: Request, context, services) {
  let result = {
    use id <- result.try(get_int_param(request, "id"))
    let db = services.database.connection
    user_operations.get_user(db, id)
  }
  
  case result {
    Ok(user) -> json_response(status.ok, user_to_json(user))
    Error(err) -> handle_error(err)
  }
}

Types

HTTP request methods

The standard HTTP methods your routes can handle. Use these in your router to specify which method a route responds to.

Example

import dream/http/request.{Get, Post, Put, Delete}
import dream/router.{route, router}

router()
|> route(method: Get, path: "/users", controller: list_users, middleware: [])
|> route(method: Post, path: "/users", controller: create_user, middleware: [])
|> route(method: Put, path: "/users/:id", controller: update_user, middleware: [])
|> route(method: Delete, path: "/users/:id", controller: delete_user, middleware: [])
pub type Method {
  Post
  Get
  Put
  Delete
  Patch
  Options
  Head
}

Constructors

  • Post
  • Get
  • Put
  • Delete
  • Patch
  • Options
  • Head

Path parameter with automatic type conversion and format detection

When you extract a path parameter with get_param(), you get a PathParam that:

  • Detects format extensions (e.g., “123.json” → value=“123”, format=Some(“json”))
  • Provides automatic conversions to Int and Float
  • Keeps the raw value for custom parsing

This makes content negotiation and type conversion trivial.

pub type PathParam {
  PathParam(
    raw: String,
    value: String,
    format: option.Option(String),
    as_int: Result(Int, Nil),
    as_float: Result(Float, Nil),
  )
}

Constructors

  • PathParam(
      raw: String,
      value: String,
      format: option.Option(String),
      as_int: Result(Int, Nil),
      as_float: Result(Float, Nil),
    )

HTTP protocol type

Specifies whether the request came over HTTP or HTTPS.

Example

case request.protocol {
  Http -> // Insecure connection
  Https -> // Secure connection
}
pub type Protocol {
  Http
  Https
}

Constructors

  • Http
  • Https

HTTP request type

Represents a complete HTTP request with all its data. This is what your controllers receive as their first parameter.

Fields

  • method: HTTP method (Get, Post, Put, etc.)
  • protocol: HTTP or HTTPS
  • version: HTTP version (Http1, Http2, Http3)
  • path: Request path (e.g., “/users/123”)
  • query: Raw query string (e.g., “format=json&page=2”)
  • params: Path parameters extracted by router (e.g., [#(“id”, “123”)])
  • host: Host header value (e.g., “example.com”)
  • port: Port number (e.g., 443)
  • remote_address: Client IP address
  • body: Request body as string (for buffered requests)
  • stream: Request body as stream (for streaming requests)
  • headers: List of HTTP headers
  • cookies: List of cookies
  • content_type: Content-Type header value
  • content_length: Content-Length header value

Example

pub fn show_user(request: Request, context, services) {
  // Access request data
  let method = request.method      // Get
  let path = request.path          // "/users/123"
  let headers = request.headers    // All headers
  let cookies = request.cookies    // All cookies
  
  // Get body safely
  let body = body_as_string(request)
  
  // Extract path parameter
  case get_int_param(request, "id") {
    Ok(id) -> show_user_by_id(services.db, id)
    Error(msg) -> error_response(msg)
  }
}
pub type Request {
  Request(
    method: Method,
    protocol: Protocol,
    version: Version,
    path: String,
    query: String,
    params: List(#(String, String)),
    host: option.Option(String),
    port: option.Option(Int),
    remote_address: option.Option(String),
    body: String,
    stream: option.Option(yielder.Yielder(BitArray)),
    headers: List(header.Header),
    cookies: List(cookie.Cookie),
    content_type: option.Option(String),
    content_length: option.Option(Int),
  )
}

Constructors

HTTP version type

Specifies which HTTP protocol version was used. Most requests will be Http1 (HTTP/1.1).

Example

case request.version {
  Http1 -> // HTTP/1.1
  Http2 -> // HTTP/2
  Http3 -> // HTTP/3 (QUIC)
}
pub type Version {
  Http1
  Http2
  Http3
}

Constructors

  • Http1
  • Http2
  • Http3

Values

pub fn body_as_string(request: Request) -> Result(String, Nil)

Get the request body as a string

Helper that handles both buffered (String) and streaming (Yielder) bodies. If the body is streaming, it consumes the stream and converts it to a string.

Example

case body_as_string(request) {
  Ok(body) -> // Use body string
  Error(_) -> // Handle UTF-8 error
}
pub fn get_int_param(
  request: Request,
  name: String,
) -> Result(Int, String)

Extract a path parameter as an integer

Returns a Result with a custom error message if the parameter is missing or cannot be converted to an integer.

Examples

// Route: /users/:id
// Request: /users/123
case get_int_param(request, "id") {
  Ok(id) -> show_user(id)
  Error(msg) -> json_response(status.bad_request, error_json(msg))
}
pub fn get_param(
  request: Request,
  name: String,
) -> Result(PathParam, String)

Extract a path parameter by name

Returns a PathParam with automatic type conversion and format detection. If the parameter doesn’t exist, returns an error message.

For common cases, use get_int_param() or get_string_param() instead, which return Result(Int, String) or Result(String, String) with custom error messages.

Examples

// Route: /users/:id
// Request: /users/123
case get_param(request, "id") {
  Ok(param) -> {
    param.value  // "123"
    param.as_int // Ok(123)
  }
  Error(msg) -> // handle error
}
// Route: /users/:id
// Request: /users/123.json
case get_param(request, "id") {
  Ok(param) -> {
    param.value  // "123"
    param.format // Some("json")
    param.as_int // Ok(123)
  }
  Error(msg) -> // handle error
}
// For simple integer extraction, use get_int_param:
case get_int_param(request, "id") {
  Ok(id) -> show_user(id)
  Error(msg) -> json_response(status.bad_request, error_json(msg))
}
pub fn get_query_param(
  query: String,
  name: String,
) -> option.Option(String)

Get a query parameter value from the raw query string

Properly decodes URL-encoded values (e.g., %20 → space, %26 → &) Returns None if the parameter is not found.

pub fn get_string_param(
  request: Request,
  name: String,
) -> Result(String, String)

Extract a path parameter as a string

Returns a Result with a custom error message if the parameter is missing.

Examples

// Route: /users/:name
// Request: /users/john
case get_string_param(request, "name") {
  Ok(name) -> show_user_by_name(name)
  Error(msg) -> json_response(status.bad_request, error_json(msg))
}
pub fn has_content_type(
  request: Request,
  content_type: String,
) -> Bool

Check if request has a specific content type

pub fn is_method(request: Request, method: Method) -> Bool

Check if request method matches

pub fn method_to_string(method: Method) -> String

Convert Method to its string representation

pub fn parse_method(str: String) -> option.Option(Method)

Parse a string to Method (case-insensitive)

pub fn set_params(
  request: Request,
  new_params: List(#(String, String)),
) -> Request

Create a new request with updated params

Search Document