Customization

The Request type is a opaque type that describes how to make an HTTP request. Each Request can be customized using the update functions in Api.elm, e.g. for adding headers, changing the base path or setting a timeout. Using the send function and a Msg the request can be converted to a Cmd Msg which allows Elm to make the actual call.

The customization also allows you to set-up your own generic solution for making HTTP requests. Let's say you need to add an authentication header to each request and your base path is loaded from your program's flags. You capture this data and store it in a Server record. The customization enables you to define your own send function like this:

type alias Server =
    { basePath : String
    , accessToken : String
    }

send : Server -> (Result Http.Error a -> msg) -> Request a -> Cmd msg
send { basePath, accessToken } toMsg request =
    request
        |> Api.withBasePath basePath
        |> Api.withHeader "ACCESS_TOKEN" accessToken
        |> Api.send toMsg

Now throughout your program you can use this function instead of the default Api.send.

The following sub-sections explain the possible customizations.

map

Api.map allows you to change the return type of a Request by mapping a Request a to a Request b. This may be useful when the OpenAPI specification returns a different type from what you would like to use.

As an example let's assume we generated the following function:

updateUser : Api.Data.User -> Api.Request Api.Data.User

updateUser takes and gives us a Api.Data.User. If we rather work with our own CustomUser instead we can map both the input and the output types using composition and Api.map:

toCustomUser : Api.Data.User -> CustomUser

fromCustomUser : CustomUser -> Api.Data.User

updateCustomUser : CustomUser -> Api.Request CustomUser
updateCustomUser = Api.map toCustomUser << updateUser << fromCustomUser

We now should use updateCustomUser instead of updateUser.

withBasePath

You can override the base path as defined in the OpenAPI specification. You can do this per request or you can fully customize the Api.send.

An example:

sendWithBasePath : (Result Http.Error a -> msg) -> Request a -> Cmd msg
sendWithBasePath toMsg request =
    request
        |> Api.withBasePath "http://elm-lang.org"
        |> Api.send toMsg

withTimeout

By default, Elm HTTP requests have no timeout. You can set one per request or you can fully customise the Api.send. The timeout is defined in milliseconds.

An example:

sendWithTimeout : (Result Http.Error a -> msg) -> Request a -> Cmd msg
sendWithTimeout toMsg request =
    request
        |> Api.withTimeout 30000
        |> Api.send toMsg

withTracker

Elm HTTP allows you to track requests. Setting the same tracker for each request probably does not make much sense, but you can set one per requests or fully customize the Api.send to accept one.

An example:

sendAndTrack : String -> (Result Http.Error a -> msg) -> Request a -> Cmd msg
sendAndTrack tracker toMsg request =
    request
        |> Api.withTracker tracker
        |> Api.send toMsg

withBearerToken

OpenAPI allows you to specify what security scheme your API uses. When using bearer authorization a header with the token is added using this function.

An example:

sendAuthenticated : String -> (Result Http.Error a -> msg) -> Request a -> Cmd msg
sendAuthenticated token toMsg request =
    request
        |> Api.withBearerToken token
        |> Api.send toMsg

withHeader and withHeaders

OpenAPI allows you to specify what headers need to be send. On top of that you can define your own additional (set of) header(s) on each request.

An example:

sendWithHeader : (Result Http.Error a -> msg) -> Request a -> Cmd msg
sendWithHeader toMsg request =
    request
        |> Api.withHeader "Max-Forwards" "10"
        |> Api.send toMsg

send and sendWithCustomError

The basic send function takes a Request a and eventually results in a message of Result Http.Error a once the Cmd is handled by the Elm runtime. sendWithCustomError allows you to map the Http.Error before making the actual request. This allows you to add custom error handling for all your requests.

An example:

type ApiError
    = Unauthorized
    | Forbidden
    | NotFound
    | ApiError String


sendWithCustomError : (Result ApiError a -> msg) -> Request a -> Cmd msg
sendWithCustomError =
    Api.sendWithCustomError (\result ->
        case result of
            Ok v ->
                Ok v

            Err (BadUrl _) ->
                ApiError "Oops, we messed up!"

            Err Timeout ->
                ApiError "Server timeout. Please try again later."

            Err NetworkError ->
                ApiError "Network error."

            Err (BadStatus code) ->
                case code of
                    401 ->
                        Unauthorized

                    403 ->
                        Forbidden

                    404 ->
                        NotFound

                    _ ->
                        ApiError "Oops, the request failed."

            Err (BadBody _) ->
                ApiError "Oops, we messed up!"
    )

task

Just like Elm's Http library, the generator also supports both commands and tasks. You can use task to create a Task from a Request. If you simply need a Cmd msg then send is the better option here.

Note: tracking requests is not supported when using tasks as it is also not supported in the native library.

results matching ""

    No results matching ""