I am trying to figure out how to add a CORS response header to Servant (basically setting the response header to "Access-Control-Allow-Origin: *"). I wrote a small test case below with the addHeader function, but it is wrong. I will be grateful for the help in finding out the error below.
code:
{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE OverloadedStrings #-} module Main where import Data.Aeson import GHC.Generics import Network.Wai import Servant import Network.Wai.Handler.Warp (run) import Control.Monad.Trans.Either import Control.Monad.IO.Class (liftIO) import Control.Monad (when, (<$!>)) import Data.Text as T import Data.Configurator as C import Data.Maybe import System.Exit (exitFailure) data User = User { name :: T.Text , password :: T.Text } deriving (Eq, Show, Generic) instance ToJSON User instance FromJSON User type Token = T.Text type UserAPI = "grant" :> ReqBody '[JSON] User :> Post '[JSON] (Headers '[Header "Access-Control-Allow-Origin" T.Text] Token) userAPI :: Proxy UserAPI userAPI = Proxy authUser :: User -> Bool authUser u = case (password u) of "somepass" -> True _ -> False server :: Server UserAPI server = users where users :: User -> EitherT ServantErr IO Token users u = case (authUser u) of True -> return $ addHeader "*" $ ("ok" :: Token) False -> return $ addHeader "*" $ ("notok" :: Token) app :: Application app = serve userAPI server main :: IO () main = run 8081 app
This is the error I get:
src/Test.hs:43:10: Couldn't match type 'Headers '[Header "Access-Control-Allow-Origin" Text] Text' with 'Text' Expected type: Server UserAPI Actual type: User -> EitherT ServantErr IO Token In the expression: users In an equation for 'server': server = users where users :: User -> EitherT ServantErr IO Token users u = case (authUser u) of { True -> return $ addHeader "*" $ ("something" :: Token) False -> return $ addHeader "*" $ ("something" :: Token) } src/Test.hs:46:28: Couldn't match type 'Text' with 'Headers '[Header h v0] Text' In the expression: addHeader "*" In the second argument of '($)', namely 'addHeader "*" $ ("something" :: Token)' In the expression: return $ addHeader "*" $ ("something" :: Token) src/Test.hs:47:29: Couldn't match type 'Text' with 'Headers '[Header h1 v1] Text' In the expression: addHeader "*" In the second argument of '($)', namely 'addHeader "*" $ ("something" :: Token)' In the expression: return $ addHeader "*" $ ("something" :: Token)
I have a working version with a simpler API (simple GET ) where it works. But, for the UserAPI above type, it is erroneous. addHeader type of the function seems to agree with the type signature, as I think of it. I definitely missed something here, or it wonβt fail in this way.
source share