This module provides the createApiAndServerDecs function. At compile time,
it will read all the files under a specified directory, embed their contents,
create a Servant "API" type synonym representing their directory layout, and
create a ServerT function for serving their contents statically.
Let's assume that we have a directory called "dir" in the root of our
Haskell web API that looks like this:
type FrontEndAPI =
-- index.html is served on the root, as well as from the path "/index.html".
Servant.API.Get '[HTML] Html:<|> "index.html" Servant.API.:>Servant.API.Get '[HTML] Html
-- hello.html is served from the path "/hello.html".
:<|> "hello.html" Servant.API.:>Servant.API.Get '[HTML] Html
-- jstest.js is served from the path "js/test.js".
:<|> "js" Servant.API.:> "test.js" Servant.API.:>Servant.API.Get '[JS] ByteString
frontEndServer :: Applicative m => Servant.Server.ServerT FrontEndAPI m
frontEndServer =
pure "<p>This is the index</p>"
:<|>pure "<p>This is the index</p>"
:<|>pure "<p>Hello World</p>"
:<|>pure "console.log(\"hello world\");"
If this WAI application is running, it is possible to use curl to access
the server:
$ curl localhost:8080/
<p>This is the index</p>
$ curl localhost:8080/index.html
<p>This is the index</p>
$ curl localhost:8080/hello.html
<p>Hello World</p>
$ curl localhost:8080/js/test.js
console.log("hello world");
This createApiAndServerDecs function is convenient to use when you want to
make a Servant application easy to deploy. All the static frontend files are
bundled into the Haskell binary at compile-time, so all you need to do is
deploy the Haskell binary. This works well for low-traffic websites like
prototypes and internal applications.
This shouldn't be used for high-traffic websites. Instead, you should serve
your static files from something like Apache, nginx, or a CDN.
Note:
If you are creating a cabal package that needs to work with cabal-install,
the "dir" you want to serve needs to be a relative path inside your
project root, and all contained files need to be listed in your
.cabal-file under the extra-source-files field so that they are
included and available at compile-time.
Take a template directory argument as a FilePath and create a Servant
type representing the files in the directory. Empty directories will be
ignored. index.html files will also be served at the root.
For example, assume the following directory structure:
Take a template directory argument as a FilePath and create a ServerT
function that serves the files under the directory. Empty directories will
be ignored. index.html files will also be served at the root.
Note that the file contents will be embedded in the function. They will
not be served dynamically at runtime. This makes it easy to create a
Haskell binary for a website with all static files completely baked-in.
For example, assume the following directory structure and file contents:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TemplateHaskell #-}
type FrontEndAPI = $(Servant.Static.TH.Internal.API.createApiType "dir")
frontEndServer :: Applicative m => ServerT FrontEndAPI m
frontEndServer = $(createServerExp "dir")
At compile time, this expands to something like the following. This has
been slightly simplified to make it easier to understand:
type FrontEndAPI =
"js" Servant.API.:> "test.js" Servant.API.:>Servant.API.Get '[JS] ByteString:<|>Servant.API.Get '[HTML] Html:<|> "index.html" Servant.API.:>Servant.API.Get '[HTML] Html
frontEndServer :: Applicative m => ServerT FrontEndAPI m
frontEndServer =
pure "console.log(\"hello world\");"
:<|>pure "<p>Hello World</p>"
The following types are the MIME types supported by servant-static-th.
If you need additional MIME types supported, feel free to create an
issue or
PR.
AcceptXMLDefined in servant-static-th-1.0.0.0 · Servant.Static.TH.Internal.Mime
application/xml
MimeRenderXMLByteStringDefined in servant-static-th-1.0.0.0 · Servant.Static.TH.Internal.Mime
Easy-To-Use Names and Paths
0 declarations
The functions in this section pick defaults for the template
directory, api name, and the server function name. This makes it easy to
use for quick-and-dirty code.