HttpClient
A module for communicating over HTTP.
You start by building a RequestConfiguration type, which represents the request you'll make to a server. Once done,
you can either do a send
, which represents the response as a Task
, or stream
which will allow you to perform
actions while the request is sending and while the response is coming in. A typical example of why you'd use stream
is to show a progress bar to the user, or decode the response incrementally as opposed to all at once.
See examples/http-client for a working example.
Initialization
Code that wishes to perform HTTP requests require a permission to do so.
A value that represents the permission to perform HTTP requests.
Only code you trust should be granted permission.
Call this during application initialization to get the permission to perform any kind of HTTP request.
Call during application initialization to get a host-specific permission. Code that has this permission value, will only be able to contact a specific host.
Request configuration
In order to send something over HTTP, you first need a description of how that request will look like.
Describes the request to be made. Use get, post or request to initialize
this value, then customize it using the following with
functions.
Initializes the configuration for a simple GET request to the given url.
Initializes the configuration for a simple POST request to the given url.
Initializes a request configuration with the given method and url.
Timeouts
A timeout represents how long you're willing to wait before giving up on receiving a response from the server. Servers might not respond for any number of reasons, like bugs or huge amounts of traffic, so it is a good idea to return an error to the user instead of waiting "forever" for a response.
This is the default timeout value. It is set to 10 seconds. If you don't use withTimeout to set a timeout specifically, this value will be used.
Lets you specify a timeout, in milliseconds, for a request. If the server doesn't respond to your request within the given timeout, the request will fail with a Timeout Error.
Headers
Every HTTP request can have arbitrary metadata attached, called headers. Headers allow you to attach things like authorization information, how the body is encoded or the name of the client making the request.
It might be interesting to read this list of HTTP header fields.
A header is a key-value pair of strings that says something about the request. Examples include the length of the body, authentication information, name of the client making the request, etc.
Header keys doesn't have to be unique. You're allowed to send the same kind of header multiple times, like sending multiple cookies. The behaviour of withHeader will replace the value of an already set header. This function will not.
Request body
The request body is the actual data that you wish to send to a server.
The body represents the main data that you will send in the HTTP request.
Removes the body from the RequestConfiguration. You normally don't have to use this function, as an empty body is the default.
If the "Content-Type" header is set, this function will remove it.
Sets the given string as the request body. You need to provide a mime type to describe what the string contains. This mime type will be set as the "Content-Type" header, potentially overwriting the header if it has already been set.
Sets the provided Json value the request body. A "Content-Type" header will be attached to the request with a value of "application/json", potentially overwriting the header if it has already been set.
Sets the provided Bytes value as the request body. You need to provide a mime type to desribe what the bytes represent. This mime type will be set as the "Content-Type" header, potentially overwriting the header if it has already been set.
Expected response body
Once a request has been sent, you usually get a response. The Expect
type represents
what we expect the response body to be.
This describes what you expect the server will respond with when it receives your request.
Use this when you you don't really care what the server responds with. Anything is fine. Actually, this is the default value so you probably don't need to use this at all.
Expect exactly nothing. Use this when you want a request to fail if the server responds with anything at all.
Use this when you expect the server to respond with a string.
Use this when you expect a Json response. The request will fail if the provided decoder fails.
Use this when you want to treat the response as bytes. This will likely never fail, as anything can be interpreted as bytes.
Send
Once your Response
is configured, you'll want to actually send the request.
Send a request. The task will either complete with a successful Response, or an Error.
The response from the server.
- statusCode: A numerical value that gives an indication of how the request went. It might be a good idea to read this list of HTTP status codes.
- statusText: A human readable interpretation of the status code.
- headers: The headers returned by the server.
- data: The data returned by the server. The type depends on the Expect value you set on the request.
Errors
A HTTP request can fail in a number of ways.
- BadUrl: Something is wrong with the URL you provided.
- BadHeaders: The request headers are invalid. Make sure you only use characters in the latin-1 character set.
- BadStatus: The status code indicates that the response didn't go well. The Response is attached, with a string-encoded data.
- Timeout: The request timed out. The server didn't respond as quickly as you expected it would.
- UnknownError: We don't know what went wrong. You should probably report this if you see it in the wild.
Gives a brief description of an error.
Streaming
Streaming is the more advanced way to perform a HTTP request. This requires that you follow the Elm architecture, as you'll receive messages for every chunk of data sent and received. The benefit of this extra complexity, is that you can perform actions while the request is being performed.
Identifies a streaming request. Required to perform certain operations while the request is streaming.
When a request is streaming, the application is notified of important events and is required to act on those events for the request to be successful.
- SentChunk: The initial request body, or the last piece of data sent with sendChunk has been sent.
Send more data, or call
startReceive
to begin listening for the response. - ReceivedChunk: The server has responded with some data. More data might be coming in, though.
The
Done
event will be triggered when there's no more data coming. You can use the providedResponse
object to access the response headers, and decide if you'd like to abort the request or not. - Error: Something went wrong. More information in the provided Error object.
- Aborted: You called abort on this request.
- Done: The server has sent all it's going to send. You're done.
Initialize a streaming request. You need to provide a function that generates a message
for handling StreamEvents. The headers and data will be sent to the server
immedietly, and a SentChunk
event will be sent they're done.
To tell different requests apart, you can use a partially applied custom type like this:
type Msg = HttpRequest String StreamEvent
HttpClient.stream httpPermission (HttpRequest "Request 1") requestConfig
Send more data to the server. This allows you to generate more data as you need to, enabling you slice up a potentially costly, memory heavy or long-running operation over time.
You don't have to wait for the matching SentChunk
event before sending more data but keep in
mind that data will be kept in memory until sent, potentially causing out-of-memory errors in
the case of large amounts of data.
If you're already receiving data from the server, calling this function will no effect.
Use this when you're done sending data. The server will now begin streaming you the response.
Stops the request, for any reason, at any time. Useful if you have an unexpected error with your own source of data, or if the server response is one you know you don't want to handle after having inspected the headers.