If you want to write a web API in Haskell, then you should start by using my
new cookiecutter template at https://github.com/jml/servant-template. It’ll
get you a production-ready web service in 5 minutes or less.
Whenever you start any new web service and you actually care about getting it
working and available to users, it’s very useful to have:
- continuous integration
- command-line parsing
These are largely boring, but nearly essential. Logs and monitoring give you
visibility into the code’s behaviour in production, tests and continuous
integration help you make sure you don’t break it, and, of course, you need
some way of actually shipping code to users. As an engineer who cares deeply
about running code in production, these are pretty much the bare minimum for
me to be able to deploy something to my users.
The cookiecutter template
at gh:jml/servant-template creates
a simple Haskell web API service that does all of these things:
As the name suggests, all of this enables writing
a servant server. Servant
lets you declaring web APIs at the type-level and then using those API
specifications to write servers. It’s hard to overstate just how useful it is
for writing RESTful APIs.
Get started with:
$ cookiecutter gh:jml/servant-template
project_name [awesome-service]: awesome-service
$ cd awesome-service
$ stack test
$ make image
$ docker run awesome-service:latest --help
awesome-service - TODO fill this in
Usage: awesome-service --port PORT [--access-logs ARG] [--log-level ARG]
One line description of project
-h,--help Show this help text
--port PORT Port to listen on
--access-logs ARG How to log HTTP access
--log-level ARG Minimum severity for log messages
--ghc-metrics Export GHC metrics. Requires running with +RTS.
$ docker run -p 8080:80 awesome-service --port 80
[2016-10-16T20:50:07.983292987000] [Informational] Listening on :80
For this to work, you’ll need to have Docker installed on your system. I’ve
tested it on my Mac with Docker Machine,
but haven’t yet with Linux.
You might have to run
stack docker pull before
make image, if you haven’t
stack to build things from within Docker.
Once it’s up and running, you can browse to http://localhost:8080/ (or
http://$(docker-machine ip):8080/) if you’re on a Mac, and you’ll see a simple
HTML page describing the API and giving you a link to the
which is where all the Prometheus metrics are exported.
There you have it, a production-ready web service. At least for some values of “production-ready”.
Of course, the API it offers is really simple. You can make it your own by
API definition and
server implementation to
make it really your own. Note these two are in separate libraries to make it
The template comes with a test suite that uses servant-quickcheck to guarantee
that none of your endpoints return 500s, take longer than 100ms to serve, and
that all the 201s include
If you’re so inclined, you could push the created Docker image to a repository
somewhere—it’s around 25MB when built. Then, people could use it and no one
would have to know that it’s Haskell, they’d just notice a fast web service
As the README
says, I’ve made a few questionable decisions when building this. If you
disagree, or think I could have done anything better
I’d love to know. If you
use this to build something cool, or even something silly, please let me know