Compare commits

...

52 Commits
master ... 0.4

Author SHA1 Message Date
Julian K. Arni 3e91a24e4c Lower upper bound for base 2016-02-19 16:28:58 +01:00
Julian K. Arni 1862b77a32 Bump to 0.4.4.7.
For aeson version bump.
2016-02-19 15:34:34 +01:00
Julian Arni 9d6dd2996f Merge pull request #386 from ondrap/0.4
Bump aeson version.
2016-02-19 15:30:43 +01:00
Ondrej Palkovsky becc013002 Bump aeson version. 2016-02-18 22:48:51 +01:00
Julian K. Arni bf47b2d86f Bump to 0.4.4.6. 2016-01-04 19:15:37 +01:00
Julian K. Arni 230f51bf22 Bump wai and warp upper bound to < 3.3.
Conflicts:
	servant-mock/servant-mock.cabal
	servant-server/servant-server.cabal
2016-01-04 18:39:58 +01:00
Julian K. Arni 9c35e21fd1 Fix -cassava version bound 2015-11-04 16:36:45 -05:00
Julian K. Arni 9cea7902df Add servant-cassava. 2015-11-04 15:53:53 -05:00
Julian K. Arni f525f5b14f Bump version to 0.4.4.5. 2015-10-13 21:50:18 +02:00
Julian K. Arni 9ad82654da Bump upper bound for http-types.
Conflicts:
	servant-server/servant-server.cabal
2015-10-13 21:18:12 +02:00
Julian Arni 5568d14eef Merge pull request #246 from ericnething/0.4
added status code 202 to servant-client POST responses
2015-10-07 13:50:34 +02:00
Eric Nething c83ec084b3 added status code 202 to servant-client POST responses 2015-10-04 20:58:38 -04:00
Julian K. Arni 363f8c48fe Version bump to 0.4.4.4. 2015-09-23 16:32:11 +02:00
Julian K. Arni 6adecc9d09 Changelog for 0.4.3. 2015-09-23 16:31:42 +02:00
Julian Arni 4e28a45da4 Merge pull request #235 from haskell-servant/jkarni/0.4-fixes
Werror fixes
2015-09-23 16:29:17 +02:00
Julian K. Arni c60588ade1 Make no-warn-missing-methods a test-all flag. 2015-09-23 15:48:41 +02:00
Julian K. Arni 48c2cc638a Loads of Werror fixes 2015-09-23 15:18:32 +02:00
Julian K. Arni fe8408e272 no-warn-missing-methods for 0.10 ToJSON 2015-09-23 14:33:59 +02:00
Julian K. Arni 397db6b4b5 Explict imports 2015-09-23 13:31:49 +02:00
Julian K. Arni ef3cf9f757 Another Day instance removed 2015-09-23 12:11:14 +02:00
Julian K. Arni afc0f31f91 Use aeson's Day instance 2015-09-23 11:58:02 +02:00
Julian K. Arni 162f5bbd9c Bump version to 0.4.4.3.
For aeson version bump.
2015-09-23 11:43:35 +02:00
AndrewRademacher 051e6118dd Bumped aeson version. 2015-09-23 11:43:02 +02:00
Julian K. Arni 867530fb59 Fix servant-mock version 2015-08-29 15:55:20 +02:00
Julian Arni b4be241fc9 Merge pull request #206 from haskell-servant/jkarni/mock-in-0.4
Add servant-mock to 0.4
2015-08-29 15:50:59 +02:00
Julian K. Arni ca1b21ebff Remove 0.5 combinators 2015-08-29 14:55:00 +02:00
Julian K. Arni 28d48ce320 Add stack.yaml 2015-08-29 14:54:45 +02:00
Julian K. Arni 4397154f49 Add servant-mock to sources.txt 2015-08-29 14:52:04 +02:00
Julian K. Arni cb75ed4073 Checkout servant-mock from master. 2015-08-29 14:46:57 +02:00
Julian K. Arni 52adac2039 Bump to 0.4.4.2.
For minor documentation fixes.
2015-08-29 13:26:06 +02:00
Julian K. Arni 85f5dfadde Remove broken links
Conflicts:
	servant/servant.cabal
2015-08-29 13:23:59 +02:00
Alp Mestanogullari 4bcf5158e7 Merge pull request #193 from haskell-servant/servant-server-readme-fix
update readme for servant-server
2015-08-16 11:32:39 +02:00
Alp Mestanogullari e5341d708f update readme for servant-server 2015-08-16 11:02:47 +02:00
Julian K. Arni 17b99b933f Bump to 0.4.4. 2015-07-30 10:49:40 +02:00
Julian K. Arni b74d699f6c Bump warp upper bound.
To < 3.2.

Conflicts:
	servant-server/servant-server.cabal
2015-07-30 10:47:44 +02:00
Julian K. Arni 1eacd565f1 Bump to 0.4.3.1 2015-07-10 13:55:18 +02:00
Julian K. Arni b5b4d9ad60 Cabal file fixes 2015-07-10 13:53:32 +02:00
Christian Marie a67cbbc224 Merge pull request #146 from haskell-servant/pingu/0.4-bugfixes
Bugfix release
2015-07-09 11:52:13 +10:00
Christian Marie fb97bee5ee Bump to 0.4.3 2015-07-09 11:05:23 +10:00
bwo 3b4df6775b servant-jquery: set content type to application/json on POST
Also remove some redundant newlines in generated JS.
2015-07-09 11:05:23 +10:00
Christian Marie 1efe9f1a2a Make bump-versions.sh work
This also makes it behave when called from from any directory.
2015-07-07 17:34:06 +10:00
Alp Mestanogullari e3c3ba2aeb remove tabs 2015-07-06 19:36:03 +10:00
Alp Mestanogullari 76b21f787c clarify some variable names in the examples + semantic html pedantry 2015-07-06 19:36:03 +10:00
Philipp Kant d1ee5c7a63 Added test for docsWith.
Make sure that no information is lost when providing additional
information via docsWith. With the current left-biased implementation of
combineAction, this can happen if the function arguments are in the
wrong order.
2015-07-06 19:36:03 +10:00
Philipp Kant 3565641359 servant-docs: Fix docsWith.
When adding extra info using using docsWith, the responses vanished from
the output. This was due to combineAction being left-biased, and
docsWith combining the extra info with the enpoint (in that
order). Flipping combineAction solves this.
2015-07-06 19:36:03 +10:00
Alp Mestanogullari 452ddf02e4 Add HasLink instance for Header. Fixes #128 2015-07-06 16:27:13 +10:00
Julian K. Arni 9f319963e9 Fix upload script issues 2015-06-09 12:51:39 +02:00
Julian K. Arni c11012dcbf Fix DIR issues 2015-06-09 12:33:30 +02:00
Julian K. Arni 0c52b23168 Upload script and some script refactoring 2015-06-09 12:33:19 +02:00
Julian K. Arni c86e32433a Bump version to 0.4.2 2015-06-09 11:06:41 +02:00
Julian K. Arni 1fc048e9db Bump string-conversions 2015-06-09 10:44:41 +02:00
Julian K. Arni 358f7691e5 Don't render header via String 2015-06-09 10:44:15 +02:00
52 changed files with 714 additions and 112 deletions

10
.gitignore vendored
View File

@ -1,8 +1,8 @@
dist
bin
lib
share
packages
/dist
/bin
/lib
/share
/packages
*-packages.conf.d
cabal-dev
add-source-timestamps

View File

@ -16,33 +16,17 @@
set -o nounset
set -o errexit
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
DRY_RUN=false
POSITION="none"
SOURCES_TXT="$( dirname $DIR)/sources.txt"
declare -a SOURCES
readarray -t SOURCES < "$SOURCES_TXT"
DIR=$( dirname $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ))
. "${DIR}/scripts/lib/common.sh"
usage () {
echo " bump-versions <POSITION> [-d|--dry-run]"
echo " bump-versions.sh <POSITION> [-d|--dry-run]"
echo " | [-h|--help]"
echo " Bumps the specified positional version of all servant packages."
echo " POSITION is a number between 0 and 3, inclusive."
exit 0
}
join () { local IFS="$1"; shift; echo "$*"; }
versions_equal () {
local NUM=$(find . -name 'servant*.cabal' | xargs grep "^version:" | awk '{ print $2 }' | uniq -c | wc -l)
if [ 1 -eq $NUM ] ; then
return 0
else
echo "versions of packages are not all the same!" && exit 1
fi
}
if [ $# -eq 0 ] ; then
echo "expecting one or more arguments. Got 0"
usage
@ -71,8 +55,11 @@ while [ "${1:-unset}" != "unset" ] ; do
done
if $DRY_RUN ; then
bumper --dry-run -"$POSITION" $(join , "${SOURCES[@]}")
echo "Would have bumped position ${POSITION} on these packages:"
( cd "$ROOT" && bumper --dry-run -"$POSITION" $(join , "${SOURCES[@]}") )
else
bumper -"$POSITION" $(join , "${SOURCES[@]}")
( cd "$ROOT" && bumper -"$POSITION" $(join , "${SOURCES[@]}") )
fi
# Trailing newline, bumper does not ship with its own.
echo

32
scripts/lib/common.sh Normal file
View File

@ -0,0 +1,32 @@
#!/bin/bash -
#===============================================================================
#
# FILE: lib/common.sh
#
# DESCRIPTION: Common functions for servant's shell scripts
# Meant to be sourced rather than run.
#
# REQUIREMENTS: bash >= 4
#===============================================================================
DIR=$( dirname $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ))
ROOT=$( dirname $DIR )
DRY_RUN=false
POSITION="none"
SOURCES_TXT="$( dirname $DIR)/sources.txt"
CABAL=${CABAL:-cabal}
declare -a SOURCES
readarray -t SOURCES < "$SOURCES_TXT"
join () { local IFS="$1"; shift; echo "$*"; }
versions_equal () {
local NUM=$(cd "$ROOT" && find . -name 'servant*.cabal' | xargs grep "^version:" | awk '{ print $2 }' | uniq -c | wc -l)
if [ 1 -eq $NUM ] ; then
return 0
else
echo "versions of packages are not all the same!" && exit 1
fi
}

View File

@ -14,11 +14,7 @@ set -o nounset
set -o errexit
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
SOURCES_TXT="$( dirname $DIR)/sources.txt"
CABAL=${CABAL:-cabal}
declare -a SOURCES
readarray -t SOURCES < "$SOURCES_TXT"
. "$DIR"/lib/common.sh
prepare_sandbox () {
$CABAL sandbox init

View File

@ -15,13 +15,10 @@ set -o nounset
set -o errexit
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
GHC_FLAGS="-Werror"
SOURCES_TXT="$( dirname $DIR)/sources.txt"
CABAL=${CABAL:-cabal}
declare -a SOURCES
readarray -t SOURCES < "$SOURCES_TXT"
. "$DIR"/lib/common.sh
# TODO: Remove missing-methods after https://github.com/bos/aeson/issues/290
GHC_FLAGS="-Werror -fno-warn-missing-methods"
prepare_sandbox () {
$CABAL sandbox init

View File

@ -12,11 +12,7 @@ set -o nounset
set -o errexit
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
BASE_DIR="$( dirname $DIR)"
SOURCES_TXT="$BASE_DIR/sources.txt"
declare -a SOURCES
readarray -t SOURCES < "$SOURCES_TXT"
. "$DIR"/lib/common.sh
for s in ${SOURCES[@]} ; do
echo $s

52
scripts/upload.sh Executable file
View File

@ -0,0 +1,52 @@
#!/bin/bash -
#===============================================================================
#
# FILE: upload.sh
#
# USAGE: ./upload.sh <USER> <PASSWORD>
#
# DESCRIPTION: Uploads all servant packages to Hackage
#
# REQUIREMENTS: cabal, bash >= 4
# AUTHOR: Julian K. Arni
# CREATED: 05.06.2015 13:05
#===============================================================================
set -o nounset
set -o errexit
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
. "$DIR"/lib/common.sh
usage () {
echo " upload.sh <USER> <PASSWORD>"
echo " Uploads all servant packages to Hackage"
exit 0
}
upload_package () {
local package="$1"
local user="$2"
local pass="$3"
local cabalFile="$package.cabal"
pushd "$package"
local version=$(grep -i '^version:' $cabalFile | awk '{ print $2 }')
local sdist="dist/${package}-${version}.tar.gz"
cabal sdist
echo "User is: $user"
cabal upload --user="$user" --password="$pass" "$sdist"
popd
}
if [ $# -ne 2 ] ; then
echo "expecting two arguments."
usage
fi
versions_equal
for s in ${SOURCES[@]} ; do
upload_package "$s" "$1" "$2"
done

View File

@ -2,7 +2,7 @@
-- documentation, see http://haskell.org/cabal/users-guide/
name: servant-blaze
version: 0.4.1
version: 0.4.4.7
synopsis: Blaze-html support for servant
-- description:
homepage: http://haskell-servant.github.io/
@ -15,6 +15,10 @@ category: Web
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
bug-reports: http://github.com/haskell-servant/servant/issues
source-repository head
type: git
location: http://github.com/haskell-servant/servant.git
library
exposed-modules: Servant.HTML.Blaze

30
servant-cassava/LICENSE Normal file
View File

@ -0,0 +1,30 @@
Copyright (c) 2015, Julian K. Arni
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Julian K. Arni nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

2
servant-cassava/Setup.hs Normal file
View File

@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain

View File

@ -0,0 +1,29 @@
-- Initial servant-cassava.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
name: servant-cassava
version: 0.4.4.7
synopsis: Servant CSV content-type for cassava
-- description:
homepage: http://haskell-servant.github.io/
license: BSD3
license-file: LICENSE
author: Julian K. Arni
maintainer: jkarni@gmail.com
-- copyright:
-- category:
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
library
exposed-modules: Servant.CSV.Cassava
-- other-modules:
-- other-extensions:
build-depends: base >=4.6 && <5
, cassava >0.4 && <0.5
, servant == 0.4.*
, http-media
, vector
hs-source-dirs: src
default-language: Haskell2010

View File

@ -0,0 +1,88 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | A @CSV@ empty datatype with `MimeRender` and `MimeUnrender` instances for
-- @cassava@'s encoding and decoding classes.
--
-- >>> type Eg = Get '[(CSV', MyEncodeOptions)] [(Int, String)]
--
-- Default encoding and decoding options are also provided, along with the
-- @CSV@ type synonym that uses them.
--
-- >>> type EgDefault = Get '[CSV] [(Int, String)]
module Servant.CSV.Cassava where
import Data.Csv
import Data.Proxy (Proxy (..))
import Data.Typeable (Typeable)
import Data.Vector (Vector)
import GHC.Generics (Generic)
import qualified Network.HTTP.Media as M
import Servant.API (Accept (..), MimeRender (..),
MimeUnrender (..))
data CSV' deriving (Typeable, Generic)
type CSV = (CSV', DefaultDecodeOpts)
-- | @text/csv;charset=utf-8@
instance Accept (CSV', a) where
contentType _ = "text" M.// "csv" M./: ("charset", "utf-8")
-- * Encoding
-- ** Instances
-- | Encode with 'encodeByNameWith'. The 'Header' param is used for determining
-- the order of headers and fields.
instance ( ToNamedRecord a, EncodeOpts opt
) => MimeRender (CSV', opt) (Header, [a]) where
mimeRender _ (hdr, vals) = encodeByNameWith (encodeOpts p) hdr vals
where p = Proxy :: Proxy opt
-- | Encode with 'encodeDefaultOrderedByNameWith'
instance ( DefaultOrdered a, ToNamedRecord a, EncodeOpts opt
) => MimeRender (CSV', opt) [a] where
mimeRender _ = encodeDefaultOrderedByNameWith (encodeOpts p)
where p = Proxy :: Proxy opt
-- ** Encode Options
class EncodeOpts a where
encodeOpts :: Proxy a -> EncodeOptions
data DefaultEncodeOpts deriving (Typeable, Generic)
instance EncodeOpts DefaultEncodeOpts where
encodeOpts _ = defaultEncodeOptions
-- * Decoding
-- ** Instances
-- | Decode with 'decodeByNameWith'
instance ( FromNamedRecord a, DecodeOpts opt
) => MimeUnrender (CSV', opt) (Header, Vector a) where
mimeUnrender _ = decodeByNameWith (decodeOpts p)
where p = Proxy :: Proxy opt
-- | Decode with 'decodeWith'. Assumes data has headers, which are stripped.
instance ( FromRecord a, DecodeOpts opt
) => MimeUnrender (CSV', opt) (Vector a) where
mimeUnrender _ = decodeWith (decodeOpts p) HasHeader
where p = Proxy :: Proxy opt
-- ** Decode Options
class DecodeOpts a where
decodeOpts :: Proxy a -> DecodeOptions
data DefaultDecodeOpts deriving (Typeable, Generic)
instance DecodeOpts DefaultDecodeOpts where
decodeOpts _ = defaultDecodeOptions

View File

@ -1,5 +1,5 @@
name: servant-client
version: 0.4.1
version: 0.4.4.7
synopsis: automatical derivation of querying functions for servant webservices
description:
This library lets you derive automatically Haskell functions that

View File

@ -252,7 +252,7 @@ instance
(MimeUnrender ct a) => HasClient (Post (ct ': cts) a) where
type Client (Post (ct ': cts) a) = EitherT ServantError IO a
clientWithRoute Proxy req baseurl =
snd <$> performRequestCT (Proxy :: Proxy ct) H.methodPost req [200,201] baseurl
snd <$> performRequestCT (Proxy :: Proxy ct) H.methodPost req [200, 201, 202] baseurl
-- | If you have a 'Post xs ()' endpoint, the client expects a 204 No Content
-- HTTP header.
@ -275,7 +275,7 @@ instance
) => HasClient (Post (ct ': cts) (Headers ls a)) where
type Client (Post (ct ': cts) (Headers ls a)) = EitherT ServantError IO (Headers ls a)
clientWithRoute Proxy req baseurl = do
(hdrs, resp) <- performRequestCT (Proxy :: Proxy ct) H.methodPost req [200, 201] baseurl
(hdrs, resp) <- performRequestCT (Proxy :: Proxy ct) H.methodPost req [200, 201, 202] baseurl
return $ Headers { getResponse = resp
, getHeadersHList = buildHeadersTo hdrs
}

View File

@ -1,3 +1,7 @@
0.4.3
-----
* docsWith will no longer eat your documentation (https://github.com/haskell-servant/servant/pull/124)
0.4
---
* `Delete` now is like `Get`, `Post`, `Put`, and `Patch` and returns a response body

View File

@ -1,5 +1,5 @@
name: servant-docs
version: 0.4.1
version: 0.4.4.7
synopsis: generate API docs for your servant webservice
description:
Library for generating API docs from a servant API definition.
@ -70,6 +70,7 @@ test-suite spec
base
, aeson
, hspec
, lens
, servant
, servant-docs
, string-conversions

View File

@ -22,18 +22,20 @@ module Servant.Docs.Internal where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative
#endif
import Control.Lens
import Control.Lens (makeLenses, over, traversed, (%~),
(&), (.~), (<>~), (^.), _1, _2,
_last, (|>))
import Data.ByteString.Conversion (ToByteString, toByteString)
import Data.ByteString.Lazy.Char8 (ByteString)
import qualified Data.CaseInsensitive as CI
import Data.Hashable
import Data.Hashable (Hashable)
import Data.HashMap.Strict (HashMap)
import Data.List
import Data.Maybe
import Data.Monoid
import Data.Ord (comparing)
import Data.Proxy
import Data.ByteString.Conversion (ToByteString, toByteString)
import Data.String.Conversions
import Data.Proxy (Proxy(Proxy))
import Data.String.Conversions (cs)
import Data.Text (Text, pack, unpack)
import GHC.Exts (Constraint)
import GHC.Generics
@ -338,7 +340,7 @@ extraInfo p action =
docsWith :: HasDocs layout => [DocIntro] -> ExtraInfo layout -> Proxy layout -> API
docsWith intros (ExtraInfo endpoints) p =
docs p & apiIntros <>~ intros
& apiEndpoints %~ HM.unionWith combineAction endpoints
& apiEndpoints %~ HM.unionWith (flip combineAction) endpoints
-- | Generate the docs for a given API that implements 'HasDocs' with with any

View File

@ -7,7 +7,9 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Servant.DocsSpec where
import Control.Lens
import Data.Aeson
import Data.Monoid
import Data.Proxy
import Data.String.Conversions (cs)
import GHC.Generics
@ -21,7 +23,27 @@ spec = describe "Servant.Docs" $ do
describe "markdown" $ do
let md = markdown (docs (Proxy :: Proxy TestApi1))
tests md
describe "markdown with extra info" $ do
let
extra = extraInfo
(Proxy :: Proxy (Get '[JSON, PlainText] Int))
(defAction & notes <>~ [DocNote "Get an Integer" ["get an integer in Json or plain text"]])
<>
extraInfo
(Proxy :: Proxy (ReqBody '[JSON] String :> Post '[JSON] Datatype1))
(defAction & notes <>~ [DocNote "Post data" ["Posts some Json data"]])
md = markdown (docsWith [] extra (Proxy :: Proxy TestApi1))
tests md
it "contains the extra info provided" $ do
md `shouldContain` "Get an Integer"
md `shouldContain` "Post data"
md `shouldContain` "get an integer in Json or plain text"
md `shouldContain` "Posts some Json data"
where
tests md = do
it "mentions supported content-types" $ do
md `shouldContain` "application/json"
md `shouldContain` "text/plain;charset=utf-8"
@ -34,10 +56,11 @@ spec = describe "Servant.Docs" $ do
md `shouldContain` "POST"
md `shouldContain` "GET"
it "contains response samples" $ do
it "contains response samples" $
md `shouldContain` "{\"dt1field1\":\"field 1\",\"dt1field2\":13}"
it "contains request body samples" $ do
it "contains request body samples" $
md `shouldContain` "17"
-- * APIs
data Datatype1 = Datatype1 { dt1field1 :: String

View File

@ -0,0 +1,3 @@
0.4.3
-----
* Clarify some variable names in the examples + semantic html pedantry

View File

@ -5,6 +5,7 @@
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
import Data.Aeson
import Data.ByteString (ByteString)
import Data.Text (Text)

View File

@ -2,6 +2,8 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
import Control.Applicative
import Control.Monad
import Control.Monad.IO.Class

View File

@ -1,5 +1,5 @@
name: servant-examples
version: 0.4.1
version: 0.4.4.7
synopsis: Example programs for servant
description: Example programs for servant,
showcasing solutions to common needs.
@ -12,12 +12,16 @@ maintainer: alpmestan@gmail.com
category: Web
build-type: Simple
cabal-version: >=1.10
bug-reports: http://github.com/haskell-servant/servant/issues
source-repository head
type: git
location: http://github.com/haskell-servant/servant.git
executable tutorial
main-is: tutorial.hs
other-modules: T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
build-depends:
aeson >= 0.8
aeson >= 0.10
, base >= 4.7 && < 5
, bytestring
, directory
@ -41,6 +45,7 @@ executable tutorial
executable t8-main
main-is: t8-main.hs
other-modules: T3, T8
hs-source-dirs: tutorial
default-language: Haskell2010
build-depends:

View File

@ -17,17 +17,12 @@ data User = User
, registration_date :: Day
} deriving (Eq, Show, Generic)
-- orphan ToJSON instance for Day. necessary to derive one for User
instance ToJSON Day where
-- display a day in YYYY-mm-dd format
toJSON d = toJSON (showGregorian d)
instance ToJSON User
type UserAPI = "users" :> Get '[JSON] [User]
users :: [User]
users =
users =
[ User "Isaac Newton" 372 "isaac@newton.co.uk" (fromGregorian 1683 3 1)
, User "Albert Einstein" 136 "ae@mc2.org" (fromGregorian 1905 12 1)
]

View File

@ -4,6 +4,7 @@
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module T10 where
import Data.ByteString.Lazy (ByteString)

View File

@ -17,11 +17,6 @@ data User = User
, registration_date :: Day
} deriving (Eq, Show, Generic)
-- orphan ToJSON instance for Day. necessary to derive one for User
instance ToJSON Day where
-- display a day in YYYY-mm-dd format
toJSON d = toJSON (showGregorian d)
instance ToJSON User
type UserAPI = "users" :> Get '[JSON] [User]

View File

@ -70,7 +70,7 @@ server = position
:<|> marketing
where position :: Int -> Int -> EitherT ServantErr IO Position
position x y = return (Position x y)
position a b = return (Position a b)
hello :: Maybe String -> EitherT ServantErr IO HelloMessage
hello mname = return . HelloMessage $ case mname of

View File

@ -4,6 +4,7 @@
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
module T4 where
import Data.Aeson
@ -25,23 +26,23 @@ instance ToJSON Person
-- HTML serialization of a single person
instance ToHtml Person where
toHtml p =
toHtml person =
tr_ $ do
td_ (toHtml $ firstName p)
td_ (toHtml $ lastName p)
td_ (toHtml . show $ age p)
td_ (toHtml $ firstName person)
td_ (toHtml $ lastName person)
td_ (toHtml . show $ age person)
toHtmlRaw = toHtml
-- HTML serialization of a list of persons
instance ToHtml [Person] where
toHtml persons = table_ $ do
toHtml ps = table_ $ do
tr_ $ do
td_ "first name"
td_ "last name"
td_ "age"
th_ "first name"
th_ "last name"
th_ "age"
foldMap toHtml persons
foldMap toHtml ps
toHtmlRaw = toHtml

View File

@ -1,10 +1,10 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
module T8 where
import Control.Monad.Trans.Either
import Data.Aeson
import Servant
import Servant.Client

View File

@ -3,6 +3,7 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
module T9 where
import Control.Applicative

View File

@ -1,6 +1,7 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
import Data.Aeson
import Data.Text
import GHC.Generics

View File

@ -1,3 +1,7 @@
0.4.3
-----
* Content type now set to JSON when a request body is sent (#122)
0.4
---
* `Delete` now is like `Get`, `Post`, `Put`, and `Patch` and returns a response body

View File

@ -1,5 +1,5 @@
name: servant-jquery
version: 0.4.1
version: 0.4.4.7
synopsis: Automatically derive (jquery) javascript functions to query servant webservices
description:
Automatically derive jquery-based javascript functions to query servant webservices.

View File

@ -65,13 +65,14 @@ generateJS req = "\n" <>
dataBody =
if req ^. reqBody
then "\n , data: JSON.stringify(body)\n"
then " , data: JSON.stringify(body)\n" <>
" , contentType: 'application/json'\n"
else ""
reqheaders =
if null hs
then ""
else "\n , headers: { " ++ headersStr ++ " }\n"
else " , headers: { " ++ headersStr ++ " }\n"
where headersStr = intercalate ", " $ map headerStr hs
headerStr header = "\"" ++

View File

@ -11,19 +11,20 @@
module Servant.JQuery.Internal where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative
import Control.Applicative
#endif
import Control.Lens
import Data.Char (toLower)
import qualified Data.CharSet as Set
import Control.Lens (makeLenses, (%~), (&), (.~)
, (<>~), (^.), _last)
import Data.Char (toLower)
import qualified Data.CharSet as Set
import qualified Data.CharSet.Unicode.Category as Set
import Data.List
import Data.Monoid
import Data.Proxy
import qualified Data.Text as T
import GHC.Exts (Constraint)
import GHC.TypeLits
import Servant.API
import Data.List
import Data.Monoid
import Data.Proxy
import qualified Data.Text as T
import GHC.Exts (Constraint)
import GHC.TypeLits
import Servant.API
type Arg = String

View File

@ -2,7 +2,7 @@
-- documentation, see http://haskell.org/cabal/users-guide/
name: servant-lucid
version: 0.4.1
version: 0.4.4.7
synopsis: Servant support for lucid
-- description:
homepage: http://haskell-servant.github.io/
@ -15,6 +15,10 @@ category: Web
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
bug-reports: http://github.com/haskell-servant/servant/issues
source-repository head
type: git
location: http://github.com/haskell-servant/servant.git
library
exposed-modules: Servant.HTML.Lucid

30
servant-mock/LICENSE Normal file
View File

@ -0,0 +1,30 @@
Copyright (c) 2015, Alp Mestanogullari
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Alp Mestanogullari nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

2
servant-mock/Setup.hs Normal file
View File

@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain

17
servant-mock/default.nix Normal file
View File

@ -0,0 +1,17 @@
{ mkDerivation, aeson, base, bytestring, http-types, QuickCheck
, servant, servant-server, stdenv, transformers, wai, warp
}:
mkDerivation {
pname = "servant-mock";
version = "0.5";
src = ./.;
isLibrary = true;
isExecutable = true;
buildDepends = [
aeson base bytestring http-types QuickCheck servant servant-server
transformers wai warp
];
homepage = "http://github.com/haskell-servant/servant";
description = "Derive a mock server for free from your servant API types";
license = stdenv.lib.licenses.bsd3;
}

View File

@ -0,0 +1,23 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeOperators #-}
import Data.Aeson
import GHC.Generics
import Network.Wai.Handler.Warp
import Servant
import Servant.Mock
import Test.QuickCheck.Arbitrary
newtype User = User { username :: String }
deriving (Eq, Show, Arbitrary, Generic)
instance ToJSON User
type API = "user" :> Get '[JSON] User
api :: Proxy API
api = Proxy
main :: IO ()
main = run 8080 (serve api $ mock api)

View File

@ -0,0 +1,46 @@
name: servant-mock
version: 0.4.4.7
synopsis: Derive a mock server for free from your servant API types
description:
Derive a mock server for free from your servant API types
.
See the @Servant.Mock@ module for the documentation and an example.
homepage: http://github.com/haskell-servant/servant
license: BSD3
license-file: LICENSE
author: Alp Mestanogullari
maintainer: alpmestan@gmail.com
copyright: 2015 Alp Mestanogullari
category: Web
build-type: Simple
cabal-version: >=1.10
flag example
description: Build the example too
manual: True
default: False
library
exposed-modules:
Servant.Mock
build-depends:
base >=4.7 && <5,
bytestring >= 0.10 && <0.11,
http-types >= 0.8 && <0.10,
servant >= 0.4,
servant-server >= 0.4,
transformers >= 0.3 && <0.5,
QuickCheck >= 2.8 && <2.9,
wai >= 3.0 && <3.3
hs-source-dirs: src
default-language: Haskell2010
executable mock-app
main-is: main.hs
hs-source-dirs: example
default-language: Haskell2010
build-depends: aeson, base, servant-mock, servant-server, QuickCheck, warp
if flag(example)
buildable: True
else
buildable: False

18
servant-mock/shell.nix Normal file
View File

@ -0,0 +1,18 @@
let
pkgs = import <nixpkgs> {};
haskellPackages = pkgs.haskellPackages.override {
overrides = self: super: {
servant = pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.appendConfigureFlag (self.callPackage ../servant {}) "--ghc-options=-Werror");
servant-client = pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.appendConfigureFlag (self.callPackage ../servant-client {}) "--ghc-options=-Werror");
servant-docs = pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.appendConfigureFlag (self.callPackage ../servant-docs {}) "--ghc-options=-Werror");
servant-js = pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.appendConfigureFlag (self.callPackage ../servant-js {}) "--ghc-options=-Werror");
servant-server = pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.appendConfigureFlag (self.callPackage ../servant-server {}) "--ghc-options=-Werror");
servant-examples = pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.appendConfigureFlag (self.callPackage ../servant-examples {}) "--ghc-options=-Werror");
servant-blaze = pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.appendConfigureFlag (self.callPackage ../servant-blaze {}) "--ghc-options=-Werror");
servant-lucid = pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.appendConfigureFlag (self.callPackage ../servant-lucid {}) "--ghc-options=-Werror");
servant-mock = pkgs.haskell.lib.appendConfigureFlag (self.callPackage ./. {}) "--ghc-options=-Werror";
};
};
in haskellPackages.servant-mock.env

View File

@ -0,0 +1,178 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- |
-- Module : Servant.Mock
-- Copyright : 2015 Alp Mestanogullari
-- License : BSD3
--
-- Maintainer : Alp Mestanogullari <alpmestan@gmail.com>
-- Stability : experimental
-- Portability : portable
--
-- Automatically derive a mock webserver that implements some API type,
-- just from the said API type's definition.
--
-- Using this module couldn't be simpler. Given some API type, like:
--
-- > type API = "user" :> Get '[JSON] User
--
-- that describes your web application, all you have to do is define
-- a 'Proxy' to it:
--
-- > myAPI :: Proxy API
-- > myAPI = Proxy
--
-- and call 'mock', which has the following type:
--
-- @
-- 'mock' :: 'HasMock' api => 'Proxy' api -> 'Server' api
-- @
--
-- What this says is, given some API type @api@ that it knows it can
-- "mock", 'mock' hands you an implementation of the API type. It does so
-- by having each request handler generate a random value of the
-- appropriate type (@User@ in our case). All you need for this to work is
-- to provide 'Arbitrary' instances for the data types returned as response
-- bodies, hence appearing next to 'Delete', 'Get', 'Patch', 'Post' and 'Put'.
--
-- To put this all to work and run the mock server, just call 'serve' on the
-- result of 'mock' to get an 'Application' that you can then run with warp.
--
-- @
-- main :: IO ()
-- main = Network.Wai.Handler.Warp.run 8080 $
-- 'serve' myAPI ('mock' myAPI)
-- @
module Servant.Mock ( HasMock(..) ) where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative
#endif
import Control.Monad.IO.Class
import Data.ByteString.Lazy.Char8 (pack)
import Data.Proxy
import GHC.TypeLits
import Network.HTTP.Types.Status
import Network.Wai
import Servant
import Servant.API.ContentTypes
import Test.QuickCheck.Arbitrary (Arbitrary (..), vector)
import Test.QuickCheck.Gen (Gen, generate)
-- | 'HasMock' defines an interpretation of API types
-- than turns them into random-response-generating
-- request handlers, hence providing an instance for
-- all the combinators of the core /servant/ library.
class HasServer api => HasMock api where
-- | Calling this method creates request handlers of
-- the right type to implement the API described by
-- @api@ that just generate random response values of
-- the right type. E.g:
--
-- @
-- type API = "user" :> Get '[JSON] User
-- :<|> "book" :> Get '[JSON] Book
--
-- api :: Proxy API
-- api = Proxy
--
-- -- let's say we will start with the frontend,
-- -- and hence need a placeholder server
-- server :: Server API
-- server = mock api
-- @
--
-- What happens here is that @'Server' API@
-- actually "means" 2 request handlers, of the following types:
--
-- @
-- getUser :: EitherT ServantErr IO User
-- getBook :: EitherT ServantErr IO Book
-- @
--
-- So under the hood, 'mock' uses the 'IO' bit to generate
-- random values of type 'User' and 'Book' every time these
-- endpoints are requested.
mock :: Proxy api -> Server api
instance (HasMock a, HasMock b) => HasMock (a :<|> b) where
mock _ = mock (Proxy :: Proxy a) :<|> mock (Proxy :: Proxy b)
instance (KnownSymbol path, HasMock rest) => HasMock (path :> rest) where
mock _ = mock (Proxy :: Proxy rest)
instance (KnownSymbol s, FromText a, HasMock rest) => HasMock (Capture s a :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (AllCTUnrender ctypes a, HasMock rest) => HasMock (ReqBody ctypes a :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (KnownSymbol s, FromText a, HasMock rest)
=> HasMock (QueryParam s a :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (KnownSymbol s, FromText a, HasMock rest)
=> HasMock (QueryParams s a :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (KnownSymbol s, HasMock rest) => HasMock (QueryFlag s :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (KnownSymbol s, FromText a, HasMock rest)
=> HasMock (MatrixParam s a :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (KnownSymbol s, FromText a, HasMock rest)
=> HasMock (MatrixParams s a :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (KnownSymbol s, HasMock rest) => HasMock (MatrixFlag s :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (KnownSymbol h, FromText a, HasMock rest) => HasMock (Header h a :> rest) where
mock _ = \_ -> mock (Proxy :: Proxy rest)
instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Delete ctypes a) where
mock _ = mockArbitrary
instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Get ctypes a) where
mock _ = mockArbitrary
instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Patch ctypes a) where
mock _ = mockArbitrary
instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Post ctypes a) where
mock _ = mockArbitrary
instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Put ctypes a) where
mock _ = mockArbitrary
instance HasMock Raw where
mock _ = \_ respond -> do
bdy <- genBody
respond $ responseLBS status200 [] bdy
where genBody = pack <$> generate (vector 100 :: Gen [Char])
mockArbitrary :: (MonadIO m, Arbitrary a) => m a
mockArbitrary = liftIO (generate arbitrary)
-- utility instance
instance (Arbitrary (HList ls), Arbitrary a)
=> Arbitrary (Headers ls a) where
arbitrary = Headers <$> arbitrary <*> arbitrary
instance Arbitrary (HList '[]) where
arbitrary = pure HNil
instance (Arbitrary a, Arbitrary (HList hs))
=> Arbitrary (HList (Header h a ': hs)) where
arbitrary = HCons <$> fmap Header arbitrary <*> arbitrary

View File

@ -1,3 +1,8 @@
0.4.3
-----
* Bump aeson upper-bound to < 0.11
0.4.1
-----
* Bump attoparsec upper bound to < 0.14

View File

@ -4,13 +4,13 @@
This library lets you *implement* an HTTP server with handlers for each endpoint of a servant API, handling most of the boilerplate for you.
## Getting started
## Tutorial
We've written a [Getting Started](http://haskell-servant.github.io/getting-started/) guide that introduces the core types and features of servant. After this article, you should be able to write your first servant webservices, learning the rest from the haddocks' examples.
We've written a [tutorial](http://haskell-servant.github.io/tutorial/) that introduces the core types and features of servant.
## Repositories and Haddocks
- The core [servant](http://github.com/haskell-servant) package - [docs](http://hackage.haskell.org/package/servant)
- The core [servant](http://github.com/haskell-servant/servant/tree/master/servant) package - [docs](http://hackage.haskell.org/package/servant)
- Implementing an HTTP server for a webservice API with [servant-server](http://github.com/haskell-servant/servant/tree/master/servant-server) - [docs](http://hackage.haskell.org/package/servant-server)
- (Haskell) client-side function generation with [servant-client](http://github.com/haskell-servant/servant/tree/master/servant-client) - [docs](http://hackage.haskell.org/package/servant-client)
- (Javascript) client-side function generation with [servant-jquery](http://github.com/haskell-servant/servant/tree/master/servant-jquery) - [docs](http://hackage.haskell.org/package/servant-jquery)

View File

@ -1,5 +1,5 @@
name: servant-server
version: 0.4.1
version: 0.4.4.7
synopsis: A family of combinators for defining webservices APIs and serving them
description:
A family of combinators for defining webservices APIs and serving them
@ -25,9 +25,10 @@ tested-with: GHC >= 7.8
extra-source-files:
CHANGELOG.md
README.md
bug-reports: http://github.com/haskell-servant/servant/issues
source-repository head
type: git
location: http://github.com/haskell-servant/servant-server.git
location: http://github.com/haskell-servant/servant.git
library
@ -40,25 +41,26 @@ library
Servant.Utils.StaticFiles
build-depends:
base >= 4.7 && < 5
, aeson >= 0.7 && < 0.10
, aeson >= 0.7 && < 0.12
, attoparsec >= 0.12 && < 0.14
, bytestring >= 0.10 && < 0.11
, either >= 4.3 && < 4.5
, http-types >= 0.8 && < 0.9
, http-types >= 0.8 && < 0.10
, network-uri >= 2.6 && < 2.7
, mtl >= 2 && < 3
, mmorph >= 1
, safe >= 0.3 && < 0.4
, servant == 0.4.*
, split >= 0.2 && < 0.3
, string-conversions >= 0.3 && < 0.4
, string-conversions >= 0.3 && < 0.5
, system-filepath >= 0.4 && < 0.5
, filepath >= 1
, text >= 1.2 && < 1.3
, transformers >= 0.3 && < 0.5
, wai >= 3.0 && < 3.1
, wai >= 3.0 && < 3.3
, wai-app-static >= 3.0 && < 3.2
, warp >= 3.0 && < 3.1
, warp >= 3.0 && < 3.3
hs-source-dirs: src
default-language: Haskell2010
ghc-options: -Wall

View File

@ -1,3 +1,7 @@
0.4.3
-----
* Add missing HasLink instance for Header (https://github.com/haskell-servant/servant/issues/128)
0.4.1
-----
* Allow whitespace after parsing JSON

View File

@ -1,14 +1,11 @@
name: servant
version: 0.4.1
version: 0.4.4.7
synopsis: A family of combinators for defining webservices APIs
description:
A family of combinators for defining webservices APIs and serving them
.
You can learn about the basics in the <http://haskell-servant.github.io/tutorial tutorial>.
.
<https://github.com/haskell-servant/servant-server/blob/master/example/greet.hs Here>'s a runnable example, with comments, that defines a dummy API and
implements a webserver that serves this API, using the <http://hackage.haskell.org/package/servant-server servant-server> package.
.
<https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md CHANGELOG>
homepage: http://haskell-servant.github.io/
Bug-reports: http://github.com/haskell-servant/servant/issues
@ -46,16 +43,16 @@ library
Servant.Common.Text
Servant.Utils.Links
build-depends:
base >=4.7 && <5
base >=4.7 && <4.9
, aeson >= 0.7
, attoparsec >= 0.12
, bytestring == 0.10.*
, bytestring-conversion == 0.3.*
, case-insensitive >= 1.2
, http-media >= 0.4 && < 0.7
, http-types == 0.8.*
, http-types >= 0.8 && < 0.10
, text >= 1 && < 2
, string-conversions >= 0.3 && < 0.4
, string-conversions >= 0.3 && < 0.5
, network-uri >= 2.6
hs-source-dirs: src
default-language: Haskell2010

View File

@ -166,7 +166,7 @@ instance ( AllMimeRender ctyps a, IsNonEmpty ctyps
handleAcceptH _ (AcceptHeader accept) val = M.mapAcceptMedia lkup accept
where pctyps = Proxy :: Proxy ctyps
amrs = allMimeRender pctyps val
lkup = fmap (\(a,b) -> (a, (cs $ show a, b))) amrs
lkup = fmap (\(a,b) -> (a, (fromStrict $ M.renderHeader a, b))) amrs
--------------------------------------------------------------------------

View File

@ -339,6 +339,10 @@ instance (ToText v, HasLink sub)
toLink (Proxy :: Proxy sub) $
addSegment (escape . unpack $ toText v) l
instance HasLink sub => HasLink (Header sym a :> sub) where
type MkLink (Header sym a :> sub) = MkLink sub
toLink _ = toLink (Proxy :: Proxy sub)
-- Verb (terminal) instances
instance HasLink (Get y r) where
type MkLink (Get y r) = URI

View File

@ -4,6 +4,7 @@
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Servant.API.ContentTypesSpec where
#if !MIN_VERSION_base(4,8,0)

View File

@ -1,4 +1,5 @@
servant
servant-cassava
servant-client
servant-docs
servant-jquery
@ -6,3 +7,4 @@ servant-server
servant-examples
servant-blaze
servant-lucid
servant-mock

15
stack.yaml Normal file
View File

@ -0,0 +1,15 @@
packages:
- servant/
- servant-blaze/
- servant-client/
- servant-docs/
- servant-examples/
- servant-jquery/
- servant-lucid/
- servant-mock/
- servant-server/
extra-deps:
- engine-io-wai-1.0.2
- attoparsec-0.13.0.1
- aeson-0.10.0.0
resolver: nightly-2015-07-24