git.iko.soy/typeable/servant
on master help sign in
More cookbook improvements (#1305)

* Simplify code in CurlMock cookbook recipe * Link to latest versions of packages on hackage * Fix grammar in the OpenIdConnect recipe * HasForeignType -> HasForeign

commit8e7b538921bf32bef2f83bf15e4c229dd317a975 authorJan Hrcek <2716069+jhrcek@users.noreply.github.com> dateWed 10 Jun 2020, 18:36 (6 years ago) parentb9d8fbc
5 files changed+24−36
doc/cookbook/curl-mock/CurlMock.lhs+7−19 doc/cookbook/https/Https.lhs+5−5 doc/cookbook/open-id-connect/OpenIdConnect.lhs+9−9 doc/cookbook/sentry/Sentry.lhs+1−1 doc/tutorial/Server.lhs+2−2
doc/cookbook/curl-mock/CurlMock.lhs+7−19
@@ -86,7 +86,7 @@ listFromAPI :: (HasForeign lang ftype api, GenerateList ftype (Foreign ftype api
8686```
8787
8888This looks a bit confusing...
89−[Here](https://hackage.haskell.org/package/servant-foreign-0.11.1/docs/Servant-Foreign.html#t:HasForeignType) is the documentation for the `HasForeign` typeclass.
89+[Here](https://hackage.haskell.org/package/servant-foreign/docs/Servant-Foreign.html#t:HasForeign) is the documentation for the `HasForeign` typeclass.
9090We will not go into details here, but this allows us to create a value of type `ftype` for any type `a` in our API.
9191
9292In our case we want to create a mock of every type `a`.
@@ -130,24 +130,12 @@ generateCurl :: (GenerateList Mocked (Foreign Mocked api), HasForeign NoLang Moc
130130generateCurl p host =
131131 fmap T.unlines body
132132 where
133− body = foldr (\endp curlCalls -> mCons (generateEndpoint host endp) curlCalls) (return [])
133+ body = mapM (generateEndpoint host)
134134 $ listFromAPI (Proxy :: Proxy NoLang) (Proxy :: Proxy Mocked) p
135135```
136136
137−To understand this function, better start at the end:
138−
139−`listFromAPI` gives us a list of endpoints. We iterate over them (`foldr`) and call `generateEndpoint` for every endpoint.
140−
141−As generate endpoint will not return `Text` but `IO Text` (remember we need some random bits to mock), we cannot just use the cons operator but need to build `IO [Text]` from `IO Text`s.
142−
143−``` haskell
144−mCons :: IO a -> IO [a] -> IO [a]
145−mCons ele list =
146− ele >>= \e -> list >>= \l -> return ( e : l )
147−```
148−
149−
150−Now comes the juicy part; accessing the endpoints data:
137+First, `listFromAPI` gives us a list of `Req Mocked`. Each `Req` describes one endpoint from the API type.
138+We generate a curl call for each of them using the following helper.
151139
152140``` haskell
153141generateEndpoint :: Text -> Req Mocked -> IO Text
@@ -169,7 +157,7 @@ generateEndpoint host req =
169157`servant-foreign` offers a multitude of lenses to be used with `Req`-values.
170158
171159`reqMethod` gives us a straigthforward `Network.HTTP.Types.Method`, `reqUrl` the url part and so on.
172−Just take a look at [the docs](https://hackage.haskell.org/package/servant-foreign-0.11.1/docs/Servant-Foreign.html).
160+Just take a look at [the docs](https://hackage.haskell.org/package/servant-foreign/docs/Servant-Foreign.html).
173161
174162But how do we get our mocked json string? This seems to be a bit to short to be true:
175163
@@ -201,7 +189,7 @@ And now, lets hook it all up in our main function:
201189``` haskell
202190main :: IO ()
203191main =
204− generateCurl api "localhost:8081" >>= (\v -> T.IO.putStrLn v)
192+ generateCurl api "localhost:8081" >>= T.IO.putStrLn
205193```
206194
207195Done:
@@ -213,6 +201,6 @@ curl -X POST -d '{"email":"wV򝣀_b򆎘:z񁊞򲙲!(3DM V","age":10,"name":"=|W"}
213201```
214202
215203This is of course no complete curl call mock generator, many things including path arguments are missing.
216−But it correctly generate mock calls for simple POST requests.
204+But it correctly generates mock calls for simple POST requests.
217205
218206Also, we now know how to use `HasForeignType` and `listFromAPI` to generate anything we want.
doc/cookbook/https/Https.lhs+5−5
@@ -34,16 +34,16 @@ app = serve api server
3434```
3535
3636It's now time to actually run the `Application`.
37−The [`warp-tls`](https://hackage.haskell.org/package/warp-tls-3.2.4/docs/Network-Wai-Handler-WarpTLS.html)
37+The [`warp-tls`](https://hackage.haskell.org/package/warp-tls/docs/Network-Wai-Handler-WarpTLS.html)
3838package provides two functions for running an `Application`, called
39−[`runTLS`](https://hackage.haskell.org/package/warp-tls-3.2.4/docs/Network-Wai-Handler-WarpTLS.html#v:runTLS)
40−and [`runTLSSocket`](https://hackage.haskell.org/package/warp-tls-3.2.4/docs/Network-Wai-Handler-WarpTLS.html#v:runTLSSocket).
39+[`runTLS`](https://hackage.haskell.org/package/warp-tls/docs/Network-Wai-Handler-WarpTLS.html#v:runTLS)
40+and [`runTLSSocket`](https://hackage.haskell.org/package/warp-tls/docs/Network-Wai-Handler-WarpTLS.html#v:runTLSSocket).
4141We will be using the first one.
4242
4343It takes two arguments,
44−[the TLS settings](https://hackage.haskell.org/package/warp-tls-3.2.4/docs/Network-Wai-Handler-WarpTLS.html#t:TLSSettings)
44+[the TLS settings](https://hackage.haskell.org/package/warp-tls/docs/Network-Wai-Handler-WarpTLS.html#t:TLSSettings)
4545(certificates, keys, ciphers, etc)
46−and [the warp settings](https://hackage.haskell.org/package/warp-3.2.12/docs/Network-Wai-Handler-Warp-Internal.html#t:Settings)
46+and [the warp settings](https://hackage.haskell.org/package/warp/docs/Network-Wai-Handler-Warp-Internal.html#t:Settings)
4747(port, logger, etc).
4848
4949We will be using very simple settings for this example but you are of
doc/cookbook/open-id-connect/OpenIdConnect.lhs+9−9
@@ -9,7 +9,7 @@ some login token would be saved in the user agent local storage.
99Workflow:
1010
11111. user is presented with a login button,
12−2. when the user click on the button it is redirected to the OIDC
12+2. when the user clicks on the button it is redirected to the OIDC
1313 provider,
14143. the user login in the OIDC provider,
15154. the OIDC provider will redirect the user and provide a `code`,
@@ -221,7 +221,7 @@ The `AuthInfo` is about the infos we can grab from OIDC provider.
221221
222222To be more precise, the user should come with a `code` (a token) and
223223POSTing that code to the correct OIDC provider endpoint should return a JSON
224−object. One of the field should be named `id_token` which should be a
224+object. One of the fields should be named `id_token` which should be a
225225JWT containing all the information we need. Depending on the scopes we
226226asked we might get more information.
227227
@@ -252,12 +252,12 @@ The `handleLoggedIn` is that part that will retrieve the information from
252252the user once he is redirected from the OIDC Provider after login.
253253
254254If the user is redirected to the `redirect_uri` but with an `error` query
255−parameter then it means something goes wrong.
255+parameter then it means something went wrong.
256256If there is no error query param but a `code` query param it means the user
257257successfully logged in. From there we need to make a request to the token
258−endpoint of the OIDC provider. Its a POST that should contains the code
259−as well as the client id & secret.
260−This is the role of the `requestTokens` to make this HTTP POST.
258+endpoint of the OIDC provider. It's a POST that should contain the code
259+as well as the client id and secret.
260+Making this HTTP POST is the responsibility of `requestTokens`.
261261
262262From there we extract the `claims` of the JWT contained in one of the value
263263of the JSON returned by the POST HTTP Request.
@@ -329,12 +329,12 @@ data Customer = Customer {
329329 }
330330```
331331
332−Here is the code that display the homepage.
332+Here is the code that displays the homepage.
333333It should contain a link to the the `/login` URL.
334−When the user will click on this link it will be redirected to Google login page
334+When the user clicks on this link it will be redirected to Google login page
335335with some generated information.
336336
337−The page also display the content of the local storage.
337+The page also displays the content of the local storage.
338338And in particular the items `api-key` and `user-id`.
339339Those items should be set after a successful login when the user is redirected to
340340`/login/cb`.
doc/cookbook/sentry/Sentry.lhs+1−1
@@ -86,7 +86,7 @@ In the second step it actually sends our message to Sentry with the `register` f
8686
8787- the configured Sentry service which we just created
8888- the name of the logger
89−- the error level (see [SentryLevel](https://hackage.haskell.org/package/raven-haskell-0.1.2.0/docs/System-Log-Raven-Types.html#t:SentryLevel) for the possible options)
89+- the error level (see [SentryLevel](https://hackage.haskell.org/package/raven-haskell/docs/System-Log-Raven-Types.html#t:SentryLevel) for the possible options)
9090- the message we want to send
9191- an update function to handle the specific `SentryRecord`
9292
doc/tutorial/Server.lhs+2−2
@@ -620,7 +620,7 @@ In short, this means that a handler of type `Handler a` is simply
620620equivalent to a computation of type `IO (Either ServerError a)`, that is, an IO
621621action that either returns an error or a result.
622622
623−The module [`Control.Monad.Except`](https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Except.html#t:ExceptT)
623+The module [`Control.Monad.Except`](https://hackage.haskell.org/package/mtl/docs/Control-Monad-Except.html#t:ExceptT)
624624from which `ExceptT` comes is worth looking at.
625625Perhaps most importantly, `ExceptT` and `Handler` are instances of `MonadError`, so
626626`throwError` can be used to return an error from your handler (whereas `return`
@@ -634,7 +634,7 @@ kind and abort early. The next two sections cover how to do just that.
634634
635635Other important instances from the list above are `MonadIO m => MonadIO
636636(ExceptT e m)`, and therefore also `MonadIO Handler` as there is a `MonadIO IO` instance.
637−[`MonadIO`](http://hackage.haskell.org/package/transformers-0.4.3.0/docs/Control-Monad-IO-Class.html)
637+[`MonadIO`](http://hackage.haskell.org/package/base/docs/Control-Monad-IO-Class.html#t:MonadIO)
638638is a class from the **transformers** package defined as:
639639
640640``` haskell ignore