servant-snap: A family of combinators for defining webservices APIs and serving them

Interpret a Servant API as a Snap server, using any Snaplets you like.

You can learn about the basics of servant in the Servant tutorial, and about the basics of Snap at the Snaplets tutorial

Here
is a runnable example, with comments, that defines a dummy API and implements
a webserver that serves this API, using this package. One route delegates to the Auth snaplet, another delegates to Heist.

Comparison with servant-server

servant-snap is very similar to servant-server, providing a number of HasServer instances for various servant API combinators and the function serveSnap for turning your API spec into a runnable server.

servant-snap hosts MonadSnap m handlers (for example Snap, Handler b v). servant-server hosts EitherT ServantErr IO handlers and other monads that can be naturally transformed via [enter](http://haskell-servant.readthedocs.io/en/stable/tutorial/Server.html#using-another-monad-for-your-handlers).
This makes servant-snap both a bit more flexible and a bit less type-safe, because servant-snap handlers can access data from the HTTP request. servant-server on the other hand hides the raw request from the handlers so that all routing decisions are determined strictly by the API type.

Snap's Handler b v handlers use lenses and snaplets to control which effects and state the handler can access.
In servant-server, you use [vault](https://hackage.haskell.org/package/servant-0.8.1/docs/Servant-API-Vault.html) to hold these needed bits of state (for example, database connections).

servant-server provides combinators for controlling access to sub-api's. servant-snap still does authentication through the [auth snaplet](https://hackage.haskell.org/package/snap-1.0.0.0/docs/Snap-Snaplet-Auth.html), without signalling this in the API type.
We are still thinking about how to support type-level signalling of auth requirements for servant-snap.
It would be possible to provide snap-specific auth combinators, but using them would force a snap dependency on the API itself, which we want to avoid (it is common to compile a servant API with ghcjs, so we want the API to be packaged without any system dependencies).

FAQ

Can servant-snap serve Heist templates?

You can call renderTemplate in a handler for a Raw endpoint. We don't offer a Heist combinator, but in the future this may be nice to have in another package.

What does Snap offer beyond a regular servant-server application?

Snap has a very simple core, a nice monad for request/response handling, and a large number of stable units of added functionality ("Snaplets") for handling auth, persistence, templating, etc. One of the biggest pain-points of Snap use is manually digging data out of requests, validating it, and building responses. Servant fills this gap for snap perfectly. Read more about the Snap Framework!

If this package is called servant-snap, shouldn't servant-server be named servant-wai? The current naming is confusing.

At some point, we hope to split servant-server into a generic base part and servant-wai, servant-snap, backends. This would make writing other backends easier and drastically reduce code duplication.

More detailed Snap example

Note: It's recommended to use snap init to build a site template for new projects, rather than packing everything into a single file like this.