Elm 0.18 made significant changes to the Http
API. This module
re-implements the entire Elm 0.17 API.
Note that we could not avoid adding an extra parameter to the string
function. We also could not avoid adding a new constructor to RawError
and Error
.
url : String -> List ( String, String ) -> String
Create a properly encoded URL with a query string. The first argument is the portion of the URL before the query string, which is assumed to be properly encoded already. The second argument is a list of all the key/value pairs needed for the query string. Both the keys and values will be appropriately encoded, so they can contain spaces, ampersands, etc.
url "http://example.com/users" [ ("name", "john doe"), ("age", "30") ]
--> "http://example.com/users?name=john+doe&age=30"
uriEncode : String -> String
Encode a string to be placed in any part of a URI. Same behavior as
JavaScript's encodeURIComponent
function.
uriEncode "hat" --> "hat"
uriEncode "to be" --> "to%20be"
uriEncode "99%" --> "99%25"
uriDecode : String -> String
Decode a URI string. Same behavior as JavaScript's decodeURIComponent
function.
-- ASCII
uriDecode "hat" --> "hat"
uriDecode "to%20be" --> "to be"
uriDecode "99%25" --> "99%"
-- UTF-8
uriDecode "%24" --> "$"
uriDecode "%C2%A2" --> "¢"
uriDecode "%E2%82%AC" --> "€"
-- Failing
uriDecode "%" --> "%" -- not followed by two hex digits
uriDecode "%XY" --> "%XY" -- not followed by two HEX digits
uriDecode "%C2" --> "%C2" -- half of the "¢" encoding "%C2%A2"
In later verions of Elm, the signature of the equivalent functions is
String -> Maybe String
to account for the fact that the input may be invalidly encoded. We can't do exactly that here, so if the input is invalid, we return it unchanged.
getString : String -> Task Error String
Send a GET request to the given URL. You will get the entire response as a string.
hats : Task Error String
hats =
getString "http://example.com/hat-categories.markdown"
get : Json.Decode.Decoder value -> String -> Task Error value
Send a GET request to the given URL. You also specify how to decode the response.
hats : Task Error (List String)
hats =
get (list string) "http://example.com/hat-categories.json"
post : Json.Decode.Decoder value -> String -> Body -> Task Error value
Send a POST request to the given URL, carrying the given body. You also specify how to decode the response with a JSON decoder.
hats : Task Error (List String)
hats =
post (list string) "http://example.com/hat-categories.json" empty
The kinds of errors you typically want in practice. When you get a
response but its status is not in the 200 range, it will trigger a
BadResponse
. When you try to decode JSON but something goes wrong,
you will get an UnexpectedPayload
.
A new
BadUrl
constructor has been added which was not in Elm 0.17.
Http.Body
An opaque type representing the body of your HTTP message. With GET requests this is empty, but in other cases it may be a string or blob.
empty : Body
An empty request body, no value will be sent along.
string : String -> String -> Body
Provide a string as the body of the request.
Notice that the first argument is a MIME type so we know to add
Content-Type: application/json
to our request headers. Make sure your
MIME type matches your data. Some servers are strict about this!
Im Elm 0.17, the first parameter was missing, and it seems that Elm did not send a
Content-type
header at all. In later versions of Elm, there is no way of avoiding sending aContent-type
header, so we have to supply the content type here. Thus, you will need to modify your code to specify the desired content type.
multipart : List Data -> Body
Create multi-part request bodies, allowing you to send many chunks of data all in one request. All chunks of data must be given a name.
Currently, you can only construct stringData
, but we will support blobData
and fileData
once we have proper APIs for those types of data in Elm.
Http.Part
Represents data that can be put in a multi-part body. Right now it only supports strings, but we will support blobs and files when we get an API for them in Elm.
stringData : String -> String -> Data
A named chunk of string data.
import Json.Encode as JS
body =
multipart
[ stringData "user" (JS.encode user)
, stringData "payload" (JS.encode payload)
]
send : Settings -> Request -> Task RawError Response
Send a request exactly how you want it. The Settings
argument lets you
configure things like timeouts and progress monitoring. The Request
argument
defines all the information that will actually be sent along to a server.
crossOriginGet : String -> String -> Task RawError Response
crossOriginGet origin url =
send defaultSettings
{ verb = "GET"
, headers = [ ( "Origin", origin ) ]
, url = url
, body = empty
}
{ verb : String
, headers : List ( String
, String )
, url : String
, body : Body
}
Fully specify the request you want to send. For example, if you want to send a request between domains (CORS request) you will need to specify some headers manually.
corsPost : Request
corsPost =
{ verb = "POST"
, headers =
[ ( "Origin", "http://elm-lang.org" )
, ( "Access-Control-Request-Method", "POST" )
, ( "Access-Control-Request-Headers", "X-Custom-Header" )
]
, url = "http://example.com/hats"
, body = empty
}
In later versions of Elm, this becomes an opaque type.
{ timeout : Time018.Time
, withCredentials : Basics.Bool
}
Configure your request if you need specific behavior.
timeout
lets you specify how long you are willing to wait for a response
before giving up. By default it is 0 which means “never give
up!”It is not feasible to re-implement the
onStart
oronProgress
fields with the same signatures as in Elm 0.17. For this reason, those fields have been omitted ... to track progress, you will need to use the Elm 0.19 APIs.It is also not possible in Elm 0.19 to re-implement what Elm 0.17 did with the
desiredResponseType
field. Therefore, it has also been omitted.
defaultSettings : Settings
The default settings used by get
and post
.
{ timeout = 0
, onStart = Nothing
, onProgress = Nothing
, desiredResponseType = Nothing
, withCredentials = False
}
{ status : Basics.Int
, statusText : String
, headers : Dict String String
, url : String
, value : Value
}
All the details of the response. There are many weird facts about responses which include:
status
may be 0 in the case that you load something from file://
url
field will let you know who sent you the response, so
you will know if it does not match the URL you requested.We have left these underlying facts about XMLHttpRequest
as is because one
goal of this library is to give a low-level enough API that others can build
whatever helpful behavior they want on top of it.
The information given in the response. Currently there is no way to handle
Blob
types since we do not have an Elm API for that yet. This type will
expand as more values become available in Elm itself.
fromJson : Json.Decode.Decoder a -> Task RawError Response -> Task Error a
Turn a Response
into an Elm value that is easier to deal with. Helpful
if you are making customized HTTP requests with send
, as is the case with
get
and post
.
Given a Response
this function will:
Value
is a string.Decoder
.Assuming all these steps succeed, you will get an Elm value as the result!
The things that count as errors at the lowest level. Technically, getting a response back with status 404 is a “successful” response in that you actually got all the information you asked for.
The fromJson
function and Error
type provide higher-level errors, but the
point of RawError
is to allow you to define higher-level errors however you
want.
We needed to add a new constructor
RawBadUrl
to cover an error state added in Elm 0.18.