Search code examples
haskellservant

Combine two Servant Servers


According to Servant's manual https://haskell-servant.readthedocs.io/en/master/tutorial/Server.html a very simple Server can be created that way:

type UserAPI1 = "users" :> Get '[JSON] [User]

server1 :: Server UserAPI1
server1 = return users1

userAPI :: Proxy UserAPI1
userAPI = Proxy

I noticed, that I it doable to keep API parts separated and combine them together later on, e.g.

type ClientAPI = 
    "users" :> Get '[HTML] (Html ()) 

type ServerAPI = 
    "users" :> Get '[JSON] [User] 
-- works fine
type API = ("api" :> ServerAPI) :<|> ClientAPI

Can I do the same with Server values ? I can't find an easy way to join two "servers" together:

clientAPI :: Server ClientAPI
clientAPI = usersView 

serverAPI :: Server ServerAPI
serverAPI = fetchUsers

api :: Server API
-- doesn't work - is there a way to combine two servers together ?
api = clientAPI + serverAPI

Solution

  • Yes, the (:<|>) combinator that you use to combine your different API routes at the type level also works at the value level for combining handlers.

    See the Hackage docs and Servant tutorial

    So simply replace the + in your api with :<|> and you should be good to go.

    EDIT: Except that order matters. The handlers in the value representing your server must be in the same order as the different routes in the type-level API declaration. So it should work if you define api = serverAPI :<|> clientAPI.