Skip to content

Instantly share code, notes, and snippets.

@maurges
Created April 14, 2020 09:17
Show Gist options
  • Select an option

  • Save maurges/c573b04b6868a33ecc079e7178dce2ce to your computer and use it in GitHub Desktop.

Select an option

Save maurges/c573b04b6868a33ecc079e7178dce2ce to your computer and use it in GitHub Desktop.
A simple servant app with redirects; also different content-types
{-# LANGUAGE DataKinds, DeriveGeneric, PolyKinds, TypeFamilies, TypeOperators #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Main where
import Data.ByteString.Lazy (ByteString)
import Data.Proxy (Proxy (Proxy))
import Data.Text (Text)
import Network.HTTP.Media.MediaType ((//))
import Servant ( (:>), Capture, ReqBody, Get, PlainText, Server, serve
, (:<|>)((:<|>)) -- daaaaammnnn
)
import Servant.API.Header (Header)
import Servant.API.ResponseHeaders (Headers, addHeader)
import Servant.API.ContentTypes (Accept, contentType, MimeRender, mimeRender)
import Servant.API.Verbs (Verb, StdMethod (GET))
import Network.Wai.Handler.Warp (runSettings, setPort, defaultSettings)
data ImagePng
instance Accept ImagePng where
contentType _ = "image" // "png"
instance MimeRender ImagePng ByteString where
mimeRender _ s = s
instance MimeRender PlainText () where
mimeRender _ _ = ""
type GetImage = Get '[ImagePng] ByteString
type MovedTemp = Verb GET 302 '[PlainText] (Headers '[Header "Location" Text] ())
type MovedPerm = Verb GET 301 '[PlainText] (Headers '[Header "Location" Text] ())
type Api =
"" :> Get '[PlainText] Text
:<|> "base" :> Get '[PlainText] Text
:<|> "i.base.jpg" :> GetImage
:<|> "i.base.png" :> GetImage
:<|> "bad" :> Get '[PlainText] Text
:<|> "i.bad.jpg" :> MovedPerm
:<|> "i.bad.png" :> MovedPerm
:<|> "nonex" :> Get '[PlainText] Text
:<|> "i.nonex.jpg" :> MovedTemp
:<|> "i.nonex.png" :> MovedTemp
api :: Proxy Api
api = Proxy
apiServer :: Server Api
apiServer = getRoot :<|> getBase :<|> getBaseJpg :<|> getBasePng
:<|> getBad :<|> getBadJpg :<|> getBadPng
:<|> getNonex :<|> getNonexJpg :<|> getNonexPng where
getRoot = pure "hello"
getBase = pure "base"
getBaseJpg = pure "base.jpg"
getBasePng = pure "base.png"
getBad = pure "bad image: a gallery for ex"
getBadJpg = pure $ addHeader "http://localhost:9999/bad" ()
getBadPng = pure $ addHeader "http://localhost:9999/bad" ()
getNonex = pure "image doesn't exist"
getNonexJpg = pure $ addHeader "http://localhost:9999/nonex" ()
getNonexPng = pure $ addHeader "http://localhost:9999/nonex" ()
main :: IO ()
main = runSettings settings (serve api apiServer) where
settings = setPort 9999
$ defaultSettings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment