lustre_http

Types

An expectation of what kind of response we’re expecting to receive. This is how you an teach lustre_http to turn HTTP responses into messages your app can handle.

For simple cases, you can use expect_text and expect_json. These functions handle the response for you and you just need to provide a function to turn the text or JSON into a message.

For more complex cases, you can use expect_text_response instead. This function lets you handle the gleam_http Response directly and is useful if you want to handle specific HTTP status codes or read the response headers.

pub opaque type Expect(msg)

A HTTP request might fail in a few different ways: some of these are errors from the server (e.g. a 404 NotFound error) but others are ways your request can fail on the client. This type enumerates all of them.

pub type HttpError {
  BadUrl(String)
  InternalServerError(String)
  JsonError(json.DecodeError)
  NetworkError
  NotFound
  OtherError(Int, String)
  Unauthorized
}

Constructors

  • BadUrl(String)

    Both get and post let you pass the request URL as a string. This error is returned if you pass in something that isn’t a valid URL.

  • InternalServerError(String)

    The server returned a 500 Internal Server Error. The body of the response is included as a string.

  • JsonError(json.DecodeError)

    When you use expect_json to decode an incoming response, this error is returned if the body is not valid JSON or the decoder fails.

  • NetworkError

    If you try and make a request while the client is offline, this error is returned.

  • NotFound

    The server returned a 404 Not Found error.

  • OtherError(Int, String)

    Any other non-200 response from the server that is not 404, 401 or 500 will be returned as this error. The status code and body of the response are included.

  • Unauthorized

    The server returned a 401 Unauthorized error.

Functions

pub fn expect_anything(
  to_msg: fn(Result(Nil, HttpError)) -> a,
) -> Expect(a)

Expect any response. This is useful if you want to just fire off a request and make sure it was successful. If you want to handle the response body in some way, you should take a look at expect_text or expect_json instead.

pub fn expect_json(
  decoder: fn(Dynamic) -> Result(a, List(DecodeError)),
  to_msg: fn(Result(a, HttpError)) -> b,
) -> Expect(b)

Expect a JSON response. The decoder is used to decode the JSON into a well-typed Gleam value. If this fails, the JsonError error variant will be returned.

Usage

import lustre_http as http
import gleam/dynamic

type Post {
  Post(id: Int, title: String, body: String)
}

type Msg {
  GotPosts(Result(List(Post), http.HttpError))
}

fn get_posts() -> Effect(msg) {
  let url = "https://jsonplaceholder.typicode.com/posts"
  let decoder = dynamic.decode3(
    Post,
    dynamic.field("id", dynamic.int),
    dynamic.field("title", dynamic.string),
    dynamic.field("body", dynamic.string),
  )

  http.get(url, http.expect_json(dynamic.list(decoder)), GotPosts)
}
pub fn expect_text(
  to_msg: fn(Result(String, HttpError)) -> a,
) -> Expect(a)

Expect a plain text response.

pub fn expect_text_response(
  on_response: fn(Response(String)) -> Result(a, b),
  on_failure: fn(HttpError) -> b,
  to_msg: fn(Result(a, b)) -> c,
) -> Expect(c)

Expect a gleam_http Response and handle it yourself. This is necessary if you want to handle specific HTTP status codes or read the response headers.

pub fn get(url: String, expect: Expect(a)) -> Effect(a)

Send a GET request to the given URL and say what kind of response you’re expecting. If the url is invalid, the expect handler will receive a BadUrl error.

Usage

import lustre_http as http

type Msg {
  GotIpAddress(Result(String, http.HttpError))
  WhoAmI
}

fn update(model, msg) {
  case msg {
    GotIpAddress(Ok(ip)) -> ...
    GotIpAddress(Error(err)) -> ...
    WhoAmI -> #(
      model,
      http.get("https://api.ipify.org", http.expect_text(GotIpAddress)
    )
  }
}

If you need tighter control over the request - e.g. to set headers - you can construct the request manually using the gleam_http package and then use send instead.

pub fn post(
  url: String,
  body: Json,
  expect: Expect(a),
) -> Effect(a)

Send a POST request to the given URL and say what kind of response you’re expecting. If the url is invalid, the expect handler will receive a BadUrl error.

Usage

import lustre_http as http
import gleam/json.{type Json}

type Msg {
  GotResponse(Result(Nil, http.HttpError))
  CreatePost(body: Json)
}

fn update(model, msg) {
  case msg {
    GotResponse(Ok(_)) -> ...
    GotResponse(Error(err)) -> ...
    CreatePost(body) -> #(
      model,
      http.post(
        "https://jsonplaceholder.typicode.com/posts",
        body,
        http.expect_anything(GotResponse))
    )
  }
}

If you need tighter control over the request - e.g. to set headers - you can construct the request manually using the gleam_http package and then use send instead.

pub fn send(req: Request(String), expect: Expect(a)) -> Effect(a)

Send a gleam_http Request along with what kind of response you’re expecting to receive. Once the request is complete, the response will be turned into a message you can handle in your update function.

If you just want to make a simple GET or POST request, you might find either get or post easier to use!

Search Document