Fix typos and grammar (#1304)
* Fix typos and grammar * Remove redundant words, fix articles * More language fixes * More typo fixes and resolve TODO about missing links
This commit is contained in:
parent
67cb564aef
commit
b9d8fbcdc1
43 changed files with 83 additions and 80 deletions
|
@ -103,7 +103,7 @@ the `news` label if you make a new package so we can know about it!
|
|||
|
||||
## Release policy
|
||||
|
||||
We are currently moving to a more aggresive release policy, so that you can get
|
||||
We are currently moving to a more aggressive release policy, so that you can get
|
||||
what you contribute from Hackage fairly soon. However, note that prior to major
|
||||
releases it may take some time in between releases.
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ See `CONTRIBUTING.md`
|
|||
- It's a good idea to separate these steps, as tests often pass, if they compile :)
|
||||
- See `cabal.project` to selectively `allow-newer`
|
||||
- If some packages are broken, on your discretisation there are two options:
|
||||
- Fix them and make PRs: it's good idea to test against older `servant` version too.
|
||||
- Fix them and make PRs: it's a good idea to test against older `servant` version too.
|
||||
- Temporarily comment out broken package
|
||||
- If you make a commit for `servant-universe`, you can use it as submodule in private projects to test even more
|
||||
- When ripples are cleared out:
|
||||
|
@ -60,7 +60,7 @@ constraints:
|
|||
troublemaker <13.37 && > 13.37
|
||||
```
|
||||
|
||||
## TechEmpower framework bechmarks
|
||||
## TechEmpower framework benchmarks
|
||||
|
||||
We develop and maintain the servant TFB entry in https://github.com/haskell-servant/FrameworkBenchmarks/
|
||||
|
||||
|
|
|
@ -8,7 +8,10 @@ In other words, without streaming libraries.
|
|||
- Some basic usage doesn't require usage of streaming libraries,
|
||||
like `conduit`, `pipes`, `machines` or `streaming`.
|
||||
We have bindings for them though.
|
||||
- This is similar example file, which is bundled with each of the packages (TODO: links)
|
||||
- Similar example is bundled with each of our streaming library interop packages (see
|
||||
[servant-pipes](https://github.com/haskell-servant/servant/blob/master/servant-pipes/example/Main.hs),
|
||||
[servant-conduit](https://github.com/haskell-servant/servant/blob/master/servant-conduit/example/Main.hs) and
|
||||
[servant-machines](https://github.com/haskell-servant/servant/blob/master/servant-machines/example/Main.hs))
|
||||
- `SourceT` doesn't have *Prelude* with handy combinators, so we have to write
|
||||
things ourselves. (Note to self: `mapM` and `foldM` would be handy to have).
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Generating mock curl calls
|
||||
|
||||
In this example we will generate curl requests with mock post data from a servant API.
|
||||
This may be usefull for testing and development purposes.
|
||||
This may be useful for testing and development purposes.
|
||||
Especially post requests with a request body are tedious to send manually.
|
||||
|
||||
Also, we will learn how to use the servant-foreign library to generate stuff from servant APIs.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
This doc will walk through a single-module implementation of a servant API connecting to a MySQL database. It will also include some basic CRUD operations.
|
||||
|
||||
Once you can wrap your head around this implemenation, understanding more complex features like resource pools would be beneficial next steps.
|
||||
Once you can wrap your head around this implementation, understanding more complex features like resource pools would be beneficial next steps.
|
||||
|
||||
The only *prerequisite* is that you have a MySQL database open on port 3306 of your machine. Docker is an easy way to manage this.
|
||||
|
||||
|
|
|
@ -90,8 +90,8 @@ startServer = run 8080 (serve api upload)
|
|||
|
||||
Finally, a main function that brings up our server and
|
||||
sends some test request with `http-client` (and not
|
||||
servant-client this time, has servant-multipart does not
|
||||
yet have support for client generation.
|
||||
servant-client this time, as servant-multipart does not
|
||||
yet have support for client generation).
|
||||
|
||||
``` haskell
|
||||
main :: IO ()
|
||||
|
|
|
@ -43,13 +43,13 @@ api :: Proxy (ToServantApi Routes)
|
|||
api = genericApi (Proxy :: Proxy Routes)
|
||||
```
|
||||
|
||||
It's recommented to use `genericApi` function, as then you'll get
|
||||
It's recommended to use `genericApi` function, as then you'll get
|
||||
better error message, for example if you forget to `derive Generic`.
|
||||
|
||||
## Links
|
||||
|
||||
The clear advantage of record-based generics approach, is that
|
||||
we can get safe links very conviently. We don't need to define endpoint types,
|
||||
we can get safe links very conveniently. We don't need to define endpoint types,
|
||||
as field accessors work as proxies:
|
||||
|
||||
```haskell
|
||||
|
@ -67,7 +67,7 @@ routesLinks = allFieldLinks
|
|||
## Client
|
||||
|
||||
Even more power starts to show when we generate a record of client functions.
|
||||
Here we use `genericClientHoist` function, which let us simultaneously
|
||||
Here we use `genericClientHoist` function, which lets us simultaneously
|
||||
hoist the monad, in this case from `ClientM` to `IO`.
|
||||
|
||||
```haskell
|
||||
|
|
|
@ -254,7 +254,7 @@ loginHandler cookieSettings jwtSettings form = do
|
|||
liftIO $ pushLogStrLn logset $ toLogStr logMsg
|
||||
throwError err401
|
||||
Just applyCookies -> do
|
||||
let successMsg = logMsg{message = "AdminUser succesfully authenticated!"}
|
||||
let successMsg = logMsg{message = "AdminUser successfully authenticated!"}
|
||||
liftIO $ pushLogStrLn logset $ toLogStr successMsg
|
||||
pure $ applyCookies successMsg
|
||||
loginHandler _ _ _ = throwError err401
|
||||
|
|
|
@ -8,7 +8,7 @@ some login token would be saved in the user agent local storage.
|
|||
|
||||
Workflow:
|
||||
|
||||
1. user is presentend with a login button,
|
||||
1. user is presented with a login button,
|
||||
2. when the user click on the button it is redirected to the OIDC
|
||||
provider,
|
||||
3. the user login in the OIDC provider,
|
||||
|
@ -222,8 +222,8 @@ The `AuthInfo` is about the infos we can grab from OIDC provider.
|
|||
To be more precise, the user should come with a `code` (a token) and
|
||||
POSTing that code to the correct OIDC provider endpoint should return a JSON
|
||||
object. One of the field should be named `id_token` which should be a
|
||||
JWT containing all the informations we need. Depending on the scopes we
|
||||
asked we might get more informations.
|
||||
JWT containing all the information we need. Depending on the scopes we
|
||||
asked we might get more information.
|
||||
|
||||
``` haskell
|
||||
-- | @AuthInfo@
|
||||
|
@ -248,13 +248,13 @@ instance JSON.ToJSON AuthInfo where
|
|||
type LoginHandler = AuthInfo -> IO (Either Text User)
|
||||
```
|
||||
|
||||
The `handleLoggedIn` is that part that will retrieve the informations from
|
||||
The `handleLoggedIn` is that part that will retrieve the information from
|
||||
the user once he is redirected from the OIDC Provider after login.
|
||||
|
||||
If the user is redirected to the `redirect_uri` but with an `error` query
|
||||
parameter then it means something goes wrong.
|
||||
If there is no error query param but a `code` query param it means the user
|
||||
sucessfully logged in. From there we need to make a request to the token
|
||||
successfully logged in. From there we need to make a request to the token
|
||||
endpoint of the OIDC provider. Its a POST that should contains the code
|
||||
as well as the client id & secret.
|
||||
This is the role of the `requestTokens` to make this HTTP POST.
|
||||
|
@ -332,7 +332,7 @@ data Customer = Customer {
|
|||
Here is the code that display the homepage.
|
||||
It should contain a link to the the `/login` URL.
|
||||
When the user will click on this link it will be redirected to Google login page
|
||||
with some generated informations.
|
||||
with some generated information.
|
||||
|
||||
The page also display the content of the local storage.
|
||||
And in particular the items `api-key` and `user-id`.
|
||||
|
@ -366,7 +366,7 @@ instance ToMarkup Homepage where
|
|||
We need some helpers to generate random string for generating state and API Keys.
|
||||
|
||||
``` haskell
|
||||
-- | generate a random Bystestring, not necessarily extremely good randomness
|
||||
-- | generate a random ByteString, not necessarily extremely good randomness
|
||||
-- still the password will be long enough to be very difficult to crack
|
||||
genRandomBS :: IO ByteString
|
||||
genRandomBS = do
|
||||
|
|
|
@ -18,7 +18,7 @@ For example: `Range: createdAt 2017-01-15T23:14:67.000Z; offset 5; order desc` i
|
|||
the client is willing to retrieve the next batch of document in descending order that were
|
||||
created after the fifteenth of January, skipping the first 5.
|
||||
|
||||
As a response, the server may return the list of corresponding document, and augment the
|
||||
As a response, the server may return the list of corresponding documents, and augment the
|
||||
response with 3 headers:
|
||||
|
||||
- `Accept-Ranges`: A comma-separated list of fields upon which a range can be defined
|
||||
|
@ -127,7 +127,7 @@ defaultRange =
|
|||
getDefaultRange (Proxy @Color)
|
||||
```
|
||||
|
||||
Note that `getFieldValue :: Proxy "name" -> Color -> String` is the minimal complete definintion
|
||||
Note that `getFieldValue :: Proxy "name" -> Color -> String` is the minimal complete definition
|
||||
of the class. Yet, you can define `getRangeOptions` to provide different parsing options (see
|
||||
the last section of this guide). In the meantime, we've also defined a `defaultRange` as it will
|
||||
come in handy when defining our handler.
|
||||
|
@ -148,7 +148,7 @@ type MyHeaders =
|
|||
```
|
||||
|
||||
`PageHeaders` is a type alias provided by the library to declare the necessary response headers
|
||||
we mentionned in introduction. Expanding the alias boils down to the following:
|
||||
we mentioned in introduction. Expanding the alias boils down to the following:
|
||||
|
||||
``` haskell
|
||||
-- type MyHeaders =
|
||||
|
@ -165,7 +165,7 @@ not, _servant-pagination_ provides an easy way to lift a collection of resources
|
|||
#### Server
|
||||
|
||||
Time to connect the last bits by defining the server implementation of our colorful API. The `Ranges`
|
||||
type we've defined above (tight to the `Range` HTTP header) indicates the server to parse any `Range`
|
||||
type we've defined above (tied to the `Range` HTTP header) indicates the server to parse any `Range`
|
||||
header, looking for the format defined in introduction with fields and target types we have just declared.
|
||||
If no such header is provided, we will end up receiving `Nothing`. Otherwise, it will be possible
|
||||
to _extract_ a `Range` from our `Ranges`.
|
||||
|
@ -192,7 +192,7 @@ the format we defined, where `<field>` here can only be `name` and `<value>` mus
|
|||
- `Range: <field> [<value>][; offset <o>][; limit <l>][; order <asc|desc>]`
|
||||
|
||||
Beside the target field, everything is pretty much optional in the `Range` HTTP header. Missing parts
|
||||
are deducted from the `RangeOptions` that are part of the `HasPagination` instance. Therefore, all
|
||||
are deduced from the `RangeOptions` that are part of the `HasPagination` instance. Therefore, all
|
||||
following examples are valid requests to send to our server:
|
||||
|
||||
- 1 - `curl http://localhost:1442/colors -vH 'Range: name'`
|
||||
|
@ -219,7 +219,7 @@ The previous ranges reads as follows:
|
|||
Note that in the simple above scenario, there's no ambiguity with `extractRange` and `returnRange`
|
||||
because there's only one possible `Range` defined on our resource. Yet, as you've most probably
|
||||
noticed, the `Ranges` combinator accepts a list of fields, each of which must declare a `HasPagination`
|
||||
instance. Doing so will make the other helper functions more ambiguous and type annotation are
|
||||
instance. Doing so will make the other helper functions more ambiguous and type annotations are
|
||||
highly likely to be needed.
|
||||
|
||||
|
||||
|
@ -235,8 +235,8 @@ instance HasPagination Color "hex" where
|
|||
#### Parsing Options
|
||||
|
||||
By default, `servant-pagination` provides an implementation of `getRangeOptions` for each
|
||||
`HasPagination` instance. However, this can be overwritten when defining the instance to provide
|
||||
your own options. This options come into play when a `Range` header is received and isn't fully
|
||||
`HasPagination` instance. However, this can be overridden when defining the instance to provide
|
||||
your own options. These options come into play when a `Range` header is received and isn't fully
|
||||
specified (`limit`, `offset`, `order` are all optional) to provide default fallback values for those.
|
||||
|
||||
For instance, let's say we wanted to change the default limit to `5` in a new range on
|
||||
|
|
|
@ -79,7 +79,7 @@ It does three things. First it initializes the service which will communicate wi
|
|||
|
||||
- the Sentry `DSN`, which is obtained when creating a new project on Sentry
|
||||
- a default way to update sentry fields, where we use the identity function
|
||||
- an event trasport, which generally would be `sendRecord`, an HTTPS capable trasport which uses http-conduit
|
||||
- an event transport, which generally would be `sendRecord`, an HTTPS capable transport which uses http-conduit
|
||||
- a fallback handler, which we choose to be `silentFallback` since later we are logging to the console anyway.
|
||||
|
||||
In the second step it actually sends our message to Sentry with the `register` function. Its arguments are:
|
||||
|
|
|
@ -144,7 +144,7 @@ simpleAPIServer
|
|||
:: m [a]
|
||||
-> (i -> m a)
|
||||
-> (a -> m NoContent)
|
||||
-> Server (SimpleAPI name a i) m
|
||||
-> ServerT (SimpleAPI name a i) m
|
||||
simpleAPIServer listAs getA postA =
|
||||
listAs :<|> getA :<|> postA
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Using a custom monad
|
||||
|
||||
In this section we will create and API for a book shelf without any backing DB storage.
|
||||
In this section we will create an API for a book shelf without any backing DB storage.
|
||||
We will keep state in memory and share it between requests using `Reader` monad and `STM`.
|
||||
|
||||
We start with a pretty standard set of imports and definition of the model:
|
||||
|
|
|
@ -141,7 +141,7 @@ and calling the continuation. We should get a `Pure` value.
|
|||
Pure n ->
|
||||
putStrLn $ "Expected 1764, got " ++ show n
|
||||
_ ->
|
||||
putStrLn "ERROR: didn't got a response"
|
||||
putStrLn "ERROR: didn't get a response"
|
||||
```
|
||||
|
||||
So that's it. Using `Free` we can evaluate servant clients step-by-step, and
|
||||
|
|
|
@ -108,7 +108,7 @@ API with "private." Additionally, the private parts of our API use the
|
|||
realm for this authentication is `"foo-realm"`).
|
||||
|
||||
Unfortunately we're not done. When someone makes a request to our `"private"`
|
||||
API, we're going to need to provide to servant the logic for validifying
|
||||
API, we're going to need to provide to servant the logic for validating
|
||||
usernames and passwords. This adds a certain conceptual wrinkle in servant's
|
||||
design that we'll briefly discuss. If you want the **TL;DR**: we supply a lookup
|
||||
function to servant's new `Context` primitive.
|
||||
|
@ -260,7 +260,7 @@ this.
|
|||
|
||||
Let's implement a trivial authentication scheme. We will protect our API by
|
||||
looking for a cookie named `"servant-auth-cookie"`. This cookie's value will
|
||||
contain a key from which we can lookup a `Account`.
|
||||
contain a key from which we can lookup an `Account`.
|
||||
|
||||
```haskell
|
||||
-- | An account type that we "fetch from the database" after
|
||||
|
@ -274,7 +274,7 @@ database = fromList [ ("key1", Account "Anne Briggs")
|
|||
, ("key3", Account "Ghédalia Tazartès")
|
||||
]
|
||||
|
||||
-- | A method that, when given a password, will return a Account.
|
||||
-- | A method that, when given a password, will return an Account.
|
||||
-- This is our bespoke (and bad) authentication logic.
|
||||
lookupAccount :: ByteString -> Handler Account
|
||||
lookupAccount key = case Map.lookup key database of
|
||||
|
@ -346,7 +346,7 @@ genAuthServerContext = authHandler :. EmptyContext
|
|||
|
||||
-- | Our API, where we provide all the author-supplied handlers for each end
|
||||
-- point. Note that 'privateDataFunc' is a function that takes 'Account' as an
|
||||
-- argument. We dont' worry about the authentication instrumentation here,
|
||||
-- argument. We don't worry about the authentication instrumentation here,
|
||||
-- that is taken care of by supplying context
|
||||
genAuthServer :: Server AuthGenAPI
|
||||
genAuthServer =
|
||||
|
@ -385,11 +385,11 @@ Creating a generalized, ad-hoc authentication scheme was fairly straight
|
|||
forward:
|
||||
|
||||
1. use the `AuthProtect` combinator to protect your API.
|
||||
2. choose a application-specific data type used by your server when
|
||||
2. choose an application-specific data type used by your server when
|
||||
authentication is successful (in our case this was `Account`).
|
||||
3. Create a value of `AuthHandler Request Account` which encapsulates the
|
||||
authentication logic (`Request -> Handler Account`). This function
|
||||
will be executed everytime a request matches a protected route.
|
||||
will be executed every time a request matches a protected route.
|
||||
4. Provide an instance of the `AuthServerData` type family, specifying your
|
||||
application-specific data type returned when authentication is successful (in
|
||||
our case this was `Account`).
|
||||
|
|
|
@ -161,7 +161,7 @@ The types of the arguments for the functions are the same as for (server-side) r
|
|||
## Changing the monad the client functions live in
|
||||
|
||||
Just like `hoistServer` allows us to change the monad in which request handlers
|
||||
of a web application live in, we also have `hoistClient` for changing the monad
|
||||
of a web application live, we also have `hoistClient` for changing the monad
|
||||
in which _client functions_ live. Consider the following trivial API:
|
||||
|
||||
``` haskell
|
||||
|
@ -173,7 +173,7 @@ hoistClientAPI = Proxy
|
|||
|
||||
We already know how to derive client functions for this API, and as we have
|
||||
seen above they all return results in the `ClientM` monad when using `servant-client`.
|
||||
However, `ClientM` rarely (or never) is the actual monad we need to use the client
|
||||
However, `ClientM` is rarely (or never) the actual monad we need to use the client
|
||||
functions in. Sometimes we need to run them in IO, sometimes in a custom monad
|
||||
stack. `hoistClient` is a very simple solution to the problem of "changing" the monad
|
||||
the clients run in.
|
||||
|
|
|
@ -77,7 +77,7 @@ instance ToSample HelloMessage where
|
|||
[ ("When a value is provided for 'name'", HelloMessage "Hello, Alp")
|
||||
, ("When 'name' is not specified", HelloMessage "Hello, anonymous coward")
|
||||
]
|
||||
-- mutliple examples to display this time
|
||||
-- multiple examples to display this time
|
||||
|
||||
ci :: ClientInfo
|
||||
ci = ClientInfo "Alp" "alp@foo.com" 26 ["haskell", "mathematics"]
|
||||
|
@ -108,7 +108,7 @@ apiDocs = docs exampleAPI
|
|||
markdown :: API -> String
|
||||
```
|
||||
|
||||
That lets us see what our API docs look down in markdown, by looking at `markdown apiDocs`.
|
||||
That lets us see what our API docs look like in markdown, by looking at `markdown apiDocs`.
|
||||
|
||||
````````` text
|
||||
## GET /hello
|
||||
|
|
|
@ -228,13 +228,13 @@ data CommonGeneratorOptions = CommonGeneratorOptions
|
|||
{
|
||||
-- | function generating function names
|
||||
functionNameBuilder :: FunctionName -> Text
|
||||
-- | name used when a user want to send the request body (to let you redefine it)
|
||||
-- | name used when a user wants to send the request body (to let you redefine it)
|
||||
, requestBody :: Text
|
||||
-- | name of the callback parameter when the request was successful
|
||||
, successCallback :: Text
|
||||
-- | name of the callback parameter when the request reported an error
|
||||
, errorCallback :: Text
|
||||
-- | namespace on which we define the js function (empty mean local var)
|
||||
-- | namespace on which we define the js function (empty means local var)
|
||||
, moduleName :: Text
|
||||
-- | a prefix that should be prepended to the URL in the generated JS
|
||||
, urlPrefix :: Text
|
||||
|
|
|
@ -183,7 +183,7 @@ users2 = [isaac, albert]
|
|||
|
||||
Now, just like we separate the various endpoints in `UserAPI` with `:<|>`, we
|
||||
are going to separate the handlers with `:<|>` too! They must be provided in
|
||||
the same order as in in the API type.
|
||||
the same order as in the API type.
|
||||
|
||||
``` haskell
|
||||
server2 :: Server UserAPI2
|
||||
|
@ -716,7 +716,7 @@ $ curl --verbose http://localhost:8081/myfile.txt
|
|||
>
|
||||
< HTTP/1.1 404 Not Found
|
||||
[snip]
|
||||
myfile.txt just isnt there, please leave this server alone.
|
||||
myfile.txt just isn't there, please leave this server alone.
|
||||
|
||||
$ echo Hello > myfile.txt
|
||||
|
||||
|
@ -818,7 +818,7 @@ If it doesn't exist, the handler will fail with a `404` status code.
|
|||
|
||||
`serveDirectoryWebApp` uses some standard settings that fit the use case of
|
||||
serving static files for most web apps. You can find out about the other
|
||||
options in the documentation of the `Servant.Utils.StaticFiles` module.
|
||||
options in the documentation of the `Servant.Server.StaticFiles` module.
|
||||
|
||||
## Nested APIs
|
||||
|
||||
|
@ -1135,7 +1135,7 @@ true
|
|||
### An arrow is a reader too.
|
||||
|
||||
In previous versions of `servant` we had an `enter` to do what `hoistServer`
|
||||
does now. `enter` had a ambitious design goals, but was problematic in practice.
|
||||
does now. `enter` had an ambitious design goals, but was problematic in practice.
|
||||
|
||||
One problematic situation was when the source monad was `(->) r`, yet it's
|
||||
handy in practice, because `(->) r` is isomorphic to `Reader r`.
|
||||
|
@ -1166,7 +1166,7 @@ back a *stream* of results, served one at a time. Stream endpoints only provide
|
|||
a single content type, and also specify what framing strategy is used to
|
||||
delineate the results. To serve these results, we need to give back a stream
|
||||
producer. Adapters can be written to *Pipes*, *Conduit* and the like, or
|
||||
written directly as `SourceIO`s. SourceIO builts upon servant's own `SourceT`
|
||||
written directly as `SourceIO`s. SourceIO builds upon servant's own `SourceT`
|
||||
stream type (it's simpler than *Pipes* or *Conduit*).
|
||||
The API of a streaming endpoint needs to explicitly specify which sort of
|
||||
generator it produces. Note that the generator itself is returned by a
|
||||
|
|
|
@ -205,7 +205,7 @@
|
|||
|
||||
- *servant-client-core* Add `hoistClient` to `HasClient`.
|
||||
Just like `hoistServer` allows us to change the monad in which request handlers
|
||||
of a web application live in, we also have `hoistClient` for changing the monad
|
||||
of a web application live, we also have `hoistClient` for changing the monad
|
||||
in which *client functions* live.
|
||||
Read [tutorial section for more information](https://docs.servant.dev/en/release-0.14/tutorial/Client.html#changing-the-monad-the-client-functions-live-in).
|
||||
([#936](https://github.com/haskell-servant/servant/pull/936))
|
||||
|
|
|
@ -104,7 +104,7 @@ test-suite spec
|
|||
, base-compat
|
||||
, servant-client-core
|
||||
|
||||
-- Additonal dependencies
|
||||
-- Additional dependencies
|
||||
build-depends:
|
||||
deepseq >= 1.4.2.0 && < 1.5
|
||||
, hspec >= 2.6.0 && < 2.8
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
|
||||
- *servant-client-core* Add `hoistClient` to `HasClient`.
|
||||
Just like `hoistServer` allows us to change the monad in which request handlers
|
||||
of a web application live in, we also have `hoistClient` for changing the monad
|
||||
of a web application live, we also have `hoistClient` for changing the monad
|
||||
in which *client functions* live.
|
||||
Read [tutorial section for more information](https://docs.servant.dev/en/release-0.14/tutorial/Client.html#changing-the-monad-the-client-functions-live-in).
|
||||
([#936](https://github.com/haskell-servant/servant/pull/936))
|
||||
|
|
|
@ -120,7 +120,7 @@ test-suite spec
|
|||
, wai
|
||||
, warp
|
||||
|
||||
-- Additonal dependencies
|
||||
-- Additional dependencies
|
||||
build-depends:
|
||||
entropy >= 0.4.1.3 && < 0.5
|
||||
, hspec >= 2.6.0 && < 2.8
|
||||
|
|
|
@ -130,7 +130,7 @@ withClientM cm env k =
|
|||
-- streaming response types ('SourceT', 'Conduit', pipes 'Proxy' or 'Machine').
|
||||
-- For those you have to use 'withClientM'.
|
||||
--
|
||||
-- /Note:/ we 'force' the result, so the likehood of accidentally leaking a
|
||||
-- /Note:/ we 'force' the result, so the likelihood of accidentally leaking a
|
||||
-- connection is smaller. Use with care.
|
||||
--
|
||||
runClientM :: NFData a => ClientM a -> ClientEnv -> IO (Either ClientError a)
|
||||
|
|
|
@ -57,7 +57,7 @@ You'll also note that multiple intros are possible.
|
|||
|
||||
This is some text
|
||||
|
||||
### Second secton
|
||||
### Second section
|
||||
|
||||
And some more
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ test-suite spec
|
|||
, servant-docs
|
||||
, string-conversions
|
||||
|
||||
-- Additonal dependencies
|
||||
-- Additional dependencies
|
||||
build-depends:
|
||||
tasty >= 1.1.0.4 && < 1.3,
|
||||
tasty-golden >= 2.3.2 && < 2.4,
|
||||
|
|
|
@ -396,7 +396,7 @@ docsWithOptions p = docsFor p (defEndpoint, defAction)
|
|||
-- > extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete)) $
|
||||
-- > defAction & headers <>~ ["unicorns"]
|
||||
-- > & notes <>~ [ DocNote "Title" ["This is some text"]
|
||||
-- > , DocNote "Second secton" ["And some more"]
|
||||
-- > , DocNote "Second section" ["And some more"]
|
||||
-- > ]
|
||||
|
||||
extraInfo :: (IsIn endpoint api, HasLink endpoint, HasDocs endpoint)
|
||||
|
|
|
@ -77,7 +77,7 @@ test-suite spec
|
|||
, servant
|
||||
, servant-foreign
|
||||
|
||||
-- Additonal dependencies
|
||||
-- Additional dependencies
|
||||
build-depends:
|
||||
hspec >= 2.6.0 && <2.8
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ listFromAPISpec = describe "listFromAPI" $ do
|
|||
shouldBe putReq $ defReq
|
||||
{ _reqUrl = Url
|
||||
[ Segment $ Static "test" ]
|
||||
-- Shoud this be |intX| or |listX of intX| ?
|
||||
-- Should this be |intX| or |listX of intX| ?
|
||||
[ QueryArg (Arg "params" "listX of intX") List ]
|
||||
, _reqMethod = "PUT"
|
||||
, _reqHeaders = []
|
||||
|
|
|
@ -114,7 +114,7 @@ test-suite spec
|
|||
, wai
|
||||
, warp
|
||||
|
||||
-- Additonal dependencies
|
||||
-- Additional dependencies
|
||||
build-depends:
|
||||
entropy >= 0.4.1.3 && < 0.5
|
||||
, hspec >= 2.6.0 && < 2.8
|
||||
|
|
|
@ -77,7 +77,7 @@ _ = client comprehensiveAPIWithoutStreaming
|
|||
|
||||
spec :: Spec
|
||||
spec = describe "Servant.HttpStreams" $ do
|
||||
sucessSpec
|
||||
successSpec
|
||||
failSpec
|
||||
wrappedApiSpec
|
||||
basicAuthSpec
|
||||
|
@ -262,8 +262,8 @@ runClientUnsafe x burl = withClientEnvIO burl (runClientMUnsafe x)
|
|||
where
|
||||
runClientMUnsafe x env = withClientM x env return
|
||||
|
||||
sucessSpec :: Spec
|
||||
sucessSpec = beforeAll (startWaiApp server) $ afterAll endWaiApp $ do
|
||||
successSpec :: Spec
|
||||
successSpec = beforeAll (startWaiApp server) $ afterAll endWaiApp $ do
|
||||
it "Servant.API.Get root" $ \(_, baseUrl) -> do
|
||||
left show <$> runClient getRoot baseUrl `shouldReturn` Right carol
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
Some APIs need query parameters rewriting, e.g. in order to support
|
||||
for multiple casing (camel, snake, etc) or something to that effect.
|
||||
|
||||
This could be easily achieved by using WAI Middleware and modyfing
|
||||
This could be easily achieved by using WAI Middleware and modifying
|
||||
request's `Query`. But QueryParam, QueryParams and QueryFlag use
|
||||
`rawQueryString`. By using `queryString` rather then `rawQueryString`
|
||||
we can enable such rewritings.
|
||||
|
@ -44,7 +44,7 @@
|
|||
|
||||
We used `build-type: Custom`, but it's problematic e.g.
|
||||
for cross-compiling. The benefit is small, as the doctests
|
||||
can be run other ways too (though not so conviniently).
|
||||
can be run other ways too (though not so conveniently).
|
||||
|
||||
0.16.2
|
||||
------
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
- `greet.hs` shows how to write a simple webservice, run it, query it with automatically-derived haskell functions and print the (generated) markdown documentation for the API.
|
||||
- `greet.md` contains the aforementionned generated documentation.
|
||||
- `greet.md` contains the aforementioned generated documentation.
|
|
@ -155,7 +155,7 @@ test-suite spec
|
|||
, transformers-compat
|
||||
, wai
|
||||
|
||||
-- Additonal dependencies
|
||||
-- Additional dependencies
|
||||
build-depends:
|
||||
aeson >= 1.4.1.0 && < 1.5
|
||||
, directory >= 1.3.0.0 && < 1.4
|
||||
|
|
|
@ -808,7 +808,7 @@ instance (HasContextEntry context (NamedContext name subContext), HasServer subA
|
|||
instance TypeError (HasServerArrowKindError arr) => HasServer ((arr :: k -> l) :> api) context
|
||||
where
|
||||
type ServerT (arr :> api) m = TypeError (HasServerArrowKindError arr)
|
||||
-- it doens't really matter what sub route we peak
|
||||
-- it doesn't really matter what sub route we peak
|
||||
route _ _ _ = error "servant-server panic: impossible happened in HasServer (arr :> api)"
|
||||
hoistServerWithContext _ _ _ = id
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import Servant.Server.Internal.ServerError
|
|||
-- * Basic Auth
|
||||
|
||||
-- | servant-server's current implementation of basic authentication is not
|
||||
-- immune to certian kinds of timing attacks. Decoding payloads does not take
|
||||
-- immune to certain kinds of timing attacks. Decoding payloads does not take
|
||||
-- a fixed amount of time.
|
||||
|
||||
-- | The result of authentication/authorization
|
||||
|
|
|
@ -20,7 +20,7 @@ import GHC.TypeLits
|
|||
--
|
||||
-- If you are using combinators that require a non-empty 'Context' you have to
|
||||
-- use 'Servant.Server.serveWithContext' and pass it a 'Context' that contains all
|
||||
-- the values your combinators need. A 'Context' is essentially a heterogenous
|
||||
-- the values your combinators need. A 'Context' is essentially a heterogeneous
|
||||
-- list and accessing the elements is being done by type (see 'getContextEntry').
|
||||
-- The parameter of the type 'Context' is a type-level list reflecting the types
|
||||
-- of the contained context entries. To create a 'Context' with entries, use the
|
||||
|
|
|
@ -268,5 +268,5 @@ runAction action env req respond k = runResourceT $
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Due to GHC issue <https://ghc.haskell.org/trac/ghc/ticket/2595 2595>, we cannot
|
||||
do the more succint thing - just update the records we actually change.
|
||||
do the more succinct thing - just update the records we actually change.
|
||||
-}
|
||||
|
|
|
@ -24,7 +24,7 @@ import Servant.Server.Internal.ServerError
|
|||
|
||||
-- | Computations used in a 'Delayed' can depend on the
|
||||
-- incoming 'Request', may perform 'IO', and result in a
|
||||
-- 'RouteResult', meaning they can either suceed, fail
|
||||
-- 'RouteResult', meaning they can either succeed, fail
|
||||
-- (with the possibility to recover), or fail fatally.
|
||||
--
|
||||
newtype DelayedIO a = DelayedIO { runDelayedIO' :: ReaderT Request (ResourceT (RouteResultT IO)) a }
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
Some APIs need query parameters rewriting, e.g. in order to support
|
||||
for multiple casing (camel, snake, etc) or something to that effect.
|
||||
|
||||
This could be easily achieved by using WAI Middleware and modyfing
|
||||
This could be easily achieved by using WAI Middleware and modifying
|
||||
request's `Query`. But QueryParam, QueryParams and QueryFlag use
|
||||
`rawQueryString`. By using `queryString` rather then `rawQueryString`
|
||||
we can enable such rewritings.
|
||||
|
@ -50,7 +50,7 @@
|
|||
|
||||
We used `build-type: Custom`, but it's problematic e.g.
|
||||
for cross-compiling. The benefit is small, as the doctests
|
||||
can be run other ways too (though not so conviniently).
|
||||
can be run other ways too (though not so conveniently).
|
||||
|
||||
- *servant* Remove deprecated modules [1268#](https://github.com/haskell-servant/servant/pull/1268)
|
||||
|
||||
|
@ -405,7 +405,7 @@
|
|||
|
||||
- *servant-client-core* Add `hoistClient` to `HasClient`.
|
||||
Just like `hoistServer` allows us to change the monad in which request handlers
|
||||
of a web application live in, we also have `hoistClient` for changing the monad
|
||||
of a web application live, we also have `hoistClient` for changing the monad
|
||||
in which *client functions* live.
|
||||
Read [tutorial section for more information](https://docs.servant.dev/en/release-0.14/tutorial/Client.html#changing-the-monad-the-client-functions-live-in).
|
||||
([#936](https://github.com/haskell-servant/servant/pull/936))
|
||||
|
@ -612,7 +612,7 @@
|
|||
|
||||
`enter` isn't exported from `Servant` module anymore. You can change
|
||||
`enter` to `hoistServer` in a straight forward way.
|
||||
Unwrap natural transformation and add a api type `Proxy`:
|
||||
Unwrap natural transformation and add an api type `Proxy`:
|
||||
|
||||
```diff
|
||||
-server = enter (NT nt) impl
|
||||
|
|
|
@ -157,7 +157,7 @@ test-suite spec
|
|||
, text
|
||||
, transformers
|
||||
|
||||
-- Additonal dependencies
|
||||
-- Additional dependencies
|
||||
build-depends:
|
||||
hspec >= 2.6.0 && < 2.8
|
||||
, QuickCheck >= 2.12.6.1 && < 2.15
|
||||
|
|
|
@ -95,7 +95,7 @@ type family HeaderValMap (f :: * -> *) (xs :: [*]) where
|
|||
|
||||
class BuildHeadersTo hs where
|
||||
buildHeadersTo :: [HTTP.Header] -> HList hs
|
||||
-- ^ Note: if there are multiple occurences of a header in the argument,
|
||||
-- ^ Note: if there are multiple occurrences of a header in the argument,
|
||||
-- the values are interspersed with commas before deserialization (see
|
||||
-- <http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 RFC2616 Sec 4.2>)
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
-- >>> toUrlPiece $ safeLink api without
|
||||
-- "bye"
|
||||
--
|
||||
-- If you would like create a helper for generating links only within that API,
|
||||
-- If you would like to create a helper for generating links only within that API,
|
||||
-- you can partially apply safeLink if you specify a correct type signature
|
||||
-- like so:
|
||||
--
|
||||
|
@ -65,7 +65,7 @@
|
|||
-- >>> apiLink = safeLink api
|
||||
-- >>> :}
|
||||
--
|
||||
-- `safeLink'` allows to make specialise the output:
|
||||
-- `safeLink'` allows you to specialise the output:
|
||||
--
|
||||
-- >>> safeLink' toUrlPiece api without
|
||||
-- "bye"
|
||||
|
@ -563,7 +563,7 @@ instance HasLink sub => HasLink (AuthProtect tag :> sub) where
|
|||
type MkLink (AuthProtect tag :> sub) a = MkLink sub a
|
||||
toLink = simpleToLink (Proxy :: Proxy sub)
|
||||
|
||||
-- | Helper for implemneting 'toLink' for combinators not affecting link
|
||||
-- | Helper for implementing 'toLink' for combinators not affecting link
|
||||
-- structure.
|
||||
simpleToLink
|
||||
:: forall sub a combinator.
|
||||
|
|
Loading…
Reference in a new issue