I'm currently trying to implement a simple web server with servant. At the moment, I have a IO (Maybe String)
that I want to expose via a GET endpoint (this might be a database lookup that may or may not return a result, hence IO
and Maybe
). If the Maybe
contains a value, the response should contain this value with a 200 OK response status. If the Maybe
is Nothing
, a 404 Not Found should be returned.
So far I was following the tutorial, which also describes handling errors using throwError
. However, I haven't managed to get it to compile. What I have is the following code:
type MaybeAPI = "maybe" :> Get '[ JSON] String
server :: Server MaybeAPI
server = stringHandler
maybeAPI :: Proxy MaybeAPI
maybeAPI = Proxy
app :: Application
app = serve maybeAPI server
stringHandler :: Handler String
stringHandler = liftIO $ fmap (\s -> (fromMaybe (throwError err404) s)) ioMaybeString
ioMaybeString :: IO (Maybe String)
ioMaybeString = return $ Just "foo"
runServer :: IO ()
runServer = run 8081 app
I know this is probably more verbose than it needs to be, but I guess it can be simplified as soon as it is working. The problem is the stringHandler
, for which the compilation fails with:
No instance for (MonadError ServerError []) arising from a use of ‘throwError’
So my question is: Is this the way to implement such an endpoint in Servant? If so, how can I fix the implementation? My Haskell knowledge is rather limited and I never used throwError
before, so it's entirely possible that I'm missing something here. Any help is appreciated!