Ulrich Schuster
Ulrich Schuster

Reputation: 1896

How to set a custom content type in an Elm HTTP request

I am exploring Elm for use in a single-page application with a REST backend that follows the JSON:API specification. Hence, all resources have the content type application/vnd.api+json instead of the usual application/json. What is the recommended approach to configure this content type in an Elm SPA?

To my understanding, when I use Http.expectJson as expected response type, elm/http will automatically set the request header content type to application/json. How can I change that? Do I need to write my own request functions that wrap Http.request? Is there a simpler, less invasive way to do it?

Upvotes: 1

Views: 212

Answers (2)

Chad Gilbert
Chad Gilbert

Reputation: 36375

Based on your description, it sounds like you are trying to set the Content-Type header of the HTTP request that you are sending to your server. The Http.expectJson function doesn't modify the request header.

If you wanted to change the request header, you can use Http.stringBody to manually set the Content Type being sent to the server. Here's a simple example of such a helper function.

postApiJson : String -> (Result Http.Error a -> msg) -> Decoder a -> Json.Encode.Value -> Cmd msg
postApiJson url msg decoder body =
    Http.post
        { url = url
        , expect = Http.expectJson msg decoder
        , body = Http.stringBody "application/vnd.api+json" (Json.Encode.encode 0 body)
        }

Upvotes: 1

bdukes
bdukes

Reputation: 155945

The Content-Type header is set based on the body, not the expected response (e.g. you could send JSON and expect a byte response, or vice versa). That header is being set to application/json when you use jsonBody, but you can easily use stringBody if you need to use another content type:

import Json.Encode as Encode

apiJsonBody : Encode.Value -> Body
apiJsonBody value =
    stringBody "application/vnd.api+json" (Encode.encode 0 value)

postBook : Book -> Cmd Msg
postBook book =
  Http.post
    { url = "https://example.com/books"
    , body = apiJsonBody (encodeBook book)
    , expect = Http.expectJson GotBooks (list string)
    }

Upvotes: 2

Related Questions