-
Notifications
You must be signed in to change notification settings - Fork 22
/
jug.html
434 lines (414 loc) · 30.5 KB
/
jug.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Getting started with Jug • jug</title>
<!-- jquery --><script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha384-nrOSfDHtoPMzJHjVTdCopGqIqeYETSXhZDFyniQ8ZHcVy08QesyHcnOUpMpqnmWq" crossorigin="anonymous"></script><!-- Bootstrap --><link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script><!-- Font Awesome icons --><link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
<!-- pkgdown --><link href="../pkgdown.css" rel="stylesheet">
<script src="../jquery.sticky-kit.min.js"></script><script src="../pkgdown.js"></script><!-- mathjax --><script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container template-vignette">
<header><div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">jug</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>
<a href="../reference/index.html">Reference</a>
</li>
<li>
<a href="../articles/index.html">Articles</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="https://github.com/Bart6114/jug">
<span class="fa fa-github fa-lg"></span>
</a>
</li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
<!--/.container -->
</div>
<!--/.navbar -->
</header><div class="row">
<div class="col-md-9">
<div class="page-header toc-ignore">
<h1>Getting started with Jug</h1>
<h4 class="author">Bart Smeets</h4>
<h4 class="date">2017-04-06</h4>
</div>
<div class="contents">
<p><em>generated using Jug version 0.1.6</em></p>
<div id="hello-world" class="section level2">
<h2 class="hasAnchor">
<a href="#hello-world" class="anchor"></a>Hello World!</h2>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">library</span>(jug)
<span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="st">"/"</span>, function(req, res, err){
<span class="st">"Hello World!"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/simple_error_handler_json.html">simple_error_handler_json</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<pre><code>Serving the jug at http://127.0.0.1:8080</code></pre>
</div>
<div id="what-is-jug" class="section level2">
<h2 class="hasAnchor">
<a href="#what-is-jug" class="anchor"></a>What is Jug?</h2>
<p>Jug is a small web development framework for R which relies heavily upon the <code>httpuv</code> package. It’s main focus is to make building APIs for your code as easy as possible.</p>
<p>Jug is not supposed to be either an especially performant nor an uber stable web framework. Other tools (and languages) might be more suited for that. It’s main focus is to easily allow you to create APIs for your R code. However, the flexibility of Jug means that, in theory, you could built an extensive web framework with it.</p>
</div>
<div id="getting-started" class="section level2">
<h2 class="hasAnchor">
<a href="#getting-started" class="anchor"></a>Getting started</h2>
<p>To install the latest version use <code>devtools</code>:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">devtools::<span class="kw">install_github</span>(<span class="st">"Bart6114/jug"</span>)</code></pre></div>
<p>Or install the CRAN version:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">install.packags</span>(<span class="st">"jug"</span>)</code></pre></div>
<p>Load the library:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">library</span>(jug)</code></pre></div>
</div>
<div id="the-jug-instance" class="section level2">
<h2 class="hasAnchor">
<a href="#the-jug-instance" class="anchor"></a>The Jug instance</h2>
<p>Everything starts with a Jug instance. This instance is created by simply calling <code><a href="../reference/Jug.html">jug()</a></code>:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>()</code></pre></div>
<pre><code>## A Jug instance with 0 middlewares attached</code></pre>
<p>Jug is made to work closely with the piping functionality of <code>magrittr</code> (<code>%>%</code>). The configuration of the Jug instance is set up by piping the instance through the various functions explained below.</p>
</div>
<div id="middleware" class="section level2">
<h2 class="hasAnchor">
<a href="#middleware" class="anchor"></a>Middleware</h2>
<p>In terms of middleware, Jug somewhat follows the specification of middleware by <code>Express</code>. In Jug, middleware is a function with access to the <strong>request</strong> (<code>req</code>), <strong>response</strong> (<code>res</code>) and <strong>error</strong> (<code>err</code>) object.</p>
<p>Multiple middlewares can be defined. The order in which the middlewares are added matters. A request will start with being passed through the first middleware added (more specifically the functions specified in it - see next paragraph). It will continue to be passed through the added middlewares until a middleware does not return <code>NULL</code> (note: if a value is set using e.g. <code>res$json("foo")</code> the body will not be <code>NULL</code>). Whatever will be passed by that middleware will be set as the response body.</p>
<p>Most middleware will accept a <code>func</code> or <code>...</code> argument to which respectively a function or multiple functions can be passed. If multiple functions are passed; the order in which they are passed will be respected when processing a request. To each function the <code>req</code>, <code>res</code> and <code>err</code> objects will be passed (and they thus should accept them).</p>
<div id="method-insensitive-middleware" class="section level3">
<h3 class="hasAnchor">
<a href="#method-insensitive-middleware" class="anchor"></a>Method insensitive middleware</h3>
<p>The <code>use</code> function is a method insensitive middleware specifier. While it is method insensitive, it can be bound to a specific path. If the <code>path</code> argument (accepts a regex string with <code>grepl</code> setting <code>perl=TRUE</code>) is set to <code>NULL</code> it also becomes path insensitive and will process <em>every</em> request.</p>
<p>A path insensitive example:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/use.html">use</a></span>(<span class="dt">path =</span> <span class="ot">NULL</span>, function(req, res, err){
<span class="st">"test 1,2,3!"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<pre><code>$ curl 127.0.0.1:8080/xyz
test 1,2,3!</code></pre>
<p>The same example, but path sensitive:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/use.html">use</a></span>(<span class="dt">path =</span> <span class="st">"/"</span>, function(req, res, err){
<span class="st">"test 1,2,3!"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<pre><code>$ curl 127.0.0.1:8080/xyz
curl: (52) Empty reply from server
$ curl 127.0.0.1:8080
test 1,2,3!</code></pre>
<p>It is however possible to specify a method to bind to using <code>use</code> (check out <code><a href="../reference/use.html">?use</a></code>), this way you can process request methods for which no prespecified middlewares exist.</p>
<p>Note that in the above example errors / missing route handling is missing (the server might crash / not respond), more on that later.</p>
</div>
<div id="method-sensitive-middleware" class="section level3">
<h3 class="hasAnchor">
<a href="#method-sensitive-middleware" class="anchor"></a>Method sensitive middleware</h3>
<p>In the same style as the request method insensitive middleware, there is request method sensitive middleware available. More specifically, you can use the <code>get</code>, <code>post</code>, <code>put</code> and <code>delete</code> functions.</p>
<p>This type of middleware is bound to a path using the <code>path</code> argument. If <code>path</code> is set to <code>NULL</code> it will bind to every request to the path, given that it is of the corresponding request method.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="dt">path =</span> <span class="st">"/"</span>, function(req, res, err){
<span class="st">"get test 1,2,3!"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<pre><code>$ curl 127.0.0.1:8080
get test 1,2,3!</code></pre>
<p>Middlewares are meant to be chained, so to bind different functions to different paths:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="dt">path =</span> <span class="st">"/"</span>, function(req, res, err){
<span class="st">"get test 1,2,3 on path /"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="dt">path =</span> <span class="st">"/my_path"</span>, function(req, res, err){
<span class="st">"get test 1,2,3 on path /my_path"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<pre><code>$ curl 127.0.0.1:8080
get test 1,2,3 on path /
$ curl 127.0.0.1:8080/my_path
get test 1,2,3 on path /my_path</code></pre>
</div>
<div id="websocket-protocol" class="section level3">
<h3 class="hasAnchor">
<a href="#websocket-protocol" class="anchor"></a>Websocket protocol</h3>
<p>By default all middleware convenience function bind to the http protocol. You can however access the jug server through websocket by using the websocket sensitive middleware function <code>ws</code>. Below an example echo’ing the incoming message.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/ws.html">ws</a></span>(<span class="st">"/echo_message"</span>, function(binary, message, res, err){
message
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<p>Opening a connection to <code>ws://127.0.0.1:8080/echo_message</code> and sending e.g. the message <code>test</code> to it will then return the value <code>test</code>.</p>
<p><strong>Please note that websocket support is experimental at this stage.</strong></p>
</div>
<div id="including-elsewhere-defined-middleware-chains" class="section level3">
<h3 class="hasAnchor">
<a href="#including-elsewhere-defined-middleware-chains" class="anchor"></a>Including elsewhere defined middleware chains</h3>
<p>In order to make you code more modular, you can include elsewhere defined middleware chains into your Jug instance. To do this you can use a combination of the <code><a href="../reference/collector.html">collector()</a></code> and <code><a href="../reference/include.html">include()</a></code> functions.</p>
<p>Below a <code>collector</code> is defined locally (in the same R script) and <code>include</code>d.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"> collected_mw<-
<span class="st"> </span><span class="kw"><a href="../reference/collector.html">collector</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="st">"/"</span>, function(req,res,err){
<span class="kw">return</span>(<span class="st">"test"</span>)
})
res<-<span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/include.html">include</a></span>(collected_mw) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<p>However, it is also possible to <code>include</code> a <code>collector</code> that is defined in another .R file.</p>
<p>Let’s say below is the file <code>my_middlewares.R</code>:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">library</span>(jug)
collected_mw<-
<span class="st"> </span><span class="kw"><a href="../reference/collector.html">collector</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="st">"/"</span>, function(req,res,err){
<span class="kw">return</span>(<span class="st">"test2"</span>)
})</code></pre></div>
<p>We can include it as follows:</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">res<-<span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/include.html">include</a></span>(collected_mw, <span class="st">"my_middlewares.R"</span>) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
</div>
</div>
<div id="predefined-middleware" class="section level2">
<h2 class="hasAnchor">
<a href="#predefined-middleware" class="anchor"></a>Predefined middleware</h2>
<div id="error-handling" class="section level3">
<h3 class="hasAnchor">
<a href="#error-handling" class="anchor"></a>Error handling</h3>
<p>A simple error handling middleware (<code>simple_error_handler</code> / <code>simple_error_handler_json</code>) which catches unbound paths and <code>func</code> evaluation errors. If you do not implement a custom error handler, I suggest you add either of these to your Jug instance. The <code>simple_error_handler</code> returns an HTML error page while the <code>simple_error_handler_json</code> returns a JSON message.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/simple_error_handler.html">simple_error_handler</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<pre><code>$ curl 127.0.0.1:8080
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Not found</title>
</head>
<body>
<p>No handler bound to path</p>
</body>
</html></code></pre>
<p>If you want to implement your own custom error handling just have a look at the code of these simple error handling middlewares.</p>
<p>Please note that generally you would like the error handler middleware to be attached to the Jug instance after all other middleware has been specified.</p>
</div>
<div id="easily-using-your-own-functions" class="section level3">
<h3 class="hasAnchor">
<a href="#easily-using-your-own-functions" class="anchor"></a>Easily using your own functions</h3>
<p>The main reason Jug was created is to easily allow access to your own custom R functions. The convenience function <code>decorate</code> is built especially for this purpose.</p>
<p>If you <code>decorate</code> your own function it will translate all arguments passed in the query string of the request as arguments to your function. It will also pass all headers to the function as arguments.</p>
<p>If your function does not accept a <code>...</code> argument, all query/header parameters that are not explicitly requested by your function are dropped. If your function requests a <code>req</code>, <code>res</code> or <code>err</code> argument (or <code>...</code>) the corresponding objects will be passed.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">say_hello<-function(name){<span class="kw">paste</span>(<span class="st">"hello"</span>,name,<span class="st">"!"</span>)}
<span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="st">"/"</span>, <span class="kw"><a href="../reference/decorate.html">decorate</a></span>(say_hello)) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<p>If in the above, you pass a parameter <code>name</code> through either the query string or as a header in the GET request, it will return as in the example below.</p>
<pre><code>$ curl 127.0.0.1:8080/?name=Bart
hello Bart !</code></pre>
</div>
<div id="static-file-server" class="section level3">
<h3 class="hasAnchor">
<a href="#static-file-server" class="anchor"></a>Static file server</h3>
<p>The <code>serve_static_file</code> middleware allows for serving static files.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_static_files.html">serve_static_files</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<p>The default root directory is the one returned by <code>getwd()</code> but can be specified by providing a <code>root_path</code> argument to the <code>serve_static_files</code> middleware. It transforms a bare <code>/</code> path to <code>index.html</code>.</p>
<p>Aside from development, I do not recommend using Jug to serve static files.</p>
</div>
<div id="cors-functionality" class="section level3">
<h3 class="hasAnchor">
<a href="#cors-functionality" class="anchor"></a>CORS functionality</h3>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS">CORS functionality</a> is introduced by the <code><a href="../reference/cors.html">cors()</a></code> middleware function.</p>
<p>Consider the following example.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/cors.html">cors</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="st">"/"</span>, function(req, res, err){
<span class="st">"Hello World!"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<pre><code>$ curl -v 127.0.0.1:8080/
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: POST,GET,PUT,OPTIONS,DELETE,PATCH
< Content-Length: 12
<
* Connection #0 to host 127.0.0.1 left intact</code></pre>
<p>As you see this adds some default CORS-headers. Check out <code><a href="../reference/cors.html">?cors</a></code> for the configuration options, note that you can also add CORS headers to a specific path by specifying the <code>path</code> parameter.</p>
</div>
<div id="authentication" class="section level3">
<h3 class="hasAnchor">
<a href="#authentication" class="anchor"></a>Authentication</h3>
<p>Currently there is only built-in support for basic authentication (check: <a href="https://www.httpwatch.com/httpgallery/authentication/" class="uri">https://www.httpwatch.com/httpgallery/authentication/</a>) through the <code>auth_basic</code> middleware function. The middleware will check the request for a valid username / password combination. If an invalid combination is passed, it will return a 401 status, a <code>WWW-Authenticate</code> header and a text body which states that there was an authentication error.</p>
<p>First you will need to define a function that accepts <code>username</code> and <code>password</code> arguments. The funtion should return <code>TRUE</code> if the combination is valid and <code>FALSE</code> if the combination is invalid. A dummy example is shown below. Note, that this function could also check e.g. a database to validate the combo.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="co"># dummy account checker</span>
account_checker <-<span class="st"> </span>function(username, password){
<span class="co"># do something to verify the username and password and return TRUE if combination OK</span>
<span class="kw">all</span>(username ==<span class="st"> "test_user"</span>,
password ==<span class="st"> "test_password"</span>)
}</code></pre></div>
<p>Next you need to instantiate the <code>auth_basic</code> middleware in you middleware chain. The <code>auth_basic</code> function accepts as first parameter the username/password validation function. Below two examples are given. The first one shows how to do authentication for a specific path (<code>/test</code>).</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="st">"/"</span>, function(req, res, err){
<span class="st">"/ req"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="st">"/test"</span>, <span class="kw"><a href="../reference/auth_basic.html">auth_basic</a></span>(account_checker), function(req, res, err){
<span class="st">"/test req"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
<p>The second example below shows how to activate basic authentication for all paths in the jug instance.</p>
<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw"><a href="../reference/Jug.html">jug</a></span>() %>%
<span class="st"> </span><span class="kw"><a href="../reference/use.html">use</a></span>(<span class="ot">NULL</span>, <span class="kw"><a href="../reference/auth_basic.html">auth_basic</a></span>(account_checker)) %>%
<span class="st"> </span><span class="kw"><a href="../reference/get.html">get</a></span>(<span class="st">"/"</span>, function(req, res, err){
<span class="st">"/ req"</span>
}) %>%
<span class="st"> </span><span class="kw"><a href="../reference/serve_it.html">serve_it</a></span>()</code></pre></div>
</div>
</div>
<div id="the-request-response-and-error-objects" class="section level2">
<h2 class="hasAnchor">
<a href="#the-request-response-and-error-objects" class="anchor"></a>The request, response and error objects</h2>
<div id="request-req-object" class="section level3">
<h3 class="hasAnchor">
<a href="#request-req-object" class="anchor"></a>Request (<code>req</code>) object</h3>
<p>The <code>req</code> object contains the request specifications. It has different attributes:</p>
<ul>
<li>
<code>req$params</code> a named list of the parameters passed by either the query string, a JSON body, URL parameters or a multipart form</li>
<li>
<code>req$path</code> the request path</li>
<li>
<code>req$method</code> the request method</li>
<li>
<code>req$raw</code> the raw request object as passsed by <code>httpuv</code>
</li>
<li>
<code>req$body</code> the full request body as a character string</li>
<li>
<code>req$protocol</code> either <code>http</code> or <code>websocket</code>
</li>
<li>
<code>req$headers</code> a named list of the headers in the request (as lowercase and stripped from the <code>HTTP_</code> prefix provided by the underlying <code>httpuv</code> framework)</li>
</ul>
<p>It has the following functions attached to it:</p>
<ul>
<li>
<code>req$get_header(key)</code> returns the value associated to the specified key in the request (no need to worry about the <code>HTTP_</code> prefix)</li>
<li>
<code>req$set_header(key, value)</code> allows to set / alter a header while processing the request (can be useful to pass data to the next middleware)</li>
<li>
<code>req$attach(key, value)</code> attach a variable to <code>req$params</code>
</li>
</ul>
</div>
<div id="response-res-object" class="section level3">
<h3 class="hasAnchor">
<a href="#response-res-object" class="anchor"></a>Response (<code>res</code>) object</h3>
<p>The <code>res</code> object contains the response specifications. It has different attributes:</p>
<ul>
<li>
<code>res$headers</code> a named list of the set headers</li>
<li>
<code>res$status</code> the status of the response (defaults to 200)</li>
<li>
<code>res$body</code> the body of the response (is automatically set to be the content of the not <code>NULL</code> returning middleware or by methods such as <code>res$json()</code>)</li>
</ul>
<p>It also has a set of functions:</p>
<ul>
<li>
<code>res$set_header(key, value)</code> set a custom header</li>
<li>
<code>res$content_type(type)</code> set your own content type (MIME)</li>
<li>
<code>res$set_status(status)</code> set the status of the response</li>
<li>
<code>res$text(body)</code> to explicitely set the body of the response</li>
<li>
<code>res$json(obj, auto_unbox=TRUE)</code> converts an object to JSON, sets it as the body and set the correct content type</li>
<li>
<code>res$plot(plot_obj, base64=TRUE)</code> convenience function to return a plot object as the response body, the returned plot can either be a base64 representation of the image (default) or the actual binary data</li>
</ul>
</div>
<div id="error-err-object" class="section level3">
<h3 class="hasAnchor">
<a href="#error-err-object" class="anchor"></a>Error (<code>err</code>) object</h3>
<p>The <code>err</code> object contains a list of errors, accessible through <code>err$errrors</code>. You can add an error to this list by calling <code>err$set(error)</code>. The error will be converted to a character.</p>
<p>Refer to the “Error handling” paragraph for more details.</p>
</div>
</div>
<div id="url-dispatching" class="section level2">
<h2 class="hasAnchor">
<a href="#url-dispatching" class="anchor"></a>URL dispatching</h2>
<p>The path parameter in the <code>get</code>, <code>post</code>, … functions are processed as being regex patterns.</p>
<p>If there are named capture groups in the path definition, they will be attached to the <code>req$params</code> object. For example the pattern <code>/test/(?<id>.*)/(?<id2>.*)</code> will result in the variables <code>id</code> and <code>id2</code> (with their respective values) being bound to the <code>req$params</code> object.</p>
<p>If a path pattern is not started with a start of string <code>^</code> regex token <strong>or</strong> ended with an end of string token <code>$</code>, these will be explicitely inserted at respectively the beginning and end of the path pattern specification. For example the path pattern <code>/</code> will be converted to <code>^/$</code>.</p>
</div>
<div id="starting-the-jug-instance" class="section level2">
<h2 class="hasAnchor">
<a href="#starting-the-jug-instance" class="anchor"></a>Starting the Jug instance</h2>
<p>Simply call <code><a href="../reference/serve_it.html">serve_it()</a></code> at the end of your piping chain (see Hello World! example).</p>
</div>
<div id="further-examples" class="section level2">
<h2 class="hasAnchor">
<a href="#further-examples" class="anchor"></a>Further examples</h2>
<p><a href="https://github.com/Bart6114/jug-crud-example">Minimal CRUD TODO app</a></p>
</div>
</div>
</div>
<div class="col-md-3 hidden-xs hidden-sm" id="sidebar">
<div id="tocnav">
<h2>Contents</h2>
<ul class="nav nav-pills nav-stacked">
<li><a href="#hello-world">Hello World!</a></li>
<li><a href="#what-is-jug">What is Jug?</a></li>
<li><a href="#getting-started">Getting started</a></li>
<li><a href="#the-jug-instance">The Jug instance</a></li>
<li><a href="#middleware">Middleware</a></li>
<li><a href="#predefined-middleware">Predefined middleware</a></li>
<li><a href="#the-request-response-and-error-objects">The request, response and error objects</a></li>
<li><a href="#url-dispatching">URL dispatching</a></li>
<li><a href="#starting-the-jug-instance">Starting the Jug instance</a></li>
<li><a href="#further-examples">Further examples</a></li>
</ul>
</div>
</div>
</div>
<footer><div class="copyright">
<p>Developed by Bart Smeets.</p>
</div>
<div class="pkgdown">
<p>Site built with <a href="http://hadley.github.io/pkgdown/">pkgdown</a>.</p>
</div>
</footer>
</div>
</body>
</html>