servant-static-th- Embed a directory of static files in your Servant server

Safe HaskellNone




createServerExp :: FilePath -> Q Exp Source #

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.

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:

  $ tree dir/
  ├── js
  │   └── test.js
  └── index.html
  $ cat dir/index.html
  <p>Hello World</p>
  $ cat dir/js/test.js
  console.log("hello world");

createServerExp is used like the following:

  {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE TemplateHaskell #-}

  type FrontEndAPI = $(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" :> "test.js" :> Get '[JS] ByteString
    :<|> "index.html" :> Get '[HTML] Html

  frontEndServer :: Applicative m => ServerT FrontEndAPI m
  frontEndServer =
         pure "console.log(\"hello world\");"
    :<|> pure "<p>Hello World</p>"

createServerDec Source #


:: String

name of the api type synonym

-> String

name of the server function

-> FilePath

directory name to read files from

-> Q [Dec] 

This is similar to createServerExp, but it creates the whole function declaration.

Given the following code:

  {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE TemplateHaskell #-}

  $(createServerDec "FrontAPI" "frontServer" "dir")

You can think of it as expanding to the following:

  frontServer :: Applicative m => ServerT FrontAPI m
  frontServer = $(createServerExp "dir")