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)
-
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!