I have a working Servant server and now I’d like to test it. The official guide suggests using servant-client
. The example on the home page of servant-client
here has some confusing syntax I’ve never seen before:
-- 'client' allows you to produce operations to query an API from a client.
postNewBook :: Book -> ClientM Book
getAllBooks :: ClientM [Book]
(getAllBooks :<|> postNewBook) = client myApi
I can’t understand how there can be multiple type signatures, followed by a single definition. But if I press on and just mimic the syntax, I can get the code to compile. That is until I include the websockets (ws) part of the API and handler:
type API = ...
:<|> ...
:<|> "api" :> "chat" :> Capture "chatId" Text :> WebSocket
WebSocket
is from the servant-websockets
package here.
I then write the testing code exactly the same way as before:
endpoint1 :: Text -> ClientM Text
endpoint2 :: Int -> ClientM Text
chatHandler :: Text -> ClientM WebSocket
( endpoint1 :<|> endpoint2 :<|> chatHandler ) = client api
But I’m hit with such an error:
• Couldn't match type ‘servant-client-core-0.18.2:Servant.Client.Core.HasClient.Client
ClientM WebSocket’
with ‘ClientM WebSocket’
Expected type: (LetterId -> ClientM LetterMeta)
:<|> ((Letter -> ClientM Text)
:<|> ((Text -> ClientM Text)
:<|> ((Text -> ClientM Text)
:<|> ((EntranceId -> ClientM Text)
:<|> ((SpawnEntranceParams -> ClientM Text)
:<|> (Text -> ClientM WebSocket))))))
Actual type: servant-client-core-0.18.2:Servant.Client.Core.HasClient.Client
ClientM API
Anyone has a clue about the strange syntax, and how to make servant-client
work with websockets?