2

I'm having a little bit of trouble using Servant with the MongoDB library. I am pretty new to Haskell and Servant, so I suspect my technique is wrong. I have two endpoints one to fetch a [Event] and one to create a new Event. So the two signatures are:

handleNewEvent :: Event -> Handler PostResult
handleListEvents :: Handler [Event]

Similar to examples in Postgres, I have added a database connection to my server. By running something like this:

db :: MonadIO m => Action m a -> m a
let db = access pipe master dbName

run port $ serve api $ server db

So now I can create a server function:

server :: MonadIO m => (Action m a -> m a) -> Server API                              
server runAction = handleFindEvents runAction :<|> handleNewEvent runAction

My problem is I need the runAction function to be Action IO () -> IO () in handleNewEvent but Action IO [Event] -> IO [Event] in handleListEvent. I suspect I'm approaching the problem from the wrong perspective (this would be how I would tackle the problem in another language). How is this meant to work using Servant? For reference here are my handler functions. I hardcoded the list handler to ensure the code compiles and runs.

newEvent :: DBContext -> Event -> Handler PostResult           
newEvent context event = do                                    
    liftIO $ context $ insert_ "events" $ toBson event         
    return $ PostResult { message = "success" , success = True}
                                                               
findEvents :: DBContext  -> Handler [Event]                    
findEvents run = return [Event "example" "event"]                  
BBS
  • 1,351
  • 2
  • 12
  • 27
  • 2
    Does it help if you declare `server` as `server :: MonadIO m => (forall a. Action m a -> m a) -> Server API` (requires `-XRank2Types` or `-XRankNTypes`)? – Mark Seemann Jul 03 '20 at 05:38
  • @MarkSeemann that got me to a program that compiles and appears to work. I had to omit the type constraint (I think that's what it is) of MonadIO. My signature now looks like `server :: (forall a. Action IO a -> IO a) -> Server API`. Thanks! – BBS Jul 03 '20 at 22:05

0 Answers0