Skip to content

Docs explaining how to actually create a full combinator (ex. one to create/store a DB connection) #704

@t3hmrman

Description

@t3hmrman

I've been stuck on this for a while and would appreciate some help/someone to enshrine how to do this axiomatically in Servant. All I'm trying to do is add a DB connection that goes along with the request. In trying to avoid global state, there are only a few places such a resource can go, namely:

  1. Vault (literally on the request)
  2. App Context (inside servant app machinery)

Making a warp middleware to do (1) was pretty easy and intuitive. Then came the problem of storing the lookup key to the vault (which seems to require (2) ). At this point I tried to do it axiomatically within servant, and do (2) outright -- creating a combinator that supplies the a "backend".

So far what I have is:

-- Servant combinator for including the database handler in subsequent requests                                                                                                                                                                                                   
data WithBackend a
    deriving Typeable

instance (HasContextEntry context a, Backend a, HasServer api context) => HasServer (WithBackend a :> api) context where
    type ServerT (WithBackend a :> api) m = ServerT api m

    route Proxy ctx subserver = route api ctx subserver
        where
          api = (Proxy :: Proxy api)

This example is a combinator that doesn't do anything (just uses the sub server) -- however, when I change the type ServerT to a -> ServerT api m, the types stop matching up and it's unclear what to do next. I could modify the context and use the modified context, but I was hoping to be able to make my handlers of type SqliteBackend -> Handler x for example, with this combinator being the thing to add the backend.

I haven't been able to find any explanation of how to do this, everyone handwaves it and says it would be easy, but I'm finding it very difficult. I found the documentation easy to follow but an explanation of HasServer and how to roll your own NON-AUTH combinators might make it perfect.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions