packages feed

servant-polysemy 0.1.1 → 0.1.2

raw patch · 7 files changed

+101/−3 lines, 7 filesdep +servantnew-component:exe:example-server-genericPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: servant

API changes (from Hackage documentation)

- Paths_servant_polysemy: getBinDir :: IO FilePath
- Paths_servant_polysemy: getDataDir :: IO FilePath
- Paths_servant_polysemy: getDataFileName :: FilePath -> IO FilePath
- Paths_servant_polysemy: getDynLibDir :: IO FilePath
- Paths_servant_polysemy: getLibDir :: IO FilePath
- Paths_servant_polysemy: getLibexecDir :: IO FilePath
- Paths_servant_polysemy: getSysconfDir :: IO FilePath
- Paths_servant_polysemy: version :: Version
- Servant.Polysemy.Client: runClient' :: forall r_aoiK o_Xn1t. (MemberWithError ServantClient r_aoiK, NFData o_Xn1t) => ClientM o_Xn1t -> Sem r_aoiK (Either ClientError o_Xn1t)
+ Servant.Polysemy.Client: runClient' :: forall r_ao68 o_XmMC. (MemberWithError ServantClient r_ao68, NFData o_XmMC) => ClientM o_XmMC -> Sem r_ao68 (Either ClientError o_XmMC)
- Servant.Polysemy.Client: runClientStreaming :: forall r_apgK o_aoiU. MemberWithError ServantClientStreaming r_apgK => ClientM o_aoiU -> Sem r_apgK o_aoiU
+ Servant.Polysemy.Client: runClientStreaming :: forall r_ap4i o_ao6i. MemberWithError ServantClientStreaming r_ap4i => ClientM o_ao6i -> Sem r_ap4i o_ao6i

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for servant-polysemy +## 0.1.2 -- 2021-02-23++* Remove Paths_servant_polysemy from exported modules.+* Add an example of using Servant.API.Generic API types.+ ## 0.1.1 -- 2020-12-11  * Relax constraint on polysemy dependency to allow version 1.5.
README.md view
@@ -7,6 +7,7 @@ Check out these examples for how to use it:  - [Server](https://github.com/AJChapman/servant-polysemy/blob/master/example/Server.hs)+- [Server using Servant.API.Generic](https://github.com/AJChapman/servant-polysemy/blob/master/example/ServerGeneric.hs) - [Server with Swagger docs](https://github.com/AJChapman/servant-polysemy/blob/master/example/ServerWithSwagger.hs) - [Client](https://github.com/AJChapman/servant-polysemy/blob/master/example/Client.hs) 
example/Client.hs view
@@ -11,11 +11,19 @@ import Servant.Client.Streaming (ClientM, client) import Servant.Polysemy.Client (ServantClient, runClient, runServantClient) +{-+This is an example client for connecting to the API defined in each of Server.hs, ServerGeneric.hs, and ServerWithSwagger.hs.+-}++-- This is the same path defined in the server.+-- Typically you would have this in a common place rather than reproducing it here. type MyApi = "api" :> "v1" :> "version" :> Get '[JSON] Version +-- The client is automatically generated from the API type. versionClient :: ClientM Version versionClient = client (Proxy @MyApi) +-- This program runs the client and then handles the response by printing info to stdout. program :: Members '[ServantClient, Embed IO] r => Sem r () program = do   ev <- runClient versionClient & runError@@ -25,6 +33,7 @@     Right v ->       embed $ putStrLn $ "Received version: " <> showVersion v +-- This runs the client, connecting to localhost:8080. main :: IO () main = program   & runServantClient "localhost:8080"
example/Server.hs view
@@ -13,13 +13,21 @@ import Servant import Servant.Polysemy.Server +{-+This is a very simple server with only one endpoint.+-}++-- This is the endpoint, which responds to a GET at /api/v1/version with the server's version in JSON format. type MyApi = "api" :> "v1" :> "version" :> Get '[JSON] Version +-- This is the implementation of the API.+-- It also does some IO to print to the terminal. myServer :: Member (Embed IO) r => ServerT MyApi (Sem (Error ServerError ': r)) myServer = do   embed $ putStrLn $ "Returning version " <> showVersion Paths.version   pure Paths.version +-- This runs Warp (a Haskell web server), serving up our API. main :: IO () main =   runWarpServer @MyApi 8080 True myServer
+ example/ServerGeneric.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DeriveGeneric #-}+module Main (main) where++import Control.Lens.Operators+import Data.Version (Version, showVersion)+import Paths_servant_polysemy as Paths+import Polysemy+import Polysemy.Error+import Servant+import Servant.Polysemy.Server+import Servant.API.Generic (ToServantApi, (:-), Generic)++{-+This example is of the same server as defined in Server.hs, but it uses Servant.API.Generic to define the path.+-}++-- This is the Servant.API.Generic style  of creating an API.+data Routes route = Routes+  { _version :: route :- "api" :> "v1" :> "version" :> Get '[JSON] Version+  } deriving (Generic)++-- This is the endpoint, which responds to a GET at /api/v1/version with the server's version in JSON format.+type MyApi = ToServantApi Routes++-- This is the implementation of the API.+-- It also does some IO to print to the terminal.+myServer :: Member (Embed IO) r => ServerT MyApi (Sem (Error ServerError ': r))+myServer = do+  embed $ putStrLn $ "Returning version " <> showVersion Paths.version+  pure Paths.version++-- This runs Warp (a Haskell web server), serving up our API.+main :: IO ()+main =+  runWarpServer @MyApi 8080 True myServer+    & runM++
example/ServerWithSwagger.hs view
@@ -19,10 +19,21 @@ import Servant.Swagger (toSwagger) import Servant.Swagger.UI (SwaggerSchemaUI, swaggerSchemaUIServer) +{-+This is the same server as in Server.hs, but is self-documenting.+-}++-- The same API type as in Server.hs. type MyApi = "api" :> "v1" :> "version" :> Get '[JSON] Version +-- This API has the swagger docs at /api/v1/swagger-ui type SwaggerDocs = "api" :> "v1" :> SwaggerSchemaUI "swagger-ui" "swagger.json" +-- Now we combine the two APIs into one, and also add redirects:+--   /       -> /api/v1/swagger-ui+--   /api    -> /api/v1/swagger-ui+--   /api/v1 -> /api/v1/swagger-ui+-- The redirects are just to help people find the documentation. type MyApiWithSwagger =   MyApi   :<|> SwaggerDocs@@ -30,11 +41,13 @@   :<|> "api" :> Redirect 302 Text -- Redirect /api to the swagger docs   :<|> Redirect 302 Text -- Redirect / to the swagger docs +-- The same server from Server.hs myServer :: Member (Embed IO) r => ServerT MyApi (Sem (Error ServerError ': r)) myServer = do   embed $ putStrLn $ "Returning version " <> showVersion Paths.version   pure Paths.version +-- The swagger endpoint implementation. mySwagger :: Swagger mySwagger = toSwagger (Proxy @MyApi)   & info.title       .~ "My API"@@ -43,6 +56,7 @@   & info.license     ?~ "Public Domain"   & host             ?~ "localhost:8080" +-- This server adds the Swagger docs and redirects to the 'myServer' implementation. mySwaggerServer :: Member (Embed IO) r => ServerT MyApiWithSwagger (Sem (Error ServerError ': r)) mySwaggerServer =   myServer@@ -51,6 +65,7 @@   :<|> redirect "/api/v1/swagger-ui"   :<|> redirect "/api/v1/swagger-ui" +-- Run 'mySwaggerServer' on port 8080. main :: IO () main =   runWarpServer @MyApiWithSwagger 8080 True mySwaggerServer
servant-polysemy.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                servant-polysemy-version:             0.1.1+version:             0.1.2 synopsis:            Utilities for using servant in a polysemy stack  description:         It's possible to use servant and polysemy together without this library, but it's not easy. This library makes it easy. homepage:         https://github.com/AJChapman/servant-polysemy#readme@@ -15,6 +15,7 @@ extra-source-files:  CHANGELOG.md                      README.md extra-doc-files:     example/Server.hs+                     example/ServerGeneric.hs                      example/ServerWithSwagger.hs                      example/Client.hs tested-with:           GHC == 8.8.4@@ -64,12 +65,12 @@   default-language:    Haskell2010   exposed-modules:     Servant.Polysemy.Client                        Servant.Polysemy.Server-                       Paths_servant_polysemy-  autogen-modules:     Paths_servant_polysemy  executable example-server   import:            deps   main-is:             Server.hs+  autogen-modules:     Paths_servant_polysemy+  other-modules:       Paths_servant_polysemy   hs-source-dirs:      example   default-language:    Haskell2010   ghc-options:       -threaded@@ -78,9 +79,25 @@   build-depends:       servant-polysemy                      , lens +executable example-server-generic+  import:            deps+  main-is:             ServerGeneric.hs+  autogen-modules:     Paths_servant_polysemy+  other-modules:       Paths_servant_polysemy+  hs-source-dirs:      example+  default-language:    Haskell2010+  ghc-options:       -threaded+                     -rtsopts+                     -with-rtsopts=-N+  build-depends:       servant-polysemy+                     , lens+                     , servant+ executable example-server-with-swagger   import:            deps   main-is:             ServerWithSwagger.hs+  autogen-modules:     Paths_servant_polysemy+  other-modules:       Paths_servant_polysemy   hs-source-dirs:      example   default-language:    Haskell2010   ghc-options:       -threaded