StaticHttp requests are an alternative to doing Elm HTTP requests the traditional way using the elm/http package.
The key differences are:
StaticHttp.Requests are performed once at build time (Http.Requests are performed at runtime, at whenever point you perform them)StaticHttp.Requests strip out unused JSON data from the data your decoder doesn't touch to minimize the JSON payloadStaticHttp.Requests can use Pages.Secrets to securely use credentials from your environemnt variables which are completely masked in the production assets.StaticHttp.Requests have a built-in StaticHttp.andThen that allows you to perform follow-up requests without using tasksIf you need data that is refreshed often you may want to do a traditional HTTP request with the elm/http package.
The kinds of situations that are served well by static HTTP are with data that updates moderately frequently or infrequently (or never).
A common pattern is to trigger a new build when data changes. Many JAMstack services
allow you to send a WebHook to your host (for example, Netlify is a good static file host that supports triggering builds with webhooks). So
you may want to have your site rebuild everytime your calendar feed has an event added, or whenever a page or article is added
or updated on a CMS service like Contentful.
In scenarios like this, you can serve data that is just as up-to-date as it would be using elm/http, but you get the performance
gains of using StaticHttp.Requests as well as the simplicity and robustness that comes with it. Read more about these benefits
in this article introducing StaticHttp requests and some concepts around it.
The full details to perform a StaticHttp request.
A simplified helper around StaticHttp.request, which builds up a StaticHttp GET request.
import Json.Decode as Decode exposing (Decoder)
import Pages.StaticHttp as StaticHttp
getRequest : StaticHttp.Request Int
getRequest =
StaticHttp.get "https://api.github.com/repos/dillonkearns/elm-pages"
(Decode.field "stargazers_count" Decode.int)Build a StaticHttp request (analagous to Http.request).
This function takes in all the details to build a StaticHttp request, but you can build your own simplified helper functions
with this as a low-level detail, or you can use functions like StaticHttp.get.
Transform a request into an arbitrary value. The same underlying HTTP requests will be performed during the build step, but mapping allows you to change the resulting values by applying functions to the results.
A common use for this is to map your data into your elm-pages view:
import Json.Decode as Decode exposing (Decoder)
import Pages.StaticHttp as StaticHttp
view =
StaticHttp.get "https://api.github.com/repos/dillonkearns/elm-pages"
(Decode.field "stargazers_count" Decode.int)
|> StaticHttp.map
(\stars ->
{ view =
\model viewForPage ->
{ title = "Current stars: " ++ String.fromInt stars
, body = Html.text <| "⭐️ " ++ String.fromInt stars
, head = []
}
}
)This is useful for prototyping with some hardcoded data, or for having a view that doesn't have any StaticHttp data.
import Pages.StaticHttp as StaticHttp
view :
List ( PagePath Pages.PathKey, Metadata )
->
{ path : PagePath Pages.PathKey
, frontmatter : Metadata
}
->
StaticHttp.Request
{ view : Model -> View -> { title : String, body : Html Msg }
, head : List (Head.Tag Pages.PathKey)
}
view siteMetadata page =
StaticHttp.succeed
{ view =
\model viewForPage ->
mainView model viewForPage
, head = head page.frontmatter
}The way you build a body is analagous to the elm/http package. Currently, only emptyBody and
stringBody are supported. If you have a use case that calls for a different body type, please open a Github issue
and describe your use case!
A body for a StaticHttp request.
Build an empty body for a StaticHttp request. See elm/http's Http.emptyBody.
Builds a string body for a StaticHttp request. See elm/http's Http.stringBody.
Build off of the response from a previous StaticHttp request to build a follow-up request. You can use the data
from the previous response to build up the URL, headers, etc. that you send to the subsequent request.
import Json.Decode as Decode exposing (Decoder)
import Pages.StaticHttp as StaticHttp
licenseData : StaticHttp.Request String
licenseData =
StaticHttp.get
(Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
(Decode.at [ "license", "url" ] Decode.string)
|> StaticHttp.andThen
(\licenseUrl ->
StaticHttp.get (Secrets.succeed licenseUrl) (Decode.field "description" Decode.string)
)Helper to remove an inner layer of Request wrapping.
Turn a list of StaticHttp.Requests into a single one.
import Json.Decode as Decode exposing (Decoder)
import Pages.StaticHttp as StaticHttp
type alias Pokemon =
{ name : String
, sprite : String
}
pokemonDetailRequest : StaticHttp.Request (List Pokemon)
pokemonDetailRequest =
StaticHttp.get
(Secrets.succeed "https://pokeapi.co/api/v2/pokemon/?limit=3")
(Decode.field "results"
(Decode.list
(Decode.map2 Tuple.pair
(Decode.field "name" Decode.string)
(Decode.field "url" Decode.string)
|> Decode.map
(\( name, url ) ->
StaticHttp.get (Secrets.succeed url)
(Decode.at
[ "sprites", "front_default" ]
Decode.string
|> Decode.map (Pokemon name)
)
)
)
)
)
|> StaticHttp.andThen StaticHttp.combineLike map, but it takes in two Requests.
view siteMetadata page =
StaticHttp.map2
(\elmPagesStars elmMarkdownStars ->
{ view =
\model viewForPage ->
{ title = "Repo Stargazers"
, body = starsView elmPagesStars elmMarkdownStars
}
, head = head elmPagesStars elmMarkdownStars
}
)
(get "https://api.github.com/repos/dillonkearns/elm-pages"
(Decode.field "stargazers_count" Decode.int)
)
(get "https://api.github.com/repos/dillonkearns/elm-markdown"
(Decode.field "stargazers_count" Decode.int)
)
A Request that will be made a build time. Multiple
StaticHttp.Requests can be combined together using themapNfunctions, very similar to how you can manipulate values with Json Decoders in Elm.