Last active
March 13, 2016 04:03
-
-
Save nouse/ab3d5ac15558170a0952 to your computer and use it in GitHub Desktop.
Haskell servant swagger example, learnt from https://haskell-servant.github.io/posts/2016-02-06-servant-swagger.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: GistAPI | |
version: 0.1.0.0 | |
synopsis: GistAPI with swagger support | |
description: Please see README.md | |
homepage: https://gist.github.com/nouse/ab3d5ac15558170a0952/edit | |
license: BSD3 | |
author: Jiang Wu | |
copyright: | |
category: Web | |
build-type: Simple | |
cabal-version: >=1.10 | |
executable gistAPI | |
hs-source-dirs: . | |
main-is: Main.hs | |
ghc-options: -threaded -rtsopts -with-rtsopts=-N | |
build-depends: base | |
, aeson | |
, servant-server | |
, servant-swagger | |
, lens | |
, bytestring | |
, unordered-containers | |
, swagger2 | |
, text | |
, time | |
default-language: Haskell2010 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE DeriveGeneric #-} | |
{-# LANGUAGE GeneralizedNewtypeDeriving #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE TypeOperators #-} | |
import Control.Lens | |
import Data.Aeson | |
import Data.Aeson.Types (camelTo) | |
import qualified Data.Aeson.Types as JSON | |
import qualified Data.ByteString.Lazy.Char8 as BL8 | |
import Data.HashMap.Strict (HashMap) | |
import Data.Proxy | |
import Data.Swagger | |
import Data.Text (Text) | |
import Data.Time (UTCTime) | |
import GHC.Generics | |
import Servant | |
import Servant.Swagger | |
type GithubGistAPI | |
= "users" :> Capture "username" Username :> "gists" :> QueryParam "since" UTCTime :> Get '[JSON] [Gist] | |
:<|> "gists" :> GistsAPI | |
type GistsAPI | |
= "public" :> QueryParam "since" UTCTime :> Get '[JSON] [Gist] | |
:<|> "starred" :> QueryParam "since" UTCTime :> Get '[JSON] [Gist] | |
:<|> Capture "id" GistId :> GistAPI | |
type GistAPI | |
= Get '[JSON] [Gist] | |
:<|> Capture "sha" Revision :> Get '[JSON] Gist | |
api :: Proxy GithubGistAPI | |
api = Proxy | |
newtype Username = Username Text deriving (Generic, ToText, FromJSON) | |
newtype GistId = GistId Text deriving (Generic, ToText, FromJSON) | |
newtype SHA = SHA Text deriving (Generic, ToText) | |
type Revision = SHA | |
data Gist = Gist { | |
gistId :: GistId, | |
gistDescription :: Text, | |
gistOwner :: Owner, | |
gistFiles :: HashMap FilePath GistFile, | |
gistTruncated :: Bool, | |
gistComments :: Integer, | |
gistCreatedAt :: UTCTime, | |
gistUpdatedAt :: UTCTime | |
} deriving Generic | |
data OwnerType = User | Organization deriving Generic | |
data Owner = Owner { | |
ownerLogin :: Username, | |
ownerType :: OwnerType, | |
ownerSiteAdmin :: Bool | |
} deriving Generic | |
data GistFile = GistFile { | |
gistfileSize :: Integer, | |
gistfileLaguage :: Text, | |
gistfileRawUrl :: Text | |
} deriving Generic | |
modifier :: String -> String | |
modifier = drop 1 . dropWhile (/= '_') . camelTo '_' | |
prefixOptions :: JSON.Options | |
prefixOptions = JSON.defaultOptions { JSON.fieldLabelModifier = modifier } | |
instance FromJSON OwnerType | |
instance FromJSON Owner where parseJSON = genericParseJSON prefixOptions | |
instance FromJSON GistFile where parseJSON = genericParseJSON prefixOptions | |
instance FromJSON Gist where parseJSON = genericParseJSON prefixOptions | |
prefixSchemaOptions :: SchemaOptions | |
prefixSchemaOptions = defaultSchemaOptions { fieldLabelModifier = modifier } | |
instance ToParamSchema SHA | |
instance ToParamSchema Username | |
instance ToParamSchema GistId | |
instance ToSchema Username | |
instance ToSchema GistId | |
instance ToSchema OwnerType | |
instance ToSchema Owner where declareNamedSchema = genericDeclareNamedSchema prefixSchemaOptions | |
instance ToSchema GistFile where declareNamedSchema = genericDeclareNamedSchema prefixSchemaOptions | |
instance ToSchema Gist where declareNamedSchema = genericDeclareNamedSchema prefixSchemaOptions | |
swaggerDoc1 :: Swagger | |
swaggerDoc1 = toSwagger api | |
genSwaggerDoc1 :: IO () | |
genSwaggerDoc1 = BL8.putStr $ encode swaggerDoc1 | |
swaggerDoc2 :: Swagger | |
swaggerDoc2 = swaggerDoc1 | |
& host ?~ "api.github.com" | |
& info.title .~ "Todo API" | |
& info.version .~ "v3" | |
main :: IO() | |
main = BL8.putStr $ encode swaggerDoc2 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# For more information, see: http://docs.haskellstack.org/en/stable/yaml_configuration.html | |
# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) | |
resolver: lts-5.7 | |
# Local packages, usually specified by relative directory name | |
packages: | |
- '.' | |
# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) | |
extra-deps: | |
- servant-swagger-1.0.3 | |
- swagger2-2.0.2 | |
# Override default flag values for local packages and extra-deps | |
flags: {} | |
# Extra package databases containing global packages | |
extra-package-dbs: [] | |
# Control whether we use the GHC we find on the path | |
# system-ghc: true | |
# Require a specific version of stack, using version ranges | |
# require-stack-version: -any # Default | |
# require-stack-version: >= 1.0.0 | |
# Override the architecture used by stack, especially useful on Windows | |
# arch: i386 | |
# arch: x86_64 | |
# Extra directories used by stack for building | |
# extra-include-dirs: [/path/to/dir] | |
# extra-lib-dirs: [/path/to/dir] | |
# Allow a newer minor version of GHC than the snapshot specifies | |
# compiler-check: newer-minor |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment