-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
141 additions
and
147 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module Main where | ||
|
||
import Network.Wai.Handler.Warp | ||
import Servant | ||
import Todo | ||
|
||
main :: IO () | ||
main = do | ||
putStrLn "Running on port 8000" | ||
run 8000 $ serve (Proxy :: Proxy API) server | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE DeriveGeneric #-} | ||
{-# LANGUAGE GeneralizedNewtypeDeriving #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
{-# LANGUAGE TypeOperators #-} | ||
module Todo where | ||
|
||
import Control.Lens | ||
import Data.Aeson | ||
import Data.Proxy | ||
import Data.Text (Text) | ||
import Data.Time (UTCTime(..), fromGregorian) | ||
import Data.Typeable | ||
import Data.Swagger | ||
import GHC.Generics | ||
import Servant | ||
import Servant.Swagger | ||
|
||
todoAPI :: Proxy TodoAPI | ||
todoAPI = Proxy | ||
|
||
-- | The API of a Todo service. | ||
type TodoAPI | ||
= "todo" :> Get '[JSON] [Todo] | ||
:<|> "todo" :> ReqBody '[JSON] Todo :> Post '[JSON] TodoId | ||
:<|> "todo" :> Capture "id" TodoId :> Get '[JSON] Todo | ||
:<|> "todo" :> Capture "id" TodoId :> ReqBody '[JSON] Todo :> Put '[JSON] TodoId | ||
|
||
-- | API for serving @swagger.json@. | ||
type SwaggerAPI = "swagger.json" :> Get '[JSON] Swagger | ||
|
||
-- | Combined API of a Todo service with Swagger documentation. | ||
type API = SwaggerAPI :<|> TodoAPI | ||
|
||
-- | A single Todo entry. | ||
data Todo = Todo | ||
{ created :: UTCTime -- ^ Creation datetime. | ||
, summary :: Text -- ^ Task summary. | ||
} deriving (Show, Generic, Typeable) | ||
|
||
-- | A unique Todo entry ID. | ||
newtype TodoId = TodoId Int | ||
deriving (Show, Generic, Typeable, ToJSON, FromText) | ||
|
||
instance ToJSON Todo | ||
instance FromJSON Todo | ||
|
||
instance ToSchema Todo where | ||
declareNamedSchema proxy = genericDeclareNamedSchema defaultSchemaOptions proxy | ||
& mapped.schema.description ?~ "This is some real Todo right here" | ||
& mapped.schema.example ?~ toJSON (Todo (UTCTime (fromGregorian 2015 12 31) 0) "get milk") | ||
|
||
instance ToParamSchema TodoId | ||
instance ToSchema TodoId | ||
|
||
-- | Swagger spec for Todo API. | ||
todoSwagger :: Swagger | ||
todoSwagger = toSwagger todoAPI | ||
& info.title .~ "Todo API" | ||
& info.version .~ "1.0" | ||
& info.description ?~ "This is an API that tests swagger integration" | ||
& info.license ?~ ("MIT" & url ?~ URL "http://mit.com") | ||
|
||
-- | Combined server of a Todo service with Swagger documentation. | ||
server :: Server API | ||
server = return todoSwagger :<|> error "not implemented" | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"swagger":"2.0","info":{"version":"1.0","title":"Todo API","license":{"url":"http://mit.com","name":"MIT"},"description":"This is an API that tests swagger integration"},"definitions":{"Todo":{"example":{"summary":"get milk","created":"2015-12-31T00:00:00.000000000000Z"},"required":["created","summary"],"type":"object","description":"This is some real Todo right here","properties":{"summary":{"type":"string"},"created":{"$ref":"#/definitions/UTCTime"}}},"UTCTime":{"format":"yyyy-mm-ddThh:MM:ssZ","type":"string"},"TodoId":{"maximum":9223372036854775807,"minimum":-9223372036854775808,"type":"integer"}},"paths":{"/todo/{id}":{"get":{"responses":{"404":{"description":"`id` not found"},"200":{"schema":{"$ref":"#/definitions/Todo"},"description":""}},"produces":["application/json"],"parameters":[{"maximum":9223372036854775807,"minimum":-9223372036854775808,"required":true,"in":"path","name":"id","type":"integer"}]},"put":{"consumes":["application/json"],"responses":{"404":{"description":"`id` not found"},"400":{"description":"Invalid `body`"},"200":{"schema":{"$ref":"#/definitions/TodoId"},"description":""}},"produces":["application/json"],"parameters":[{"maximum":9223372036854775807,"minimum":-9223372036854775808,"required":true,"in":"path","name":"id","type":"integer"},{"required":true,"schema":{"$ref":"#/definitions/Todo"},"in":"body","name":"body"}]}},"/todo":{"post":{"consumes":["application/json"],"responses":{"400":{"description":"Invalid `body`"},"201":{"schema":{"$ref":"#/definitions/TodoId"},"description":""}},"produces":["application/json"],"parameters":[{"required":true,"schema":{"$ref":"#/definitions/Todo"},"in":"body","name":"body"}]},"get":{"responses":{"200":{"schema":{"items":{"$ref":"#/definitions/Todo"},"type":"array"},"description":""}},"produces":["application/json"]}}}} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{-# OPTIONS_GHC -F -pgmF hspec-discover #-} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{-# OPTIONS_GHC -fno-warn-orphans #-} | ||
module TodoSpec where | ||
|
||
import Data.Aeson | ||
import qualified Data.ByteString.Lazy.Char8 as BL8 | ||
import Servant.Swagger.Test | ||
import Test.Hspec | ||
import Test.QuickCheck | ||
import Test.QuickCheck.Instances () | ||
import Todo | ||
import Paths_example | ||
|
||
spec :: Spec | ||
spec = describe "Swagger" $ do | ||
context "ToJSON matches ToSchema" $ validateEveryToJSON todoAPI | ||
it "swagger.json is up-to-date" $ do | ||
path <- getDataFileName "swagger.json" | ||
swag <- eitherDecode <$> BL8.readFile path | ||
swag `shouldBe` Right todoSwagger | ||
|
||
instance Arbitrary Todo where | ||
arbitrary = Todo <$> arbitrary <*> arbitrary | ||
|
||
instance Arbitrary TodoId where | ||
arbitrary = TodoId <$> arbitrary |