-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathdocs.html
572 lines (493 loc) · 39.1 KB
/
docs.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
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
<!-- TODO: switch to new layout for docs -->
<div class="blog-area">
<h1>Documentation</h1>
<div class="container">
<div class="row">
<!-- blog-left-sidebar start -->
<div class="col-lg-3 col-md-3 col-sm-3">
<div class="widget_area fix">
<!-- widget-categories start -->
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Getting Started</h3>
<ul class="sidebar_menu">
<li><a href="{{appUrl}}/faq">What is a Microservice?</a></li>
<li><a href="{{appUrl}}/faq">Don't start a server!</a></li>
<li><a href="#language" class="i18n">Choosing a Language</a></li>
<li><a href="{{appUrl}}/examples" class="i18n">Interactive Examples</a></li>
<li><a href="{{appUrl}}/editor" class="i18n">Interactive Playground</a></li>
<li><a href="#creating" class="i18n">Creating a Service</a></li>
<li><a href="#forking" class="i18n">Forking an existing Service</a></li>
</ul>
</aside>
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Running Services</h3>
<ul class="sidebar_menu">
<li><a href="#running" class="i18n">Running a Service</a></li>
<li><a href="#hook" class="i18n">The Hook object</a></li>
<li><a href="#logs" class="i18n">Debugging and Logs</a></li>
<li><a href="#events" class="i18n">System Events Logs</a></li>
<li><a href="#hot-code" class="i18n">Hot-code Gateways</a></li>
</ul>
</aside>
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Sending Data to Services</h3>
<ul class="sidebar_menu">
<li><a href="#data" class="i18n">Sending Data to a Service</a></li>
<li><a href="#content-type" class="i18n">Content-Type Routing</a></li>
<li><a href="#content-type" class="i18n">Streaming HTTP Support</a></li>
<li><a href="{{appUrl}}/curl" class="i18n">UNIX Pipe Support</a></li>
<li><a href="{{appUrl}}/sdk" class="i18n">Client SDK</a></li>
</ul>
</aside>
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Managing Services</h3>
<ul class="sidebar_menu">
<li><a href="#admin" class="i18n">Admin Panel</a></li>
<li><a href="#code" class="i18n">Editing a Service</a></li>
<li><a href="#env" class="i18n">Environment variables</a></li>
<li><a href="#rateLimits" class="i18n">Rate Limits</a></li>
<li><a href="#concurrency" class="i18n">Concurrency Limits</a></li>
<li><a href="#timeouts" class="i18n">Custom Service Timeouts</a></li>
<li><a href="#viewsource" class="i18n">Service Source Code</a></li>
</ul>
</aside>
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Service Features</h3>
<ul class="sidebar_menu">
<li><a href="#schema" class="i18n">Service Input Schema</a></li>
<!--
<li><a href="#forms" class="i18n">Schema Form Generator</a></li>
-->
<!-- <li><a href="#themes" class="i18n">Themes</a></li> -->
<li><a href="{{appUrl}}/cron" class="i18n">Schedule Cronjob</a></li>
<!-- <li><a href="#cache" class="i18n">Cache Controls</a></li> -->
</ul>
</aside>
<!--
<ul style="font-size:22px;">
<li>
Restricting Access to Services
<ul>
<li><a href="#keys" class="i18n">Creating API Access Keys</a></li>
<li><a href="#keys" class="i18n">Restricting access to Services ( private hooks )</a></li>
<li><a href="#roles" class="i18n">Using Role Based Access Control ( RBAC )</a></li>
</ul>
</li>
<li>Additional Platform Features
<ul>
<li><a href="#datastore" class="i18n">Using the Cloud Datastore</a></li>
<li><a href="#files" class="i18n">Using the Multi-Cloud Virtual File System</a></li>
<li><a href="#domains" class="i18n">Setting Custom Domains</a></li>
<li><a href="#events" class="i18n">Accessing System Events</a></li>
<li><a href="#api" class="i18n">Using {{appName}} through it's HTTP API</a></li>
<li><a href="#ssl" class="i18n">SSL / HTTPS</a></li>
</ul>
</li>
</ul>
-->
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Role Based Access</h3>
<ul class="sidebar_menu">
<li><a href="#keys" class="i18n">API Access Keys</a></li>
<li><a href="#keys" class="i18n">Restricting Service Access</a></li>
<li><a href="#roles" class="i18n">Custom Role Checks</a></li>
</ul>
</aside>
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Logging and Events</h3>
<ul class="sidebar_menu">
<li><a href="{{appUrl}}/logs">Service Logs</a></li>
<li><a href="{{appUrl}}/events">System Events</a></li>
</ul>
</aside>
<!-- <li><a href="#metrics">Hook Metrics</a></li> -->
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Multi-Cloud Databases</h3>
<ul class="sidebar_menu">
<li><a href="{{appUrl}}/databases">Documentation </a></li>
</ul>
</aside>
<!-- widget-categories end -->
<!-- widget-categories start -->
<aside class="left_widget blog_border0">
<h3 class="sidebar_middle_title">Multi-Cloud File Storage</h3>
<ul class="sidebar_menu">
<li><a href="{{appUrl}}/files">Documentation </a></li>
</ul>
</aside>
<!-- widget-categories end -->
<!-- widget-tag start -->
<aside class="left_middle_widget">
<h3 class="sidebar_middle_title">Platform Technologies</h3>
<ul class="tag">
<!-- TODO: add feature tag cloud, use many tags -->
</ul>
<!--
<div class="view_all">
<a href="">View All Technologies</a>
</div>
-->
</aside>
<!-- end widget-tag -->
</div>
</div>
<!--end blog-left-sidebar start -->
<!-- shop-content start -->
<div class="col-lg-9 col-md-9 col-sm-9">
<!-- end single blog item-->
<div class="col-lg-12 col-md-12 col-sm-12 item">
<div class="content">
<style>
.content p {
/*font-size: 20px;*/
}
.content h2 {
/*font-weight: bold;*/
}
.warning {
color: red;
}
.documentation li {
padding-top:10px;
padding-bottom:10px;
}
.documentation ul {
padding-top:10px;
padding-bottom:10px;
}
</style>
<div align="left" class="documentation">
<div class="docsHeader">
<!-- <h1 class="i18n">Documentation</h1> -->
</div>
<div class="content">
<h2 class="i18n">Getting Started</h2>
<p class="i18n">A Hook is single function or block of code represented by a unique URL.</p>
<p class="i18n">The Hook can be executed by sending HTTP requests to this URL.</p>
<p><span class="i18n">To see live examples of using Hooks visit the:</span> <a class="i18n" href="{{appUrl}}/editor">Interactive Microservice Tutorial</a></p>
<p><span>To see example Hooks which you can <a href="#forking">fork</a> visit:</span> <a class="i18n" href="{{appUrl}}/examples">Examples</a></p>
<p>
<ul style="font-size:22px;">
<li><a href="#datastore" class="i18n">Getting Started</a></li>
<li><a href="#files" class="i18n">Running Services</a></li>
<li><a href="#domains" class="i18n">Sending Data to Services</a></li>
<li><a href="#events" class="i18n">Managing Services</a></li>
<li><a href="#api" class="i18n">Service Features</a></li>
<li><a href="#ssl" class="i18n">Role Based Access Control</a></li>
<li><a href="#ssl" class="i18n">Logging and Events</a></li>
<li><a href="#ssl" class="i18n">Multi-Cloud Databases</a></li>
<li><a href="#ssl" class="i18n">Multi-Cloud File Storage</a></li>
<!-- <li><a href="#metrics">Hook Metrics</a></li> -->
</ul>
</p>
<hr/>
<a name="language"></a>
<h2 class="i18n">Choosing a Programming Language</h2>
<p class="i18n">{{appName}} supports writing services in other programming languages besides JavaScript. </p>
<ul style="font-size:18px;" class="programmingLanguages">
</ul>
<p class="i18n">You may select new languages while creating or editing a service.</p>
<p><a class="i18n" href="{{appUrl}}/editor">Click here for an Interactive Microservice Tutorial</a></p>
<a name="creating"></a>
<h2 class="i18n">Creating a Hook</h2>
<p><span class="i18n">To create a Hook visit: </span><a href="{{appUrl}}/new">{{appUrl}}/new</a></p>
<!--
<p class="i18n">On this page, the following properties can be specified to create a Hook:</p>
<p> <strong class="i18n">Name</strong> <em class="i18n">required</em> - <span class="i18n">Name of hook</span></p>
<p> <strong class="i18n">Path</strong> <em class="i18n">optional</em> - <span class="i18n">url regex route for the hook. Supports named parameters, splats, and groups.</span></p>
<p> <strong class="i18n">Gist</strong> <em class="i18n">required</em> - <span class="i18n">Source code of the Hook as a Github Gist</span></p>
<p> <strong class="i18n">Theme</strong> <em class="i18n">optional</em> - <span class="i18n">A View-Presenter that will render the output of the Hook, see:</span> <a href="{{appUrl}}/themes">Themes</a></p>
<p> <strong class="i18n">Cron</strong> <em class="i18n">optional</em> - <span class="i18n">Run this Hook on a Cron schedule, see: </span><a class="i18n" href="{{appUrl}}/cron">Cron</a></p>
-->
<a name="forking"></a>
<h2 class="i18n">Forking an existing Hook</h2>
<p>To fork another Hook, simply add <code>/fork</code> to the url of the Hook you want to fork.</p>
<p class="i18n">By specifying the <code>fork</code> parameter, you will be taken to a new page where you can start customizing your Fork.</p>
<p class="i18n">Once a Hook is created the browser will redirect to the admin page for that Hook.</p>
<p><strong class="i18n">Try It Now:</strong> <a href="{{appUrl}}/examples/echo/fork">{{appUrl}}/examples/echo/fork</a></p>
<p><strong class="i18n">Many Examples To Fork From:</strong> <a href="{{appUrl}}/examples">{{appUrl}}/examples</a></p>
<hr/>
<a name="running"></a>
<h2 class="i18n">Running a Hook</h2>
<p class="i18n">Hooks are automatically executed when an HTTP request is sent to the Hook's url.</p>
<p class="i18n">This HTTP request can be sent from any source ( such as the browser, custom application, or the command line).</p>
<h3 class="warning">Important Note about Service Timeouts:</h3>
<p>All hooks have a <code>10 second</code> timeout value by default. If the execution of your service takes longer then this value, the client will receive a <code>service timeout</code> error message.</p>
<p>In the majority of cases, <strong>a time-out</strong> indicates that the service failed to end properly and <strong>usually indicates a programming error</strong>.</p>
<p align="center"><strong>Attempting to run an HTTP or TCP server in a Hook will not work! <br/>Hooks are microservices ( think functions ), not servers.</strong>
<p>In some other cases, you may be dealing with transferring a larger amount of data from a third-party service and the default timeout of ten seconds is not long enough to complete the transmission.</p>
<p> If you think your service may require more than 10 seconds to execute, {{appName}} allows for <a href="#timeouts">Custom Timeouts</a> per service.</p>
<hr/>
<a name="viewsource"></a>
<h2 class="i18n">View Hook Source</h2>
<p class="i18n">To view the source code of any Hook simply attach <code>/_src</code> to the Hook service url.</p>
<!-- <p class="i18n">This will also work for the Hook's <code>View</code>and <code>Presenter</code>.</p> -->
<p><strong class="i18n">Source Code:</strong> <a href="{{appUrl}}/examples/echo/_src">{{appUrl}}/examples/echo/_src</a></p>
<p><strong class="i18n">Logs:</strong> <a href="{{appUrl}}/examples/echo/logs">{{appUrl}}/examples/echo/logs</a></p>
<p><strong class="i18n">Resource:</strong> <a href="{{appUrl}}/examples/echo/resource">{{appUrl}}/examples/echo/resource</a></p>
<p><strong class="i18n">View:</strong> <a href="{{appUrl}}/examples/echo/view">{{appUrl}}/examples/echo/view</a></p>
<!-- <p><strong class="i18n">Presenter:</strong> <a href="{{appUrl}}/examples/echo/presenter">{{appUrl}}/examples/echo/presenter</a></p> -->
<p class="i18n">If you require the source code of a Hook to remain private, upgrade to a <a href="{{appUrl}}/pricing">paid account</a> and set the Hook to <code>Private</code>
<a name="admin"></a>
<h2 class="i18n">Hook Admin Panel</h2>
<p class="i18n">To access the Administration page for a Hook simply attach <code>/admin</code> to the Hook service url.</p>
<p class="i18n">This will only work for Hooks which you own.</p>
<a name="logs"></a>
<hr/>
<h2 class="i18n">Hook Debugging and Logs</h2>
<p class="i18n">{{appName}} provides a seamless streaming log service which Hooks can write to with <code>console.log</code>. Simply call <code>console.log</code> from inside the Hook source code and the logging statement will be saved.</p>
<p class="i18n">Streaming log endpoints are available for real-time consumption on all Hook service urls as <code>/logs</code>.</p>
<p><strong>Example:</strong> <a href="{{appUrl}}/examples/echo/logs">{{appUrl}}/examples/echo/logs</a>
<p>Complete logging documentation can be found at <a href="{{appUrl}}/logs">{{appUrl}}/logs</a>
<a name="data"></a>
<hr/>
<h2 class="i18n">Sending data to the Hook</h2>
<p class="i18n">Data can be sent to a Hook through any methods HTTP supports.</p>
<p class="i18n">The most common way to send data to a Hook is through the URL query string or posted through forms or binary data transfers.</p>
<h3><strong class="i18n">Query String Data</strong></h3>
<p class="i18n">To add a parameter via query string simply append it to the url of the Hook</p>
<p><strong class="i18n">Example:</strong> <a href="{{appUrl}}/examples/echo?foo=bar&hello=there&run=true">{{appUrl}}/examples/echo?foo=bar&hello=there&run=true</a></p>
<p class="i18n">Nested parameters are also supported.</p>
<p><strong class="i18n">Example:</strong> <a href="{{appUrl}}/examples/echo?foo['bar']=one&foo['tar']=two&run=true">{{appUrl}}/examples/echo?foo['bar']=one&foo['tar']=two&run=true</a></p>
<h3><strong class="i18n">Form Data</strong></h3>
<p class="i18n">Data can also be sent via form POST</p>
<p><strong class="i18n">Curl Example:</strong> <input id="curl" type="text" value="curl --data 'foo=bar&hello=there' {{appUrl}}/examples/echo" size="60"/></p>
<h3><strong class="i18n">Streaming Data</strong></h3>
<p class="i18n">To send streaming data to the hook, simply open up a streaming http request.</p>
<p><a class="i18n" href="{{appUrl}}/Marak/transform">Here is an example of streaming data to a hook</a></p>
<h3><strong class="i18n">Websockets</strong></h3>
<p>To send data to a Hook over Websocket, simply connect to the endpoint using any <code>ws</code> client</p>
<p>More detailed instructions can be found at <a href="{{appUrl}}/websockets"> {{appUrl}}/websockets</a></p>
<hr/>
<a name="code"></a>
<h2 class="i18n">Editing Hook source code</h2>
<p class="i18n">There are three options for specifying the source code for a Hook. Source code can be set on the <code>/admin</code> page for the Hook. <em><span class="i18n">To quickly get started, we recommend </span> <a href="#forking">Forking</a> an existing service.</em></p>
<h3 class="i18n">Code Editor</h3>
<p class="i18n">Uses a built-in Code Editor and stores source code of the service in {{appName}}</p>
<h3 class="i18n">Github Repository</h3>
<p class="i18n">Pulls the source code of the service from a Github Repository.</p>
<h3 class="i18n">Github Gist</h3>
<p class="i18n">Pulls the source code of the service from a Github Gist.</p>
<hr/>
<a name="hook"></a>
<h2 class="i18n">Accessing the Hook object inside your code</h2>
<p>All services are populated with a <code>Hook</code> object containing many useful properties.</p>
<p>For JavaScript based services, <code>Hook</code> will be the first function argument and <code>Hook.req</code> and <code>Hook.req</code> will be streams. For other programming languages, <code>Hook</code> will be defined globally in the script and <code>STDIN</code> and <code>STDOUT</code> streams will be available. The best way to understand how this works is by looking at <a href="{{appUrl}}/examples">the examples</a>.</p>
<p>
<!--
deprecated in favor of `console.log` <strong>Hook.debug</strong> - Logging method for sending debug messages to the debug console <br/>
-->
<strong>Hook.params</strong> - <span class="i18n">Incoming HTTP request data ( query string and form fields )</span><br/>
<strong>Hook.req</strong> - <span class="i18n">Incoming</span> <a href="http://nodejs.org/api/http.html#http_http_incomingmessage">http.IncomingMessage</a> stream <br/>
<strong>Hook.res</strong> - <span class="i18n">Outgoing</span> <a href="http://nodejs.org/api/http.html#http_class_http_serverresponse">httpServer.ServerResponse</a> stream<br/>
<strong>Hook.datastore</strong> - <span class="i18n">Contains methods for getting and setting key-values from the datastore</span><br/>
<strong>Hook.fs</strong> - <span class="i18n">Contains methods for using the <a href="{{appUrl}}/files">Cloud Files API</a></span><br/>
<strong>Hook.sdk</strong> - <span class="i18n">Contains a reference copy of the <a href="{{appUrl}}/sdk">{{appName}}-sdk</a></span><br/>
<!-- <strong>Hook.open</strong> - <span class="i18n">Method for opening URLs ( such as another Hook ). Options pass through to</span> <a href="https://github.com/substack/hyperquest">Hyperquest API</a>.<br/> -->
<strong>Hook.schema</strong> - <span>Optional <a href="https://github.com/mschema/mschema">mschema</a> for <strong>hook.params</strong><br/>
<strong>Hook.env</strong> - <span class="i18n">Optional. Key / value pairs stored by the owner of the Hook. See:</span> <a class="i18n" href="#env">Setting Hook Environment</a><br/>
<strong>Hook.streaming</strong> - <span class="i18n">Boolean. Is the Hook.req still streaming data. For most browser requests, this will be false.</span> <br/>
</p>
<hr/>
<a name="datastore"></a>
<h2 class="i18n">Using the Cloud Datastore</h2>
<p class="i18n">Hooks have access to a key-value cloud datastore which can be used to store and manage persistent data. This is useful for storing persistent information which you may want to retrieve later.</p>
<p class="i18n">Read more about cloud datastore: <a href="{{appUrl}}/datastore">{{appUrl}}/datastore</a></p>
<a name="schema"></a>
<h2 class="i18n">Specifying Optional Schema</h2>
<p><span>Through the use of</span> <code>mschema</code>, <span>it is possible to enable validation and default values for incoming hook parameters.</span></p>
<p class="i18n">To create a schema for the incoming hook parameters, simply specify the schema property on the <code>/admin</code> page for the hook. HTTP params will then be available in <code>Hook.params</code>.</p>
<!--
<p>
<strong class="i18n">Example:</strong>
<div data-gist="33f13d0f9a390c9601f9">Loading...</div>
</p>
-->
<p class="i18n">
Documentation for mschema can be found <a href="http://github.com/mschema/mschema/">here</a>.
</p>
<hr/>
<a name="files"></a>
<h2 class="i18n">Using the Mutli-Cloud Virtual File System</h2>
<p class="i18n">Hooks have access to a robust multi-cloud virtual file-system which can be used to manage files across multiple adapters. This is useful for storing persistent files which you may want to retrieve later.</p>
<p>Read more about multi-cloud virtual file system: </span> <a href="{{appUrl}}/files">{{appUrl}}/files</a></p>
<hr/>
<!--
<a name="forms"></a>
<h2>Using Schema Based Forms</h2>
<p>Through the use of <a href="https://github.com/mschema/mschema-forms">mschema-forms</a>, all Hooks have the ability to auto-generate an HTML form element populated with input fields matching that Hook's <strong>Hook.schema</strong></p>
<p>Forms are automatically generated in the <strong>friendly</strong> format when a <strong>Hook.schema</strong> is specified.</p>
<p>
-->
<hr/>
<a name="env"></a>
<h2 class="i18n">Setting Hook Environment Variables</h2>
<p><span class="i18n">To set Hook Environment variables visit:</span> <a href="{{appUrl}}/env">{{appUrl}}/env</a></p>
<p class="i18n">Arbitrary key / value pairs can be set on your account so that all your Hooks will have access to the pairs in the <strong>Hook.env</strong> variable.</p>
<p class="i18n">This is useful for protecting private authorization credentials from public view ( such as an API key or password ).</p>
<p class="i18n">After you have updated your environment variables they will be available in your hook's <strong>Hook.env</strong> </p>
<hr/>
<a name="domains"></a>
<h2 class="i18n">Setting Custom Domains</h2>
<p class="i18n">Custom domains are a great way to brand the appearance of your service with it's own unique domain name.</p>
<p><span class="i18n">To add a Custom Domain, you will first need to set the domains</span> <code>A record</code> to <code>{{balancerIP}}</code> ( which is the ip address of {{appName}} ).</p>
<p><span class="i18n">After setting the <code>A record</code> in your domain's DNS manager, simply visit:</span> <a href="{{appUrl}}/domains">{{appUrl}}/domains</a> <span class="i18n">to complete the process by mapping any of your Hooks to the Custom Domain.</span></p>
<hr/>
<a name="content-type"></a>
<h2 class="i18n">Content-Type Routing</h2>
<p class="i18n">Based on the <code>Content-Type</code> header, {{appName}} will process the incoming request differently.</p>
<br/>
<p>
<strong>application/json</strong><br/>
<span class="i18n">Will buffer the incoming request in order to parse the body as JSON. Incoming JSON maps to <em>Hook.params</em>. Streaming the incoming request is no longer possible at this point.</span>
</p>
<p>
<strong>application/x-www-form-urlencoded</strong><br/>
<span class="i18n">Will buffer the incoming request in order to process form fields. Incoming form fields maps to <em>Hook.params</em>.Streaming the incoming request is no longer possible at this point.</span>
</p>
<p><strong>multipart/form-data</strong><br/>
<span class="i18n">Will attach any multipart file uploads as streams to <em>Hook.params</em>. File uploads can then be handled as streams inside the Hook.</span>
</p>
<p><strong>application/octet-stream</strong><br/>
<span class="i18n">Will treat the incoming request as a binary data stream.</span>
</p>
<!--
<br/>
<h2 class="i18n">Accept Header Routing</h2>
<p class="i18n">The hook will also respond to requests differently based on their incoming <strong>Accept</strong> HTTP header.</p>
<br/>
<p><strong>text/html</strong><br/>
<span class="i18n">Returns a friendly HTML landing page ( useful for humans )</span>
</p>
<p><strong>*/*</strong><br/>
<span class="i18n">Executes the hook and returns the response type specified in the Hook ( useful for programs )</span>
</p>
<p><span class="i18n">Accept Header Routing can be overridden by setting</span> <em>Hook.params.format</em> to <em>raw</em>.
<br/>
-->
<hr/>
<!--
<a name="cache"></a>
<h2 class="i18n">Cache Controls</h2>
<p class="i18n">To ensure optimal execution speeds, {{appName}} can cache your Hook's source code and assets in memory.</p>
<p class="i18n">Currently, these caching controls can be toggled by setting the <code>mode</code> property in the Hook's admin page to either <code>Production</code> or <code>Development</code>.</p>
<p class="i18n">In <code>Development</code> mode, all Hook source code will be pulled from it's original source on every request. This is useful for Hooks which are in active development.</p>
<p class="i18n">In <code>Production</code> mode, all Hook source code will be cached in memory. This ensures much faster execution speeds, but also means that any updates to the Hook's external sources will not be immediately loaded.</p>
<br/>
<hr/>
-->
<a name="rateLimits"></a>
<h2>Rate Limiting</h2>
<p>{{appName}} will limit the total amount of API requests made against every account. This includes all API endpoints and every execution of any Hooks associated with the account.</p>
<p>In the event the total amount of API requests exceeds the amount of requests allocated with the accounts plan, further requests will be rate-limited. To increase rate limits, you can <a href="{{appUrl}}/pricing">upgrade the account</a> to a larger plan or <a href="{{appUrl}}/contact?t=Rate Limit Reset Request">email support</a> for a temporary reset.</p>
<p>Rate Limits will automatically reset at the start of every billing cycle.</p>
<h3>Rate Limiting HTTP Headers</h3>
<p>Every API response from {{appName}} will include special HTTP headers indicating the current status of Rate Limits and Concurrency Limits.</p>
<p>
<code> X-RateLimit-Limit</code> - <em>Total amount of requests allowed per cycle</em> <br/>
<code> X-RateLimit-Remaining</code> - <em>Total amount of requests remaining in cycle</em> <br/>
<code> X-RateLimit-Running</code> - <em>Total amount of actively running requests</em> <br/>
<hr/>
<a name="concurrency"></a>
<h2>Hook Concurrency Limitations</h2>
<p>{{appName}} will limit the of total amount services running concurrently per account. This means that every account may only have a certain amount of services running at the exact same time. In the event that too many services are running concurrently per account, further incoming HTTP requests will be rate-limited until some of the running services complete.</p>
<p>
To increase concurrency limits, you can <a href="{{appUrl}}/pricing">upgrade the account</a> to a larger plan or email support.
</p>
<hr/>
<a name="timeouts"></a>
<h2>Custom Service Timeouts</h2>
<p>All hooks have a <code>10000</code> millisecond timeout ( 10 second ) value by default. If the execution of your service takes longer than this value, the client will receive a <code>service timeout</code> error.</p>
<p>In the majority of cases, <strong>a time-out error</strong> indicates that the service failed to end properly and <strong>usually indicates a programming error</strong>. Attempting to run an HTTP or TCP server in a Hook will not work! Hooks are microservices ( think functions ), not servers.</p>
<p>In some other cases, you may be dealing with transferring a larger amount of data from a third-party service or communicating with a slow responding third-party service and the default timeout of ten seconds is not long enough to complete the transmission. If you think your service may require more than 10 seconds to execute, simply visit the <code>/admin</code> page for the Hook and set the form field for "Custom Timeout" in milliseconds. Note: A <a href="{{appUrl}}/pricing">paid account</a> may be required.</p>
<hr/>
<br/>
<a name="hot-code"></a>
<h2 class="i18n">Hot-Code Execution Gateway</h2>
<p class="i18n">In most cases, you will want to save your service's source-code as a Hook.</p>
<p class="i18n">In other situations, you may need to send code that has to be executed immediately and without any additional requests ( such as testing and developing hooks or executing dynamically created source code from a third-party service ).</p>
<h3>Read more on <a href="{{appUrl}}/gateways">{{appUrl}}/gateways</a></h3>
<p>{{appName}} provides a hot-code gateway which allows users to send code to be executed immediately. In fact, if you look at the <a href="https://{{appName}}#tuts">Interactive Example</a> on the {{appName}} homepage, you will notice it is powered by several hot-code gateways ( a separate gateway for each specific programming language ).</p>
<h3>Examples of using the Hot-Code Gateways</h3>
<p>Here are two simple examples of using <code>echo</code> and <code>curl</code> to execute hot-code against {{appName}}'s gateway.</p>
<h4>JavasScript</h4>
<p>
<pre><code>echo 'module["exports"] = function helloWorld (h) { h.res.end("Hello world!"); };' | curl --data-urlencode source@- http://javascript.{{appName}}</code></pre>
</p>
<h4>Python</h4>
<p>
<pre><code>echo 'print "hello world"' | curl --data-urlencode source@- http://python.{{appName}}/</code></pre>
</p>
<p>You can also simply open a url to the gateway like this: <a href="http://python.{{appName}}/?source=print%20%22hello%20world%22">http://python.{{appName}}/?source=print "hello world"</a>
<br/>
<h3>Available Gateways</h3>
<em>Note: Most gateways will an return an error or blank response if the <code>source</code> parameter is not provided</em>
<ul style="padding-top:10px;list-style-type: disc;">
<li><a href="http://javascript.{{appName}}">javascript.{{appName}}</a></li>
<li><a href="http://coffee.{{appName}}">coffee.{{appName}}</a></li>
<li><a href="http://bash.{{appName}}">bash.{{appName}}</a></li>
<li><a href="http://lua.{{appName}}">lua.{{appName}}</a></li>
<li><a href="http://perl.{{appName}}">perl.{{appName}}</a></li>
<li><a href="http://php.{{appName}}">php.{{appName}}</a></li>
<li><a href="http://python.{{appName}}">python.{{appName}}</a></li>
<li><a href="http://python3.{{appName}}">python3.{{appName}}</a></li>
<li><a href="http://ruby.{{appName}}">ruby.{{appName}}</a></li>
<li><a href="http://scheme.{{appName}}">scheme.{{appName}}</a></li>
<li><a href="http://smalltalk.{{appName}}">smalltalk.{{appName}}</a></li>
<li><a href="http://tcl.{{appName}}">tcl.{{appName}}</a></li>
</ul>
<br/>
<hr/>
<a name="events"></a>
<h2>System Events</h2>
<p>All actions on {{appName}} are tracked internally as <a href="{{appUrl}}/events">System Events</a>.</a>
<p>These events are useful for monitoring the actions your services are performing, and who is performing them.</p>
<h3>The relation of System Events and Role Access</h3>
<p>It's important to note that all {{appName}} events are available as Access Roles. This mapping allows granular role based key access per System Event.</p>
<p><a href="{{appUrl}}/keys">Read More about Role Based Access Control</a></p>
<hr/>
<br/>
<a name="ssl"></a>
<h2>SSL / HTTPS</h2>
<p class="i18n">Currently, <code>HTTPS</code> is supported on {{appName}} through a single shared <code>SSL</code> certificate.</p>
<p class="i18n">All URLs and services on the site are available over <code>HTTPS</code></p>
<p class="i18n">If you require a custom <code>SSL</code> certificate for your microservices, please contact <a href="mailto:hookmaster@{{appName}}">hookmaster@{{appName}}</a></p>
<br/>
<hr/>
<a name="api"></a>
<h2>Using {{appName}} as an HTTP API</h2>
<p><span class="i18n">A graphical interface exists for all of {{appName}}'s supported features at </span> <a href="{{appUrl}}">{{appUrl}}</a> In some cases, you may want a third party script or client ( not your browser window ), to be able to access a specific {{appName}} platform feature ( such as logs, the datastore, or creating a new hook service ). Using {{appName}}'s HTTP API, you can access any platform feature that is available in our web app.</p>
<p>To keep things simple ( and self documenting ), the routes in our web app are 1:1 with our API. The <a href="{{appUrl}}/datastore/set">/datastore</a> or <a href="{{appUrl}}/logs">/logs</a> endpoints are well documented examples of how this works, but other endpoints like <a href="{{appUrl}}/new">/new</a> might require a small amount of reverse engineering.</p>
<h3>{{appName}} SDK</h3>
<p>An easy way to access the {{appName}} API programmatically is through the {{appName}} SDK. Read more on <a href="{{appUrl}}/sdk">{{appUrl}}/sdk</a></p>
<a name="keys"></a>
<h3>API Access Keys</h3>
<p class="i18n">{{appName}} provides a robust role based API key access system.</p>
<p><span class="i18n">All</span> <a href="{{appUrl}}/events">events</a> <span class="i18n">on {{appName}} are registered as</span> roles <span class="i18n">which can be granted per</span> <a href="{{appUrl}}/keys"><span class="i18n">generated API access key</span></a></p>
<p>All API endpoints are backed by <a href="#roles">Role Based Access Control</a>, so if you provide a <code>hook_private_key</code> parameter in your request which matches a known API key containing the required role that request will be granted access to the resource. <a href="{{appUrl}}/keys">Read More about Keys and Roles</a></p>
<!--
<a name="generate-keys"></a>
<h2>Generating New Keys</h2>
<p>To create new security access keys, simply login and use the form at the bottom of this page.</p>
<a name="metrics"></a>
<h2>Hook Metrics</h2>
<p>{{appName}} provides a basic API endpoint for accessing historical information on Hook metrics.</p>
<p>This is useful for giving an insight as to how the Hook is performing.</p>
<p>Currently the following metrics are available:</p>
<ul>
<li>/metrics/hook/examples/echo/totalHits</li>
</ul>
-->
<br/>
<br/>
<br/>
</div>
</div>
</div>
</div>
<!-- end single blog item-->
</div>
<!-- end shop-content start -->
</div>
</div>
</div>