Skip to content

Instantly share code, notes, and snippets.

@seanhess
Last active March 16, 2016 16:49
Show Gist options
  • Save seanhess/1aa69806430a312936e8 to your computer and use it in GitHub Desktop.
Save seanhess/1aa69806430a312936e8 to your computer and use it in GitHub Desktop.
Servant Method combinator to match routes by method early
-- combinator that returns a mismatch if the method doesn't match
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Servant.Method where
import qualified Network.HTTP.Types as HTTP
import Network.Wai (requestMethod)
import Servant
import Servant.Server.Internal
data GET
data POST
data DELETE
data PUT
data Method a
class ToMethod method where
toMethod :: Proxy method -> HTTP.Method
instance ToMethod GET where
toMethod _ = HTTP.methodGet
instance ToMethod POST where
toMethod _ = HTTP.methodPost
instance ToMethod DELETE where
toMethod _ = HTTP.methodDelete
instance ToMethod PUT where
toMethod _ = HTTP.methodPut
instance (ToMethod method, HasServer api) => HasServer (Method method :> api) where
type ServerT (Method method :> api) m =
ServerT api m
route Proxy api req respond = do
if requestMethod req == toMethod (Proxy :: Proxy method)
then route (Proxy :: Proxy api) api req respond
else respond . failWith $ WrongMethod
type ModelAPI =
"models" :>
( ProjectKey :> Get '[JSON] [Model]
-- Bug in MultipartUpload. Has to be last or it expects EVERYTHING to have multipart uploads
:<|> ProjectKey :> Method POST :> MultipartUpload :> Post '[JSON] Model
:<|> ProjectKey :> Capture "modelID" ID :> Get '[JSON] Model
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment