rsvp
Types
A request might fail for a number of reasons. This type is a high-level wrapper over the different kinds of errors that might occur when creating and executing an HTTP request.
pub type Error {
BadBody
BadUrl(String)
HttpError(response.Response(String))
JsonError(json.DecodeError)
NetworkError
UnhandledResponse(response.Response(String))
}
Constructors
-
BadBody
This error can happen when we successfully receive an HTTP response but the body of the response is invalid or not well-formed.
-
BadUrl(String)
-
HttpError(response.Response(String))
This error can happen when the HTTP response status code is not in the
2xx
range but a handler expected it to be. -
JsonError(json.DecodeError)
This error is returned when decoding a JSON response body fails.
-
NetworkError
This error can happen when the HTTP request fails to connect to the server or there is some other connectivity issue.
-
UnhandledResponse(response.Response(String))
This error can be returned by a handler when it does not know how to handle a response. For example, the
expect_json
handler will return this error if the response content-type is not"application/json"
.
A handler is a function that knows how to take the result of an HTTP request
and turn it into a message that can be dispatched back to your update
function. rsvp exposess a number of handlers for common scenarios:
-
expect_json
to ensure a response’s content-type is"application/json"
and run a JSON decoder on that body. -
expect_text
to ensure a response’s content-type specifies"text/"
and return the body as a string. -
expect_ok_response
to handle any response with a 2xx status code. -
expect_any_response
to handle any HTTP response, including 4xx and 5xx errors.
pub opaque type Handler(msg)
Values
pub fn expect_any_response(
handler: fn(Result(response.Response(String), Error)) -> msg,
) -> Handler(msg)
Handle any HTTP response, regardless of status code. Your custom handler will still have to handle potential errors such as network errors or malformed responses.
It is uncommon to need a handler this low-level, instead you can consider the following more-specific handlers:
-
expect_ok_response
to handle any response with a2xx
status code. -
expect_json
to handle responses from JSON apis
pub fn expect_json(
decoder: decode.Decoder(a),
handler: fn(Result(a, Error)) -> msg,
) -> Handler(msg)
A handler that runs a JSON decoder on a response body and returns the result as a message. This handler will check the following conditions:
-
The response status code is
2xx
. -
The response content-type is
"application/json"
-
The response body can be decoded using the provided JSON decoder
If any of these conditions are not met, an Error
will be returned instead.
The specific error will depend on which condition failed:
-
4xx
and5xx
status codes will returnHttpError
-
Other non
2xx
status codes will returnUnhandledResponse
-
A missing or incorrect
content-type
header will returnUnhandledResponse
-
A JSON decoding error will return
JsonError
Note: if you need more advanced handling of the request body directly, you
should use the more-general expect_ok_response
or
expect_any_response
handlers.
pub fn expect_ok_response(
handler: fn(Result(response.Response(String), Error)) -> msg,
) -> Handler(msg)
Handle any response with a 2xx
status code. This handler will return an
Error
if the response status code is not in the 2xx
range. The specific
error will depend on the status code:
-
4xx
and5xx
status codes will returnHttpError
-
Other non
2xx
status codes will returnUnhandledResponse
Note: if you need to handle HTTP responses with different status codes,
you should use the more-general expect_any_response
handler.
pub fn expect_text(
handler: fn(Result(String, Error)) -> msg,
) -> Handler(msg)
Handle the body of a plain text response. This handler will check the following conditions:
-
The response status code is
2xx
. -
The response content-type specifies
"text/"
such as"text/plain"
or"text/html"
.
If any of these conditions are not met, an Error
will be returned instead.
The specific error will depend on which condition failed:
-
4xx
and5xx
status codes will returnHttpError
-
Other non
2xx
status codes will returnUnhandledResponse
-
A missing or incorrect
content-type
header will returnUnhandledResponse
Note: if you need more advanced handling of the request body directly, you
should use the more-general expect_ok_response
or
expect_any_response
handlers.
pub fn get(
url: String,
handler: Handler(msg),
) -> effect.Effect(msg)
A convenience function to send a GET
request to a URL and handle the response
using a Hander
.
Note: if you need more control over the kind of request being sent, for
example to set additional headers or use a different HTTP method, you should
use the more-general send
function instead.
Note: On the JavaScript target this will use the fetch
API. Make
sure you have a polyfill for it if you need to support older browsers or
server-side runtimes that don’t have it.
Note: On the Erlang target this will use the httpc
module. Each
request will start a new linked process to make and handle the request.
pub fn parse_relative_uri(
uri_string: String,
) -> Result(uri.Uri, Nil)
The standard library uri.parse
function does not support relative URIs. When running in the browser, however,
we have enough information to resolve relative URIs into complete ones!
This function will always fail when running on the server, but in the browser it will resolve relative URIs based on the current page’s URL
pub fn post(
url: String,
body: json.Json,
handler: Handler(msg),
) -> effect.Effect(msg)
A convenience function for sending a POST request with a JSON body and handle
the response with a handler function. This will automatically set the
content-type
header to application/json
and handle requests to relative
URLs if this effect is running in a browser.
Note: if you need more control over the kind of request being sent, for
example to set additional headers or use a different HTTP method, you should
use the more-general send
function instead.
Note: On the JavaScript target this will use the fetch
API. Make
sure you have a polyfill for it if you need to support older browsers or
server-side runtimes that don’t have it.
Note: On the Erlang target this will use the httpc
module. Each
request will start a new linked process to make and handle the request.
pub fn send(
request: request.Request(String),
handler: Handler(msg),
) -> effect.Effect(msg)
Send a Request
and dispatch a message back to your update
function when the response is
handled.
For simple requests, you can use the more-convenient get
and
post
functions instead.
Note: On the JavaScript target this will use the fetch
API. Make
sure you have a polyfill for it if you need to support older browsers or
server-side runtimes that don’t have it.
Note: On the Erlang target this will use the httpc
module. Each
request will start a new linked process to make and handle the request.
pub fn simulate(
simulation: simulate.Simulation(model, msg),
response response: response.Response(String),
handler handler: Handler(msg),
) -> simulate.Simulation(model, msg)
Simulate a response in a simulated application. This runs the provided handler against the response and dispatches the message to your simulated application.