You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/tutorial/Javascript.lhs
+75-31Lines changed: 75 additions & 31 deletions
Original file line number
Diff line number
Diff line change
@@ -1,9 +1,7 @@
1
1
# Generating Javascript functions to query an API
2
2
3
-
We will now see how *servant* lets you turn an API type into javascript
4
-
functions that you can call to query a webservice. The derived code assumes you
5
-
use *jQuery* but you could very easily adapt the code to generate ajax requests
6
-
based on vanilla javascript or another library than *jQuery*.
3
+
We will now see how **servant** lets you turn an API type into javascript
4
+
functions that you can call to query a webservice.
7
5
8
6
For this, we will consider a simple page divided in two parts. At the top, we
9
7
will have a search box that lets us search in a list of Haskell books by
@@ -32,10 +30,11 @@ import Data.Aeson
32
30
import Data.Proxy
33
31
import Data.Text as T (Text)
34
32
import Data.Text.IO as T (writeFile, readFile)
35
-
import qualified Data.Text as T
36
33
import GHC.Generics
37
34
import Language.Javascript.JQuery
38
35
import Network.Wai
36
+
import Network.Wai.Handler.Warp
37
+
import qualified Data.Text as T
39
38
import Servant
40
39
import Servant.JS
41
40
import System.Random
@@ -78,7 +77,8 @@ book :: Text -> Text -> Int -> Book
78
77
book = Book
79
78
```
80
79
81
-
We need a "book database". For the purpose of this guide, let's restrict ourselves to the following books.
80
+
We need a "book database". For the purpose of this guide, let's restrict
81
+
ourselves to the following books.
82
82
83
83
``` haskell
84
84
books :: [Book]
@@ -92,7 +92,10 @@ books =
92
92
]
93
93
```
94
94
95
-
Now, given an optional search string `q`, we want to perform a case insensitive search in that list of books. We're obviously not going to try and implement the best possible algorithm, this is out of scope for this tutorial. The following simple linear scan will do, given how small our list is.
95
+
Now, given an optional search string `q`, we want to perform a case insensitive
96
+
search in that list of books. We're obviously not going to try and implement
97
+
the best possible algorithm, this is out of scope for this tutorial. The
98
+
following simple linear scan will do, given how small our list is.
96
99
97
100
``` haskell
98
101
searchBook :: Monad m => Maybe Text -> m (Search Book)
We also need an endpoint that generates random points `(x, y)` with `-1 <= x,y <= 1`. The code below uses [random](http://hackage.haskell.org/package/random)'s `System.Random`.
112
+
We also need an endpoint that generates random points `(x, y)` with `-1 <= x,y
Why two different API types, proxies and servers though? Simply because we don't want to generate javascript functions for the `Raw` part of our API type, so we need a `Proxy` for our API type `API'` without its `Raw` endpoint.
148
+
Why two different API types, proxies and servers though? Simply because we
149
+
don't want to generate javascript functions for the `Raw` part of our API type,
150
+
so we need a `Proxy` for our API type `API'` without its `Raw` endpoint.
141
151
142
-
Very similarly to how one can derive haskell functions, we can derive the javascript with just a simple function call to `jsForAPI` from `Servant.JQuery`.
152
+
Very similarly to how one can derive haskell functions, we can derive the
153
+
javascript with just a simple function call to `jsForAPI` from
154
+
`Servant.JQuery`.
143
155
144
156
``` haskell
145
157
apiJS :: Text
146
158
apiJS = jsForAPI api vanillaJS
147
159
```
148
160
149
-
This `String` contains 2 Javascript functions:
161
+
This `Text` contains 2 Javascript functions, 'getPoint' and 'getBooks':
Right before starting up our server, we will need to write this `String` to a file, say `api.js`, along with a copy of the *jQuery* library, as provided by the [js-jquery](http://hackage.haskell.org/package/js-jquery) package.
207
+
We created a directory `static` that contains two static files: `index.html`,
208
+
which is the entrypoint to our little web application; and `ui.js`, which
209
+
contains some hand-written javascript. This javascript code assumes the two
210
+
generated functions `getPoint` and `getBooks` in scope. Therefore we need to
And we're good to go. Start the server with `dist/build/tutorial/tutorial 9` and go to `http://localhost:8081/`. Start typing in the name of one of the authors in our database or part of a book title, and check out how long it takes to approximate π using the method mentioned above.
221
+
(We're also writing the jquery library into a file, as it's also used by
222
+
`ui.js`.) `static/api.js` will be included in `index.html` and the two
223
+
generated functions will therefore be available in `ui.js`.
224
+
225
+
And we're good to go. You can start the `main` function of this file and go to
226
+
`http://localhost:8000/`. Start typing in the name of one of the authors in our
227
+
database or part of a book title, and check out how long it takes to
0 commit comments