packages feed

servant-effectful-1.0.0: src/Effectful/Servant.hs

{-# LANGUAGE Trustworthy #-}

-- |
-- Module      : Effectful.servant
-- Copyright   : (c) 2026 Institute for Digital Autonomy
-- License     : EUPL-1.2
-- Maintainer  : IDA
--
-- This library provides @<http://hackage.haskell.org/package/servant-server servant-server>@
-- runners built on top of @<http://hackage.haskell.org/package/wai-effectful wai-effectful>@.
--
-- Servant and Effectful use the @:>@ type operator for different purposes.
-- This library introduces the ':/' operator as an alias to Servant's ':>' operator.
--
-- = Example usage
--
-- Define your API using standard Servant types.
-- Note the use of the ':/' type operator instead of Servant's ':>':
--
-- > type API = NamedRoutes NamedAPI
-- >
-- > data NamedAPI (mode :: Type) = NamedAPI
-- >     { helloAPI :: mode :- NamedRoutes HelloAPI
-- >     , handleCount :: mode :- "count" :/ Get '[JSON] Int
-- >     }
-- >     deriving stock (Generic)
-- >
-- > data HelloAPI (mode :: Type) = HelloAPI
-- >     { hello :: mode :- Get '[PlainText] String
-- >     , namedHello :: mode :- Capture "name" String :/ Get '[PlainText] String
-- >     }
-- >     deriving stock (Generic)
--
-- Use the 'Handler' type to implement handlers.
-- Note the use of the ':>' type operator for effects:
--
-- > server :: forall es. (State Int :> es) => NamedAPI (AsServer es)
-- > server =
-- >     NamedAPI
-- >         { helloAPI = HelloAPI{..}
-- >         , handleCount = State.get
-- >         }
-- >   where
-- >     hello :: Handler es String
-- >     hello = State.modify @Int succ >> pure "Hello!"
-- >
-- >     namedHello :: String -> Handler es String
-- >     namedHello "teapot" = throwError err418
-- >     namedHello name = do
-- >         State.modify @Int succ
-- >         pure $ "Hello, " <> name <> "!"
--
-- Call one of the 'serve' functions to convert the server to a wai 'Application':
--
-- > app :: (IOE :> es) => Application es
-- > app = serve @API Proxy server
--
-- Finally, run the 'Application' using
-- @<http://hackage.haskell.org/package/warp-effectful warp-effectful>@:
--
-- > main :: IO ()
-- > main = runEff . Warp.run 3000 $ app
module Effectful.Servant
    ( -- * Defining APIs
      module Effectful.Servant.API

      -- * Implementing servers for APIs
    , module Effectful.Servant.Server

      -- * Serving static files
    , module Effectful.Servant.Server.StaticFiles

      -- * Useful re-exports
    , module Data.Proxy
    , module Effectful.Error.Static
    )
where

import Data.Proxy (Proxy (..))
import Effectful.Error.Static (throwError)
import Effectful.Servant.API
import Effectful.Servant.Server
import Effectful.Servant.Server.StaticFiles