Begin freer-servant-client
This commit is contained in:
parent
70aae4c5c0
commit
e7f6be0aa9
15 changed files with 182 additions and 3 deletions
|
@ -1,6 +1,7 @@
|
||||||
packages:
|
packages:
|
||||||
servant/
|
servant/
|
||||||
servant-client/
|
servant-client/
|
||||||
|
freer-servant-client/
|
||||||
servant-docs/
|
servant-docs/
|
||||||
servant-foreign/
|
servant-foreign/
|
||||||
servant-server/
|
servant-server/
|
||||||
|
|
0
freer-servant-client/CHANGELOG.md
Normal file
0
freer-servant-client/CHANGELOG.md
Normal file
0
freer-servant-client/LICENSE
Normal file
0
freer-servant-client/LICENSE
Normal file
0
freer-servant-client/README.md
Normal file
0
freer-servant-client/README.md
Normal file
2
freer-servant-client/Setup.hs
Normal file
2
freer-servant-client/Setup.hs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
import Distribution.Simple
|
||||||
|
main = defaultMain
|
100
freer-servant-client/freer-servant-client.cabal
Normal file
100
freer-servant-client/freer-servant-client.cabal
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
name: freer-servant-client
|
||||||
|
version: 0.1
|
||||||
|
synopsis: automatical derivation of querying functions for servant webservices
|
||||||
|
description:
|
||||||
|
This library lets you derive automatically Haskell functions that
|
||||||
|
let you query each endpoint of a <http://hackage.haskell.org/package/servant servant> webservice.
|
||||||
|
license: BSD3
|
||||||
|
license-file: LICENSE
|
||||||
|
author: Servant Contributors
|
||||||
|
maintainer: haskell-servant-maintainers@googlegroups.com
|
||||||
|
copyright: 2014-2016 Zalora South East Asia Pte Ltd, Servant Contributors
|
||||||
|
category: Servant Web
|
||||||
|
build-type: Simple
|
||||||
|
cabal-version: >=1.10
|
||||||
|
tested-with: GHC >= 7.8
|
||||||
|
homepage: http://haskell-servant.readthedocs.org/
|
||||||
|
Bug-reports: http://github.com/haskell-servant/servant/issues
|
||||||
|
extra-source-files:
|
||||||
|
include/*.h
|
||||||
|
CHANGELOG.md
|
||||||
|
README.md
|
||||||
|
source-repository head
|
||||||
|
type: git
|
||||||
|
location: http://github.com/haskell-servant/servant.git
|
||||||
|
|
||||||
|
library
|
||||||
|
exposed-modules:
|
||||||
|
Servant.FreerClient
|
||||||
|
build-depends:
|
||||||
|
base >= 4.7 && < 4.11
|
||||||
|
, base-compat >= 0.9.1 && < 0.10
|
||||||
|
, aeson >= 0.7 && < 1.3
|
||||||
|
, attoparsec >= 0.12 && < 0.14
|
||||||
|
, base64-bytestring >= 1.0.0.1 && < 1.1
|
||||||
|
, bytestring >= 0.10 && < 0.11
|
||||||
|
, containers >= 0.5.7.1
|
||||||
|
, exceptions >= 0.8 && < 0.9
|
||||||
|
, freer-effects == 0.3.*
|
||||||
|
, generics-sop >= 0.1.0.0 && < 0.4
|
||||||
|
, http-api-data >= 0.3.6 && < 0.4
|
||||||
|
, http-client >= 0.4.18.1 && < 0.6
|
||||||
|
, http-client-tls >= 0.2.2 && < 0.4
|
||||||
|
, http-media >= 0.6.2 && < 0.7
|
||||||
|
, http-types >= 0.8.6 && < 0.10
|
||||||
|
, monad-control >= 1.0.0.4 && < 1.1
|
||||||
|
, network-uri >= 2.6 && < 2.7
|
||||||
|
, safe >= 0.3.9 && < 0.4
|
||||||
|
, semigroupoids >= 4.3 && < 5.3
|
||||||
|
, servant == 0.11.*
|
||||||
|
, servant-client == 0.11.*
|
||||||
|
, string-conversions >= 0.3 && < 0.5
|
||||||
|
, text >= 1.2 && < 1.3
|
||||||
|
, transformers >= 0.3 && < 0.6
|
||||||
|
, transformers-base >= 0.4.4 && < 0.5
|
||||||
|
, transformers-compat >= 0.4 && < 0.6
|
||||||
|
, mtl
|
||||||
|
, freer-http
|
||||||
|
if !impl(ghc >= 8.0)
|
||||||
|
build-depends:
|
||||||
|
semigroups >=0.16.2.2 && <0.19
|
||||||
|
hs-source-dirs: src
|
||||||
|
default-language: Haskell2010
|
||||||
|
ghc-options: -Wall
|
||||||
|
if impl(ghc >= 8.0)
|
||||||
|
ghc-options: -Wno-redundant-constraints
|
||||||
|
include-dirs: include
|
||||||
|
|
||||||
|
test-suite spec
|
||||||
|
type: exitcode-stdio-1.0
|
||||||
|
ghc-options: -Wall
|
||||||
|
default-language: Haskell2010
|
||||||
|
hs-source-dirs: test
|
||||||
|
main-is: Spec.hs
|
||||||
|
other-modules:
|
||||||
|
Servant.ClientSpec
|
||||||
|
, Servant.Common.BaseUrlSpec
|
||||||
|
build-depends:
|
||||||
|
base == 4.*
|
||||||
|
, aeson
|
||||||
|
, base-compat
|
||||||
|
, bytestring
|
||||||
|
, deepseq
|
||||||
|
, hspec == 2.*
|
||||||
|
, http-api-data
|
||||||
|
, http-client
|
||||||
|
, http-media
|
||||||
|
, http-types
|
||||||
|
, HUnit
|
||||||
|
, mtl
|
||||||
|
, network >= 2.6
|
||||||
|
, QuickCheck >= 2.7
|
||||||
|
, servant
|
||||||
|
, servant-client
|
||||||
|
, servant-server == 0.11.*
|
||||||
|
, text
|
||||||
|
, transformers
|
||||||
|
, transformers-compat
|
||||||
|
, wai
|
||||||
|
, warp
|
||||||
|
, generics-sop
|
69
freer-servant-client/src/Servant/FreerClient.hs
Normal file
69
freer-servant-client/src/Servant/FreerClient.hs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
{-# LANGUAGE GADTs #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
{-# LANGUAGE TypeOperators #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE PartialTypeSignatures #-}
|
||||||
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
|
||||||
|
module Servant.FreerClient where
|
||||||
|
|
||||||
|
import Control.Exception (toException)
|
||||||
|
import Control.Monad.Freer
|
||||||
|
import Control.Monad.Freer.Exception
|
||||||
|
import Control.Monad.Freer.Http
|
||||||
|
import Control.Monad.Freer.Reader
|
||||||
|
import Data.ByteString.Lazy hiding (pack, filter, map, null, elem, any)
|
||||||
|
import Data.String.Conversions (cs)
|
||||||
|
import Network.HTTP.Client (Response)
|
||||||
|
import Network.HTTP.Types
|
||||||
|
import Network.HTTP.Media
|
||||||
|
import Servant.Common.Req hiding (ClientM, runClientM')
|
||||||
|
|
||||||
|
import qualified Network.HTTP.Client as Client
|
||||||
|
import qualified Network.HTTP.Types.Header as HTTP
|
||||||
|
|
||||||
|
newtype ClientM r a = ClientM { runClientM' :: ( Member (Reader ClientEnv) r
|
||||||
|
, Member (Exc ServantError) r
|
||||||
|
, Member Http r) => (Eff r) a }
|
||||||
|
|
||||||
|
instance Functor (ClientM r) where
|
||||||
|
fmap f a = ClientM $ fmap f (runClientM' a)
|
||||||
|
|
||||||
|
instance Applicative (ClientM r) where
|
||||||
|
pure a = ClientM $ pure a
|
||||||
|
f <*> a = ClientM $ (runClientM' f) <*> (runClientM' a)
|
||||||
|
|
||||||
|
instance Monad (ClientM r) where
|
||||||
|
a >>= f = ClientM $ (runClientM' a) >>= (runClientM' . f)
|
||||||
|
|
||||||
|
performRequest :: ( Member Http r
|
||||||
|
, Member (Reader ClientEnv) r
|
||||||
|
, Member (Exc ServantError) r)
|
||||||
|
=> Method -> Req -> ClientM r ( Int, ByteString, MediaType
|
||||||
|
, [HTTP.Header], Response ByteString)
|
||||||
|
performRequest reqMethod req = ClientM $ do
|
||||||
|
m <- asks manager
|
||||||
|
reqHost <- asks baseUrl
|
||||||
|
response <- case (reqToRequest req reqHost) of
|
||||||
|
Left some -> throwError . ConnectionError $ toException some
|
||||||
|
Right request -> doRequest request
|
||||||
|
let status = Client.responseStatus response
|
||||||
|
body = Client.responseBody response
|
||||||
|
hdrs = Client.responseHeaders response
|
||||||
|
status_code = statusCode status
|
||||||
|
ct <- case lookup "Content-Type" $ Client.responseHeaders response of
|
||||||
|
Nothing -> pure $ "application"//"octet-stream"
|
||||||
|
Just t -> case parseAccept t of
|
||||||
|
Nothing -> throwError $ InvalidContentTypeHeader (cs t) body
|
||||||
|
Just t' -> pure t'
|
||||||
|
return (status_code, body, ct, hdrs, response)
|
||||||
|
|
||||||
|
runClientM :: ClientM ('[ Reader ClientEnv
|
||||||
|
, Exc ServantError
|
||||||
|
, Http
|
||||||
|
, IO]) a -> ClientEnv -> IO (Either ServantError a)
|
||||||
|
runClientM cm ce@ClientEnv { manager = mgr } =
|
||||||
|
runM . (runHttp mgr) . runError . (flip runReader ce) $ runClientM' cm
|
0
freer-servant-client/test/Spec.hs
Normal file
0
freer-servant-client/test/Spec.hs
Normal file
|
@ -47,7 +47,7 @@ library
|
||||||
, http-api-data >= 0.3.6 && < 0.4
|
, http-api-data >= 0.3.6 && < 0.4
|
||||||
, http-client >= 0.4.18.1 && < 0.6
|
, http-client >= 0.4.18.1 && < 0.6
|
||||||
, http-client-tls >= 0.2.2 && < 0.4
|
, http-client-tls >= 0.2.2 && < 0.4
|
||||||
, http-media >= 0.6.2 && < 0.8
|
, http-media >= 0.6.2 && < 0.7
|
||||||
, http-types >= 0.8.6 && < 0.10
|
, http-types >= 0.8.6 && < 0.10
|
||||||
, monad-control >= 1.0.0.4 && < 1.1
|
, monad-control >= 1.0.0.4 && < 1.1
|
||||||
, network-uri >= 2.6 && < 2.7
|
, network-uri >= 2.6 && < 2.7
|
||||||
|
|
|
@ -64,7 +64,7 @@ library
|
||||||
, bytestring >= 0.10 && < 0.11
|
, bytestring >= 0.10 && < 0.11
|
||||||
, case-insensitive >= 1.2 && < 1.3
|
, case-insensitive >= 1.2 && < 1.3
|
||||||
, http-api-data >= 0.3 && < 0.4
|
, http-api-data >= 0.3 && < 0.4
|
||||||
, http-media >= 0.4 && < 0.8
|
, http-media >= 0.4 && < 0.7
|
||||||
, http-types >= 0.8 && < 0.10
|
, http-types >= 0.8 && < 0.10
|
||||||
, natural-transformation >= 0.4 && < 0.5
|
, natural-transformation >= 0.4 && < 0.5
|
||||||
, mtl >= 2.0 && < 2.3
|
, mtl >= 2.0 && < 2.3
|
||||||
|
|
|
@ -2,6 +2,7 @@ flags: {}
|
||||||
packages:
|
packages:
|
||||||
- servant/
|
- servant/
|
||||||
- servant-client/
|
- servant-client/
|
||||||
|
- freer-servant-client/
|
||||||
- servant-docs/
|
- servant-docs/
|
||||||
- servant-foreign/
|
- servant-foreign/
|
||||||
- servant-server/
|
- servant-server/
|
||||||
|
|
|
@ -2,6 +2,7 @@ flags: {}
|
||||||
packages:
|
packages:
|
||||||
- servant/
|
- servant/
|
||||||
- servant-client/
|
- servant-client/
|
||||||
|
- freer-servant-client/
|
||||||
- servant-docs/
|
- servant-docs/
|
||||||
- servant-foreign/
|
- servant-foreign/
|
||||||
- servant-server/
|
- servant-server/
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
resolver: ghc-8.2.0.20170507
|
resolver: ghc-8.2.0.20170507
|
||||||
packages:
|
packages:
|
||||||
- servant-client/
|
- servant-client/
|
||||||
|
- freer-servant-client/
|
||||||
- servant-docs/
|
- servant-docs/
|
||||||
- servant-foreign/
|
- servant-foreign/
|
||||||
- servant-server/
|
- servant-server/
|
||||||
|
|
|
@ -2,14 +2,18 @@ resolver: nightly-2017-04-01
|
||||||
packages:
|
packages:
|
||||||
- servant/
|
- servant/
|
||||||
- servant-client/
|
- servant-client/
|
||||||
|
- freer-servant-client/
|
||||||
- servant-docs/
|
- servant-docs/
|
||||||
- servant-foreign/
|
- servant-foreign/
|
||||||
- servant-server/
|
- servant-server/
|
||||||
- doc/tutorial
|
- doc/tutorial
|
||||||
|
- location:
|
||||||
|
git: git@gitlab.com:costar-astrology/freer-http.git
|
||||||
|
commit: 23310fb0d4d91197a2c6cda071e9f5fb6fe34fcc
|
||||||
|
extra-dep: true
|
||||||
extra-deps:
|
extra-deps:
|
||||||
- aeson-1.2.0.0
|
- aeson-1.2.0.0
|
||||||
- attoparsec-iso8601-1.0.0.0
|
- attoparsec-iso8601-1.0.0.0
|
||||||
- http-media-0.7.0
|
|
||||||
- cabal-doctest-1.0.2
|
- cabal-doctest-1.0.2
|
||||||
- http-api-data-0.3.7
|
- http-api-data-0.3.7
|
||||||
- servant-js-0.9.3
|
- servant-js-0.9.3
|
||||||
|
|
Loading…
Reference in a new issue