mirror of https://gitee.com/bigwinds/arangodb
Doc - removes deprecated Actions pages and examples (#7391)
This commit is contained in:
parent
1a0b9b9261
commit
f5e8d5ead4
|
@ -61,5 +61,5 @@ the view name is *demo*, then the URL of that view is:
|
|||
A view instance may be:
|
||||
* [Created](Creating.md)
|
||||
* [Retrieved](Getting.md)
|
||||
* [Modifled](Modifying.md)
|
||||
* [Modified](Modifying.md)
|
||||
* [Deleted](Dropping.md)
|
||||
|
|
|
@ -1,298 +0,0 @@
|
|||
A Hello World Example
|
||||
=====================
|
||||
|
||||
The client API or browser sends a HTTP request to the ArangoDB server and the
|
||||
server returns a HTTP response to the client. A HTTP request consists of a
|
||||
method, normally *GET* or *POST* when using a browser, and a request path like
|
||||
*/hello/world*. For a real Web server there are a zillion of other thing to
|
||||
consider, we will ignore this for the moment. The HTTP response contains a
|
||||
content type, describing how to interpret the returned data, and the data
|
||||
itself.
|
||||
|
||||
In the following example, we want to define an action in ArangoDB, so that the
|
||||
server returns the HTML document
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
Hello World
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
if asked *GET /hello/world*.
|
||||
|
||||
The server needs to know what function to call or what document to deliver if it
|
||||
receives a request. This is called routing. All the routing information of
|
||||
ArangoDB is stored in a collection *_routing*. Each entry in this collections
|
||||
describes how to deal with a particular request path.
|
||||
|
||||
For the above example, add the following document to the _routing collection:
|
||||
|
||||
@startDocuBlockInline HTML_01_routingCreateHtml
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{HTML_01_routingCreateHtml}
|
||||
|db._routing.save({
|
||||
| url: {
|
||||
| match: "/hello/world"
|
||||
| },
|
||||
| content: {
|
||||
| contentType: "text/html",
|
||||
| body: "<html><body>Hello World</body></html>"
|
||||
| }
|
||||
});
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock HTML_01_routingCreateHtml
|
||||
|
||||
In order to activate the new routing, you must either restart the server or call
|
||||
the internal reload function.
|
||||
|
||||
@startDocuBlockInline HTML_02_routingReload
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{HTML_02_routingReload}
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock HTML_02_routingReload
|
||||
|
||||
Now use the browser and access http:// localhost:8529/hello/world
|
||||
|
||||
You should see the *Hello World* in our browser:
|
||||
|
||||
@startDocuBlockInline HTML_03_routingCurlHtml
|
||||
@EXAMPLE_ARANGOSH_RUN{HTML_03_routingCurlHtml}
|
||||
var url = "/hello/world";
|
||||
var response = logCurlRequest('GET', url);
|
||||
assert(response.code === 200);
|
||||
logRawResponse(response);
|
||||
db._query("FOR route IN _routing FILTER route.url.match == '/hello/world' REMOVE route in _routing")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock HTML_03_routingCurlHtml
|
||||
|
||||
|
||||
Matching a URL
|
||||
--------------
|
||||
|
||||
There are a lot of options for the *url* attribute. If you define different
|
||||
routing for the same path, then the following simple rule is applied in order to
|
||||
determine which match wins: If there are two matches, then the more specific
|
||||
wins. I. e, if there is a wildcard match and an exact match, the exact match is
|
||||
preferred. If there is a short and a long match, the longer match wins.
|
||||
|
||||
### Exact Match
|
||||
|
||||
If the definition is
|
||||
|
||||
{
|
||||
url: {
|
||||
match: "/hello/world"
|
||||
}
|
||||
}
|
||||
|
||||
then the match must be exact. Only the request for */hello/world* will match,
|
||||
everything else, e. g. */hello/world/my* or */hello/world2*, will not match.
|
||||
|
||||
The following definition is a short-cut for an exact match.
|
||||
|
||||
{
|
||||
url: "/hello/world"
|
||||
}
|
||||
|
||||
|
||||
**Note**: While the two definitions will result in the same URL
|
||||
matching, there is a subtle difference between them:
|
||||
|
||||
The former definition (defining *url* as an object with a *match* attribute)
|
||||
will result in the URL being accessible via all supported HTTP methods (e.g.
|
||||
*GET*, *POST*, *PUT*, *DELETE*, ...), whereas the latter definition (providing a string
|
||||
*url* attribute) will result in the URL being accessible via HTTP *GET* and
|
||||
HTTP *HEAD* only, with all other HTTP methods being disabled. Calling a URL
|
||||
with an unsupported or disabled HTTP method will result in an HTTP 501
|
||||
(not implemented) error.
|
||||
|
||||
### Prefix Match
|
||||
|
||||
If the definition is
|
||||
|
||||
{
|
||||
url: {
|
||||
match: "/hello/world/*"
|
||||
}
|
||||
}
|
||||
|
||||
then the match can be a prefix match. The requests for */hello/world*,
|
||||
*/hello/world/my*, and */hello/world/how/are/you* will all match. However
|
||||
*/hello/world2* does not match. Prefix matches within a URL part,
|
||||
i. e. */hello/world**, are not allowed. The wildcard must occur at the end,
|
||||
i. e.
|
||||
|
||||
/hello/*/world
|
||||
|
||||
is also disallowed.
|
||||
|
||||
If you define two routes
|
||||
|
||||
{ url: { match: "/hello/world/*" } }
|
||||
{ url: { match: "/hello/world/emil" } }
|
||||
|
||||
then the second route will be used for */hello/world/emil* because it is more
|
||||
specific.
|
||||
|
||||
### Parameterized Match
|
||||
|
||||
A parameterized match is similar to a prefix match, but the parameters are also
|
||||
allowed inside the URL path.
|
||||
|
||||
If the definition is
|
||||
|
||||
{
|
||||
url: {
|
||||
match: "/hello/:name/world"
|
||||
}
|
||||
}
|
||||
|
||||
then the URL must have three parts, the first part being *hello* and the third
|
||||
part *world*. For example, */hello/emil/world* will match, while
|
||||
*/hello/emil/meyer/world* will not.
|
||||
|
||||
### Constraint Match
|
||||
|
||||
A constraint match is similar to a parameterized match, but the parameters can
|
||||
carry constraints.
|
||||
|
||||
If the definition is
|
||||
|
||||
{
|
||||
url: {
|
||||
match: "/hello/:name/world",
|
||||
constraint: {
|
||||
name: "/[a-z]+/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
then the URL must have three parts, the first part being *hello* and the third
|
||||
part *world*. The second part must be all lowercase.
|
||||
|
||||
It is possible to use more then one constraint for the same URL part.
|
||||
|
||||
{
|
||||
url: {
|
||||
match: "/hello/:name|:id/world",
|
||||
constraint: {
|
||||
name: "/[a-z]+/", id: "/[0-9]+/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### Optional Match
|
||||
|
||||
An optional match is similar to a parameterized match, but the last parameter is
|
||||
optional.
|
||||
|
||||
If the definition is
|
||||
|
||||
{
|
||||
url: {
|
||||
match: "/hello/:name?",
|
||||
constraint: {
|
||||
name: "/[a-z]+/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
then the URL */hello* and */hello/emil* will match.
|
||||
|
||||
If the definitions are
|
||||
|
||||
{ url: { match: "/hello/world" } }
|
||||
{ url: { match: "/hello/:name", constraint: { name: "/[a-z]+/" } } }
|
||||
{ url: { match: "/hello/*" } }
|
||||
|
||||
then the URL */hello/world* will be matched by the first route, because it is
|
||||
the most specific. The URL */hello/you* will be matched by the second route,
|
||||
because it is more specific than the prefix match.
|
||||
|
||||
### Method Restriction
|
||||
|
||||
You can restrict the match to specific HTTP methods.
|
||||
|
||||
If the definition is
|
||||
|
||||
{
|
||||
url: {
|
||||
match: "/hello/world",
|
||||
methods: [ "post", "put" ]
|
||||
}
|
||||
}
|
||||
|
||||
then only HTTP *POST* and *PUT* requests will match.
|
||||
Calling with a different HTTP method will result in an HTTP 501 error.
|
||||
|
||||
Please note that if *url* is defined as a simple string, then only the
|
||||
HTTP methods *GET* and *HEAD* will be allowed, an all other methods will be
|
||||
disabled:
|
||||
|
||||
{
|
||||
url: "/hello/world"
|
||||
}
|
||||
|
||||
### More on Matching
|
||||
|
||||
Remember that the more specific match wins.
|
||||
|
||||
- A match without parameter or wildcard is more specific than a match with
|
||||
parameters or wildcard.
|
||||
- A match with parameter is more specific than a match with a wildcard.
|
||||
- If there is more than one parameter, specificity is applied from left to
|
||||
right.
|
||||
|
||||
Consider the following definitions
|
||||
|
||||
@startDocuBlockInline HTML_04_routingCreateMultiPath
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{HTML_04_routingCreateMultiPath}
|
||||
|db._routing.save({
|
||||
| url: { match: "/hello/world" },
|
||||
content: { contentType: "text/plain", body: "Match No 1"} });
|
||||
|db._routing.save({
|
||||
| url: { match: "/hello/:name", constraint: { name: "/[a-z]+/" } },
|
||||
content: { contentType: "text/plain", body: "Match No 2"} });
|
||||
|db._routing.save({
|
||||
| url: { match: "/:something/world" },
|
||||
content: { contentType: "text/plain", body: "Match No 3"} });
|
||||
|db._routing.save({
|
||||
| url: { match: "/hi/*" },
|
||||
content: { contentType: "text/plain", body: "Match No 4"} });
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock HTML_04_routingCreateMultiPath
|
||||
|
||||
Then
|
||||
|
||||
@startDocuBlockInline HTML_05_routingGetMultiPath
|
||||
@EXAMPLE_ARANGOSH_RUN{HTML_05_routingGetMultiPath}
|
||||
| var url = ["/hello/world",
|
||||
| "/hello/emil",
|
||||
| "/your/world",
|
||||
"/hi/you"];
|
||||
| for (let i = 0; i < 4; i++) {
|
||||
| var response = logCurlRequest('GET', url[i]);
|
||||
| assert(response.code === 200);
|
||||
| assert(parseInt(response.body.substr(-1)) === (i + 1))
|
||||
| logRawResponse(response);
|
||||
}
|
||||
db._query("FOR route IN _routing FILTER route.content.contentType == 'text/plain' REMOVE route in _routing")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock HTML_05_routingGetMultiPath
|
||||
|
||||
|
||||
You can write the following document into the *_routing* collection
|
||||
to test the above examples.
|
||||
|
||||
{
|
||||
routes: [
|
||||
{ url: { match: "/hello/world" }, content: "route 1" },
|
||||
{ url: { match: "/hello/:name|:id", constraint: { name: "/[a-z]+/", id: "/[0-9]+/" } }, content: "route 2" },
|
||||
{ url: { match: "/:something/world" }, content: "route 3" },
|
||||
{ url: { match: "/hello/*" }, content: "route 4" },
|
||||
]
|
||||
}
|
|
@ -1,351 +0,0 @@
|
|||
A Hello World Example for JSON
|
||||
==============================
|
||||
|
||||
If you change the example slightly, then a JSON object will be delivered.
|
||||
|
||||
@startDocuBlockInline JSON_01_routingCreateJsonHelloWorld
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_01_routingCreateJsonHelloWorld}
|
||||
|db._routing.save({
|
||||
| url: "/hello/json",
|
||||
| content: {
|
||||
| contentType: "application/json",
|
||||
| body: '{"hello" : "world"}'
|
||||
| }
|
||||
});
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_01_routingCreateJsonHelloWorld
|
||||
|
||||
Again check with your browser or cURL http://localhost:8529/hello/json
|
||||
|
||||
Depending on your browser and installed add-ons you will either see the JSON
|
||||
object or a download dialog. If your browser wants to open an external
|
||||
application to display the JSON object, you can change the *contentType* to
|
||||
*"text/plain"* for the example. This makes it easier to check the example using
|
||||
a browser. Or use *curl* to access the server.
|
||||
|
||||
@startDocuBlockInline JSON_02_routingCurlJsonHelloWorld
|
||||
@EXAMPLE_ARANGOSH_RUN{JSON_02_routingCurlJsonHelloWorld}
|
||||
var url = "/hello/json";
|
||||
var response = logCurlRequest('GET', url);
|
||||
assert(response.code === 200);
|
||||
logJsonResponse(response);
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_02_routingCurlJsonHelloWorld
|
||||
|
||||
@startDocuBlockInline JSON_03_routingCleanupJsonHelloWorld
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_03_routingCleanupJsonHelloWorld}
|
||||
~db._query("FOR route IN _routing FILTER route.url == '/hello/json' REMOVE route in _routing")
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_03_routingCleanupJsonHelloWorld
|
||||
|
||||
Delivering Content
|
||||
------------------
|
||||
|
||||
There are a lot of different ways on how to deliver content. We have already
|
||||
seen the simplest one, where static content is delivered. The fun, however,
|
||||
starts when delivering dynamic content.
|
||||
|
||||
### Static Content
|
||||
|
||||
You can specify a body and a content-type.
|
||||
|
||||
@startDocuBlockInline JSON_05a_routingCreateContentTypeHelloWorld
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_05a_routingCreateContentTypeHelloWorld}
|
||||
|db._routing.save({
|
||||
| url: "/hello/contentType",
|
||||
| content: {
|
||||
| contentType: "text/html",
|
||||
| body: "<html><body>Hello World</body></html>"
|
||||
| }
|
||||
});
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_05a_routingCreateContentTypeHelloWorld
|
||||
|
||||
@startDocuBlockInline JSON_05b_routingCurlContentTypeHelloWorld
|
||||
@EXAMPLE_ARANGOSH_RUN{JSON_05b_routingCurlContentTypeHelloWorld}
|
||||
var url = "/hello/contentType";
|
||||
var response = logCurlRequest('GET', url);
|
||||
assert(response.code === 200);
|
||||
logRawResponse(response);
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_05b_routingCurlContentTypeHelloWorld
|
||||
|
||||
@startDocuBlockInline JSON_05c_routingCleanupContentTypeHelloWorld
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_05c_routingCleanupContentTypeHelloWorld}
|
||||
~db._query("FOR route IN _routing FILTER route.url == '/hello/contentType' REMOVE route in _routing")
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_05c_routingCleanupContentTypeHelloWorld
|
||||
|
||||
If the content type is *text/plain* then you can use the short-cut
|
||||
|
||||
```js
|
||||
{
|
||||
content: "Hello World"
|
||||
}
|
||||
```
|
||||
|
||||
### A Simple Action
|
||||
|
||||
The simplest dynamic action is:
|
||||
|
||||
```js
|
||||
{
|
||||
action: {
|
||||
do: "@arangodb/actions/echoRequest"
|
||||
}
|
||||
}
|
||||
```
|
||||
It is not advisable to store functions directly in the routing table. It is
|
||||
better to call functions defined in modules. In the above example the function
|
||||
can be accessed from JavaScript as:
|
||||
|
||||
```js
|
||||
require("@arangodb/actions").echoRequest
|
||||
```
|
||||
|
||||
The function *echoRequest* is pre-defined. It takes the request objects and
|
||||
echos it in the response.
|
||||
|
||||
The signature of such a function must be
|
||||
|
||||
```js
|
||||
function (req, res, options, next)
|
||||
```
|
||||
|
||||
*Examples*
|
||||
|
||||
@startDocuBlockInline JSON_06_routingCreateHelloEcho
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_06_routingCreateHelloEcho}
|
||||
|db._routing.save({
|
||||
| url: "/hello/echo",
|
||||
| action: {
|
||||
| do: "@arangodb/actions/echoRequest"
|
||||
| }
|
||||
});
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_06_routingCreateHelloEcho
|
||||
|
||||
Reload the routing and check http:// 127.0.0.1:8529/hello/echo
|
||||
|
||||
You should see something like
|
||||
|
||||
@startDocuBlockInline JSON_07_fetchroutingCreateHelloEcho
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_07_fetchroutingCreateHelloEcho}
|
||||
arango.GET_RAW("/hello/echo", { "accept" : "application/json" })
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_07_fetchroutingCreateHelloEcho
|
||||
|
||||
@startDocuBlockInline JSON_08_routingCleanupHelloEcho
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_08_routingCleanupHelloEcho}
|
||||
~db._query("FOR route IN _routing FILTER route.url == '/hello/echo' REMOVE route in _routing")
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_08_routingCleanupHelloEcho
|
||||
|
||||
The request might contain *path*, *prefix*, *suffix*, and *urlParameters*
|
||||
attributes. *path* is the complete path as supplied by the user and always
|
||||
available. If a prefix was matched, then this prefix is stored in the attribute
|
||||
*prefix* and the remaining URL parts are stored as an array in *suffix*. If one
|
||||
or more parameters were matched, then the parameter values are stored in
|
||||
*urlParameters*.
|
||||
|
||||
For example, if the url description is
|
||||
|
||||
```js
|
||||
{
|
||||
url: {
|
||||
match: "/hello/:name/:action"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
and you request the path */hello/emil/jump*, then the request object
|
||||
will contain the following attribute
|
||||
|
||||
```js
|
||||
urlParameters: {
|
||||
name: "emil",
|
||||
action: "jump"
|
||||
}
|
||||
```
|
||||
|
||||
### Action Controller
|
||||
|
||||
As an alternative to the simple action, you can use controllers. A controller is
|
||||
a module, defines the function *get*, *put*, *post*, *delete*, *head*,
|
||||
*patch*. If a request of the corresponding type is matched, the function will be
|
||||
called.
|
||||
|
||||
*Examples*
|
||||
|
||||
@startDocuBlockInline JSON_09_routingCreateEchoController
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_09_routingCreateEchoController}
|
||||
|db._routing.save({
|
||||
| url: "/hello/echo",
|
||||
| action: {
|
||||
| controller: "@arangodb/actions/echoController"
|
||||
| }
|
||||
});
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_09_routingCreateEchoController
|
||||
|
||||
Reload the routing and check http:// 127.0.0.1:8529/hello/echo:
|
||||
|
||||
@startDocuBlockInline JSON_10_fetchroutingCreateEchoController
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_10_fetchroutingCreateEchoController}
|
||||
arango.GET_RAW("/hello/echo", { "accept" : "application/json" })
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_10_fetchroutingCreateEchoController
|
||||
|
||||
@startDocuBlockInline JSON_11_routingCleanupEchoController
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_11_routingCleanupEchoController}
|
||||
~db._query("FOR route IN _routing FILTER route.url == '/hello/echo' REMOVE route in _routing")
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_11_routingCleanupEchoController
|
||||
|
||||
|
||||
### Prefix Action Controller
|
||||
|
||||
The controller is selected when the definition is read. There is a more
|
||||
flexible, but slower and maybe insecure variant, the prefix controller.
|
||||
|
||||
Assume that the url is a prefix match
|
||||
|
||||
```js
|
||||
{
|
||||
url: {
|
||||
match: /hello/*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can use
|
||||
|
||||
```js
|
||||
{
|
||||
action: {
|
||||
prefixController: "@arangodb/actions"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
to define a prefix controller. If the URL */hello/echoController* is given, then
|
||||
the module *@arangodb/actions/echoController* is used.
|
||||
|
||||
If you use a prefix controller, you should make certain that no unwanted actions
|
||||
are available under the prefix.
|
||||
|
||||
The definition
|
||||
|
||||
```js
|
||||
{
|
||||
action: "@arangodb/actions"
|
||||
}
|
||||
```
|
||||
is a short-cut for a prefix controller definition.
|
||||
|
||||
### Function Action
|
||||
|
||||
You can also store a function directly in the routing table.
|
||||
|
||||
*Examples*
|
||||
|
||||
@startDocuBlockInline JSON_12a_routingCreateEchoFunction
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_12a_routingCreateEchoFunction}
|
||||
|db._routing.save({
|
||||
| url: "/hello/echo",
|
||||
| action: {
|
||||
| callback: "function(req,res) {res.statusCode=200; res.body='Hello'}"
|
||||
| }
|
||||
});
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_12a_routingCreateEchoFunction
|
||||
|
||||
@startDocuBlockInline JSON_12b_fetchroutingEchoFunction
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_12b_fetchroutingEchoFunction}
|
||||
arango.GET_RAW("hello/echo", { "accept" : "application/json" })
|
||||
db._query("FOR route IN _routing FILTER route.url == '/hello/echo' REMOVE route in _routing")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_12b_fetchroutingEchoFunction
|
||||
|
||||
### Requests and Responses
|
||||
|
||||
The controller must define handler functions which take a request object and
|
||||
fill the response object.
|
||||
|
||||
A very simple example is the function *echoRequest* defined in the module
|
||||
*@arangodb/actions*.
|
||||
|
||||
```js
|
||||
function (req, res, options, next) {
|
||||
var result;
|
||||
|
||||
result = { request: req, options: options };
|
||||
|
||||
res.responseCode = exports.HTTP_OK;
|
||||
res.contentType = "application/json";
|
||||
res.body = JSON.stringify(result);
|
||||
}
|
||||
```
|
||||
|
||||
Install it via:
|
||||
|
||||
@startDocuBlockInline JSON_13_routingCreateEchoAction
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_13_routingCreateEchoAction}
|
||||
|db._routing.save({
|
||||
| url: "/echo",
|
||||
| action: {
|
||||
| do: "@arangodb/actions/echoRequest"
|
||||
| }
|
||||
})
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_13_routingCreateEchoAction
|
||||
|
||||
Reload the routing and check http:// 127.0.0.1:8529/hello/echo
|
||||
|
||||
You should see something like
|
||||
|
||||
@startDocuBlockInline JSON_14_fetchroutingRequestHelloEcho
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_14_fetchroutingRequestHelloEcho}
|
||||
arango.GET_RAW("/hello/echo", { "accept" : "application/json" })
|
||||
db._query("FOR route IN _routing FILTER route.url == '/hello/echo' REMOVE route in _routing")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_14_fetchroutingRequestHelloEcho
|
||||
|
||||
You may also pass options to the called function:
|
||||
|
||||
@startDocuBlockInline JSON_15_routingCreateEchoRequestOptions
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_15_routingCreateEchoRequestOptions}
|
||||
|db._routing.save({
|
||||
| url: "/echo",
|
||||
| action: {
|
||||
| do: "@arangodb/actions/echoRequest",
|
||||
| options: {
|
||||
| "Hello": "World"
|
||||
| }
|
||||
| }
|
||||
});
|
||||
~require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_15_routingCreateEchoRequestOptions
|
||||
|
||||
You now see the options in the result:
|
||||
|
||||
@startDocuBlockInline JSON_16_fetchroutingEchoRequestOptions
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{JSON_16_fetchroutingEchoRequestOptions}
|
||||
arango.GET_RAW("/echo", { accept: "application/json" })
|
||||
db._query("FOR route IN _routing FILTER route.url == '/echo' REMOVE route in _routing")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock JSON_16_fetchroutingEchoRequestOptions
|
|
@ -1,481 +0,0 @@
|
|||
Modifying Request and Response
|
||||
==============================
|
||||
|
||||
As we've seen in the previous examples, actions get called with the request and
|
||||
response objects (named *req* and *res* in the examples) passed as parameters to
|
||||
their handler functions.
|
||||
|
||||
The *req* object contains the incoming HTTP request, which might or might not
|
||||
have been modified by a previous action (if actions were chained).
|
||||
|
||||
A handler can modify the request object in place if desired. This might be
|
||||
useful when writing middleware (see below) that is used to intercept incoming
|
||||
requests, modify them and pass them to the actual handlers.
|
||||
|
||||
While modifying the request object might not be that relevant for non-middleware
|
||||
actions, modifying the response object definitely is. Modifying the response
|
||||
object is an action's only way to return data to the caller of the action.
|
||||
|
||||
We've already seen how to set the HTTP status code, the content type, and the
|
||||
result body. The *res* object has the following properties for these:
|
||||
|
||||
- *contentType*: MIME type of the body as defined in the HTTP standard (e.g.
|
||||
*text/html*, *text/plain*, *application/json*, ...)
|
||||
- *responsecode*: the HTTP status code of the response as defined in the HTTP
|
||||
standard. Common values for actions that succeed are *200* or *201*.
|
||||
Please refer to the HTTP standard for more information.
|
||||
- *body*: the actual response data
|
||||
|
||||
To set or modify arbitrary headers of the response object, the *headers*
|
||||
property can be used. For example, to add a user-defined header to the response,
|
||||
the following code will do:
|
||||
|
||||
```js
|
||||
res.headers = res.headers || { }; // headers might or might not be present
|
||||
res.headers['X-Test'] = 'someValue'; // set header X-Test to "someValue"
|
||||
```
|
||||
|
||||
This will set the additional HTTP header *X-Test* to value *someValue*. Other
|
||||
headers can be set as well. Note that ArangoDB might change the case of the
|
||||
header names to lower case when assembling the overall response that is sent to
|
||||
the caller.
|
||||
|
||||
It is not necessary to explicitly set a *Content-Length* header for the response
|
||||
as ArangoDB will calculate the content length automatically and add this header
|
||||
itself. ArangoDB might also add a *Connection* header itself to handle HTTP
|
||||
keep-alive.
|
||||
|
||||
ArangoDB also supports automatic transformation of the body data to another
|
||||
format. Currently, the only supported transformations are base64-encoding and
|
||||
base64-decoding. Using the transformations, an action can create a base64
|
||||
encoded body and still let ArangoDB send the non-encoded version, for example:
|
||||
|
||||
```js
|
||||
res.body = 'VGhpcyBpcyBhIHRlc3Q=';
|
||||
res.transformations = res.transformations || [ ]; // initialize
|
||||
res.transformations.push('base64decode'); // will base64 decode the response body
|
||||
```
|
||||
|
||||
When ArangoDB processes the response, it will base64-decode what's in *res.body*
|
||||
and set the HTTP header *Content-Encoding: binary*. The opposite can be achieved
|
||||
with the *base64encode* transformation: ArangoDB will then automatically
|
||||
base64-encode the body and set a *Content-Encoding: base64* HTTP header.
|
||||
|
||||
Writing dynamic action handlers
|
||||
-------------------------------
|
||||
|
||||
To write your own dynamic action handlers, you must put them into modules.
|
||||
|
||||
Modules are a means of organizing action handlers and making them loadable under
|
||||
specific names.
|
||||
|
||||
To start, we'll define a simple action handler in a module */ownTest*:
|
||||
|
||||
@startDocuBlockInline MOD_01a_routingCreateOwnTest
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_01a_routingCreateOwnTest}
|
||||
|db._modules.save({
|
||||
| path: "/db:/ownTest",
|
||||
| content:
|
||||
| "exports.do = function(req, res, options, next) {"+
|
||||
| " res.body = 'test';" +
|
||||
| " res.responseCode = 200;" +
|
||||
| " res.contentType = 'text/plain';" +
|
||||
| "};"
|
||||
});
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_01a_routingCreateOwnTest
|
||||
|
||||
This does nothing but register a do action handler in a module */ownTest*. The
|
||||
action handler is not yet callable, but must be mapped to a route first. To map
|
||||
the action to the route */ourtest*, execute the following command:
|
||||
|
||||
@startDocuBlockInline MOD_01b_routingEnableOwnTest
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_01b_routingEnableOwnTest}
|
||||
|db._routing.save({
|
||||
| url: "/ourtest",
|
||||
| action: {
|
||||
| controller: "db://ownTest"
|
||||
| }
|
||||
});
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_01b_routingEnableOwnTest
|
||||
|
||||
Now use the browser or cURL and access http://localhost:8529/ourtest :
|
||||
|
||||
@startDocuBlockInline MOD_01c_routingCurlOwnTest
|
||||
@EXAMPLE_ARANGOSH_RUN{MOD_01c_routingCurlOwnTest}
|
||||
var url = "/ourtest";
|
||||
var response = logCurlRequest('GET', url);
|
||||
assert(response.code === 200);
|
||||
assert(response.body === 'test');
|
||||
logRawResponse(response);
|
||||
db._query("FOR route IN _routing FILTER route.url == '/ourtest' REMOVE route in _routing")
|
||||
db._query("FOR module IN _modules FILTER module.path == '/db:/ownTest' REMOVE module in _modules")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_RUN
|
||||
@endDocuBlock MOD_01c_routingCurlOwnTest
|
||||
|
||||
|
||||
You will see that the module's do function has been executed.
|
||||
|
||||
A Word about Caching
|
||||
--------------------
|
||||
|
||||
Sometimes it might seem that your change do not take effect. In this case the
|
||||
culprit could be the routing caches:
|
||||
|
||||
The routing cache stores the routing information computed from the *_routing*
|
||||
collection. Whenever you change this collection manually, you need to call
|
||||
|
||||
@startDocuBlockInline MOD_05_routingModifyReload
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_05_routingModifyReload}
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_05_routingModifyReload
|
||||
|
||||
in order to rebuild the cache.
|
||||
|
||||
|
||||
Advanced Usages
|
||||
---------------
|
||||
|
||||
For detailed information see the reference manual.
|
||||
|
||||
### Redirects
|
||||
|
||||
Use the following for a permanent redirect:
|
||||
|
||||
@startDocuBlockInline MOD_06a_routingRedirect
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_06a_routingRedirect}
|
||||
| db._routing.save({
|
||||
| url: "/redirectMe",
|
||||
| action: {
|
||||
| do: "@arangodb/actions/redirectRequest",
|
||||
| options: {
|
||||
| permanently: true,
|
||||
| destination: "/somewhere.else/"
|
||||
| }
|
||||
| }
|
||||
});
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_06a_routingRedirect
|
||||
|
||||
@startDocuBlockInline MOD_06b_routingCurlRedirect
|
||||
@EXAMPLE_ARANGOSH_RUN{MOD_06b_routingCurlRedirect}
|
||||
var url = "/redirectMe";
|
||||
var response = logCurlRequest('GET', url);
|
||||
assert(response.code === 301);
|
||||
logHtmlResponse(response);
|
||||
db._query("FOR route IN _routing FILTER route.url == '/redirectMe' REMOVE route in _routing")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_RUN
|
||||
@endDocuBlock MOD_06b_routingCurlRedirect
|
||||
|
||||
### Routing Bundles
|
||||
|
||||
Instead of adding all routes for package separately, you can
|
||||
specify a bundle:
|
||||
|
||||
@startDocuBlockInline MOD_07a_routingMulti
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_07a_routingMulti}
|
||||
| db._routing.save({
|
||||
| routes: [
|
||||
| {
|
||||
| url: "/url1",
|
||||
| content: "route 1"
|
||||
| },
|
||||
| {
|
||||
| url: "/url2",
|
||||
| content: "route 2"
|
||||
| },
|
||||
| {
|
||||
| url: "/url3",
|
||||
| content: "route 3"
|
||||
| }
|
||||
| ]
|
||||
});
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_07a_routingMulti
|
||||
|
||||
|
||||
@startDocuBlockInline MOD_07b_routingCurlMulti
|
||||
@EXAMPLE_ARANGOSH_RUN{MOD_07b_routingCurlMulti}
|
||||
var url = ["/url1", "/url2", "/url3"];
|
||||
var reply = ["route 1", "route 2", "route 3"]
|
||||
for (var i = 1; i < 3; i++) {
|
||||
var response = logCurlRequest('GET', url[i]);
|
||||
assert(response.code === 200);
|
||||
assert(response.body === reply[i])
|
||||
logRawResponse(response);
|
||||
}
|
||||
db._query("FOR route IN _routing FILTER route.routes[0].url == '/url1' REMOVE route in _routing")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_RUN
|
||||
@endDocuBlock MOD_07b_routingCurlMulti
|
||||
|
||||
The advantage is, that you can put all your routes into one document
|
||||
and use a common prefix.
|
||||
|
||||
@startDocuBlockInline MOD_07c_routingMulti
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_07c_routingMulti}
|
||||
| db._routing.save({
|
||||
| urlPrefix: "/test",
|
||||
| routes: [
|
||||
| {
|
||||
| url: "/url1",
|
||||
| content: "route 1"
|
||||
| },
|
||||
| {
|
||||
| url: "/url2",
|
||||
| content: "route 2"
|
||||
| },
|
||||
| {
|
||||
| url: "/url3",
|
||||
| content: "route 3"
|
||||
| }
|
||||
| ]
|
||||
});
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_07c_routingMulti
|
||||
|
||||
will define the URL */test/url1*, */test/url2*, and */test/url3*:
|
||||
|
||||
@startDocuBlockInline MOD_07d_routingCurlMulti
|
||||
@EXAMPLE_ARANGOSH_RUN{MOD_07d_routingCurlMulti}
|
||||
var url = ["/test/url1", "/test/url2", "/test/url3"];
|
||||
var reply = ["route 1", "route 2", "route 3"]
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var response = logCurlRequest('GET', url[i]);
|
||||
assert(response.code === 200);
|
||||
assert(response.body === reply[i])
|
||||
logRawResponse(response);
|
||||
}
|
||||
db._query("FOR route IN _routing FILTER route.routes[0].url == '/url1' REMOVE route in _routing")
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_RUN
|
||||
@endDocuBlock MOD_07d_routingCurlMulti
|
||||
|
||||
### Writing Middleware
|
||||
|
||||
Assume, you want to log every request in your namespace to the console. *(if ArangoDB is running
|
||||
as a daemon, this will end up in the logfile)*. In this case you can easily define an
|
||||
action for the URL */subdirectory*. This action simply logs
|
||||
the requests, calls the next in line, and logs the response:
|
||||
|
||||
@startDocuBlockInline MOD_08a_routingCreateOwnConsoleLog
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_08a_routingCreateOwnConsoleLog}
|
||||
|db._modules.save({
|
||||
| path: "/db:/OwnMiddlewareTest",
|
||||
| content:
|
||||
| "exports.logRequest = function (req, res, options, next) {" +
|
||||
| " console = require('console'); " +
|
||||
| " console.log('received request: %s', JSON.stringify(req));" +
|
||||
| " next();" +
|
||||
| " console.log('produced response: %s', JSON.stringify(res));" +
|
||||
| "};"
|
||||
});
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_08a_routingCreateOwnConsoleLog
|
||||
|
||||
This function will now be available as *db://OwnMiddlewareTest/logRequest*. You need to
|
||||
tell ArangoDB that it is should use a prefix match and that the shortest match
|
||||
should win in this case:
|
||||
|
||||
@startDocuBlockInline MOD_08b_routingCreateRouteToOwnConsoleLog
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_08b_routingCreateRouteToOwnConsoleLog}
|
||||
|db._routing.save({
|
||||
| middleware: [
|
||||
| {
|
||||
| url: {
|
||||
| match: "/subdirectory/*"
|
||||
| },
|
||||
| action: {
|
||||
| do: "db://OwnMiddlewareTest/logRequest"
|
||||
| }
|
||||
| }
|
||||
| ]
|
||||
});
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_08b_routingCreateRouteToOwnConsoleLog
|
||||
|
||||
When you call *next()* in that action, the next specific routing will
|
||||
be used for the original URL. Even if you modify the URL in the request
|
||||
object *req*, this will not cause the *next()* to jump to the routing
|
||||
defined for this next URL. If proceeds occurring the origin URL. However,
|
||||
if you use *next(true)*, the routing will stop and request handling is
|
||||
started with the new URL. You must ensure that *next(true)* is never
|
||||
called without modifying the URL in the request object
|
||||
*req*. Otherwise an endless loop will occur.
|
||||
|
||||
Now we add some other simple routings to test all this:
|
||||
|
||||
@startDocuBlockInline MOD_08c_routingCreateRouteToOwnConsoleLog
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_08c_routingCreateRouteToOwnConsoleLog}
|
||||
|db._routing.save({
|
||||
| url: "/subdirectory/ourtest/1",
|
||||
| action: {
|
||||
| do: "@arangodb/actions/echoRequest"
|
||||
| }
|
||||
});
|
||||
|db._routing.save({
|
||||
| url: "/subdirectory/ourtest/2",
|
||||
| action: {
|
||||
| do: "@arangodb/actions/echoRequest"
|
||||
| }
|
||||
});
|
||||
|db._routing.save({
|
||||
| url: "/subdirectory/ourtest/3",
|
||||
| action: {
|
||||
| do: "@arangodb/actions/echoRequest"
|
||||
| }
|
||||
});
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_08c_routingCreateRouteToOwnConsoleLog
|
||||
|
||||
Then we send some curl requests to these sample routes:
|
||||
|
||||
@startDocuBlockInline MOD_08d_routingCurlToOwnConsoleLog
|
||||
@EXAMPLE_ARANGOSH_RUN{MOD_08d_routingCurlToOwnConsoleLog}
|
||||
var url = ["/subdirectory/ourtest/1",
|
||||
"/subdirectory/ourtest/2",
|
||||
"/subdirectory/ourtest/3"];
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var response = logCurlRequest('GET', url[i]);
|
||||
assert(response.code === 200);
|
||||
logJsonResponse(response);
|
||||
}
|
||||
db._query("FOR route IN _routing FILTER route.middleware[0].url.match == '/subdirectory/*' REMOVE route in _routing");
|
||||
db._query("FOR route IN _routing FILTER route.url == '/subdirectory/ourtest/1' REMOVE route in _routing");
|
||||
db._query("FOR route IN _routing FILTER route.url == '/subdirectory/ourtest/2' REMOVE route in _routing");
|
||||
db._query("FOR route IN _routing FILTER route.url == '/subdirectory/ourtest/3' REMOVE route in _routing");
|
||||
db._query("FOR module IN _modules FILTER module.path == '/db:/OwnMiddlewareTest' REMOVE module in _modules");
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_RUN
|
||||
@endDocuBlock MOD_08d_routingCurlToOwnConsoleLog
|
||||
|
||||
and the console (and / or the logfile) will show requests and replies.
|
||||
*Note that logging doesn't warrant the sequence in which these lines
|
||||
will appear.*
|
||||
|
||||
Application Deployment
|
||||
----------------------
|
||||
|
||||
Using single routes or [bundles](#routing-bundles) can be
|
||||
become a bit messy in large applications. Kaerus has written a [deployment tool](https://github.com/kaerus/arangodep) in node.js.
|
||||
|
||||
Note that there is also [Foxx](../../../Foxx/README.md) for building applications
|
||||
with ArangoDB.
|
||||
|
||||
Common Pitfalls when using Actions
|
||||
----------------------------------
|
||||
|
||||
### Caching
|
||||
|
||||
If you made any changes to the routing but the changes does not have any effect
|
||||
when calling the modified actions URL, you might have been hit by some
|
||||
caching issues.
|
||||
|
||||
After any modification to the routing or actions, it is thus recommended to
|
||||
make the changes "live" by calling the following functions from within arangosh:
|
||||
|
||||
@startDocuBlockInline MOD_09_routingReload
|
||||
@EXAMPLE_ARANGOSH_RUN{MOD_09_routingReload}
|
||||
require("internal").reloadRouting();
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_09_routingReload
|
||||
|
||||
You might also be affected by client-side caching.
|
||||
Browsers tend to cache content and also redirection URLs. You might need to
|
||||
clear or disable the browser cache in some cases to see your changes in effect.
|
||||
|
||||
### Data types
|
||||
|
||||
When processing the request data in an action, please be aware that the data
|
||||
type of all query parameters is *string*. This is because the whole URL is a
|
||||
string and when the individual parts are extracted, they will also be strings.
|
||||
|
||||
For example, when calling the URL http:// localhost:8529/hello/world?value=5
|
||||
|
||||
the parameter *value* will have a value of (string) *5*, not (number) *5*.
|
||||
This might be troublesome if you use JavaScript's *===* operator when checking
|
||||
request parameter values.
|
||||
|
||||
The same problem occurs with incoming HTTP headers. When sending the following
|
||||
header from a client to ArangoDB
|
||||
|
||||
X-My-Value: 5
|
||||
|
||||
then the header *X-My-Value* will have a value of (string) *5* and not (number) *5*.
|
||||
|
||||
### 404 Not Found
|
||||
|
||||
If you defined a URL in the routing and the URL is accessible fine via
|
||||
HTTP *GET* but returns an HTTP 501 (not implemented) for other HTTP methods
|
||||
such as *POST*, *PUT* or *DELETE*, then you might have been hit by some
|
||||
defaults.
|
||||
|
||||
By default, URLs defined like this (simple string *url* attribute) are
|
||||
accessible via HTTP *GET* and *HEAD* only. To make such URLs accessible via
|
||||
other HTTP methods, extend the URL definition with the *methods* attribute.
|
||||
|
||||
For example, this definition only allows access via *GET* and *HEAD*:
|
||||
|
||||
```js
|
||||
{
|
||||
url: "/hello/world"
|
||||
}
|
||||
```
|
||||
|
||||
whereas this definition allows HTTP *GET*, *POST*, and *PUT*:
|
||||
|
||||
@startDocuBlockInline MOD_09a_routingSpecifyMethods
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{MOD_09a_routingSpecifyMethods}
|
||||
|db._routing.save({
|
||||
| url: {
|
||||
| match: "/hello/world",
|
||||
| methods: [ "get", "post", "put" ]
|
||||
| },
|
||||
| action: {
|
||||
| do: "@arangodb/actions/echoRequest"
|
||||
| }
|
||||
});
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock MOD_09a_routingSpecifyMethods
|
||||
|
||||
@startDocuBlockInline MOD_09b_routingCurlSpecifyMethods
|
||||
@EXAMPLE_ARANGOSH_RUN{MOD_09b_routingCurlSpecifyMethods}
|
||||
var url = "/hello/world"
|
||||
var postContent = "{hello: 'world'}";
|
||||
var response = logCurlRequest('GET', url);
|
||||
assert(response.code === 200);
|
||||
logJsonResponse(response);
|
||||
|
||||
var response = logCurlRequest('POST', url, postContent);
|
||||
assert(response.code === 200);
|
||||
logJsonResponse(response);
|
||||
|
||||
var response = logCurlRequest('PUT', url, postContent);
|
||||
assert(response.code === 200);
|
||||
logJsonResponse(response);
|
||||
|
||||
var response = logCurlRequest('DELETE', url);
|
||||
assert(response.code === 404);
|
||||
logJsonResponse(response);
|
||||
|
||||
db._query("FOR route IN _routing FILTER route.url.match == '/hello/world' REMOVE route in _routing");
|
||||
require("internal").reloadRouting()
|
||||
@END_EXAMPLE_ARANGOSH_RUN
|
||||
@endDocuBlock MOD_09b_routingCurlSpecifyMethods
|
||||
|
||||
The former definition (defining *url* as an object with a *match* attribute)
|
||||
will result in the URL being accessible via all supported HTTP methods (e.g.
|
||||
*GET*, *POST*, *PUT*, *DELETE*, ...), whereas the latter definition (providing a string
|
||||
*url* attribute) will result in the URL being accessible via HTTP *GET* and
|
||||
HTTP *HEAD* only, with all other HTTP methods being disabled. Calling a URL
|
||||
with an unsupported or disabled HTTP method will result in an HTTP 404 error.
|
|
@ -1,60 +0,0 @@
|
|||
ArangoDB's Actions
|
||||
==================
|
||||
|
||||
{% hint 'warning' %}
|
||||
It is recommended to use [**Foxx**](../../../Foxx/README.md) instead.
|
||||
{% endhint %}
|
||||
|
||||
Introduction to User Actions
|
||||
----------------------------
|
||||
|
||||
In some ways the communication layer of the ArangoDB server behaves like a Web
|
||||
server. Unlike a Web server, it normally responds to HTTP requests by delivering
|
||||
JSON objects. Remember, documents in the database are just JSON objects. So,
|
||||
most of the time the HTTP response will contain a JSON document from the
|
||||
database as body. You can extract the documents stored in the database using
|
||||
HTTP *GET*. You can store documents using HTTP *POST*.
|
||||
|
||||
However, there is something more. You can write small snippets - so called
|
||||
actions - to extend the database. The idea of actions is that sometimes it is
|
||||
better to store parts of the business logic within ArangoDB.
|
||||
|
||||
The simplest example is the age of a person. Assume you store information about
|
||||
people in your database. It is an anti-pattern to store the age, because it
|
||||
changes every now and then. Therefore, you normally store the birthday and let
|
||||
the client decide what to do with it. However, if you have many different
|
||||
clients, it might be easier to enrich the person document with the age using
|
||||
actions once on the server side.
|
||||
|
||||
Or, for instance, if you want to apply some statistics to large data-sets and
|
||||
you cannot easily express this as query. You can define a action instead of
|
||||
transferring the whole data to the client and do the computation on the client.
|
||||
|
||||
Actions are also useful if you want to restrict and filter data according to
|
||||
some complex permission system.
|
||||
|
||||
The ArangoDB server can deliver all kinds of information, JSON being only one
|
||||
possible format. You can also generate HTML or images. However, a Web server is
|
||||
normally better suited for the task as it also implements various caching
|
||||
strategies, language selection, compression and so on. Having said that, there
|
||||
are still situations where it might be suitable to use the ArangoDB to deliver
|
||||
HTML pages - static or dynamic. A simple example is the built-in administration
|
||||
interface. You can access it using any modern browser and there is no need for a
|
||||
separate Apache or IIS.
|
||||
|
||||
In general you will use [Foxx](../../../Foxx/README.md) to easily extend the database with
|
||||
business logic. Foxx provides an simple to use interface to actions.
|
||||
|
||||
The following sections will explain the low-level actions within ArangoDB on
|
||||
which Foxx is built and show how to define them. The examples start with
|
||||
delivering static HTML pages - even if this is not the primary use-case for
|
||||
actions. The later sections will then show you how to code some pieces of your
|
||||
business logic and return JSON objects.
|
||||
|
||||
The interface is loosely modeled after the JavaScript classes for HTTP request
|
||||
and responses found in node.js and the middleware/routing aspects of connect.js
|
||||
and express.js.
|
||||
|
||||
Note that unlike node.js, ArangoDB is multi-threaded and there is no easy way to
|
||||
share state between queries inside the JavaScript engine. If such state
|
||||
information is required, you need to use the database itself.
|
|
@ -6,7 +6,7 @@ considered obsolete and may get removed in a future release. They are currently
|
|||
kept for backward compatibility. There are usually better alternatives to
|
||||
replace the old features with:
|
||||
|
||||
- **Simple Queries**: Ideomatic interface in arangosh to perform trivial queries.
|
||||
- **Simple Queries**: Idiomatic interface in arangosh to perform trivial queries.
|
||||
They are superseded by [AQL queries](../../../AQL/index.html), which can also
|
||||
be run in arangosh. AQL is a language on its own and way more powerful than
|
||||
*Simple Queries* could ever be. In fact, the (still supported) *Simple Queries*
|
||||
|
@ -18,3 +18,12 @@ replace the old features with:
|
|||
custom endpoints. Since the Foxx revamp in 3.0, it became really easy to
|
||||
write [Foxx Microservices](../../Foxx/README.md), which allow you to define
|
||||
custom endpoints even with complex business logic.
|
||||
|
||||
From v3.5.0 on, the system collections `_routing` and `_modules` are not
|
||||
created anymore when the `_system` database is first created (blank new data
|
||||
folder). They are not actively removed, they remain on upgrade or backup
|
||||
restoration from previous versions.
|
||||
|
||||
You can still find the
|
||||
[Actions documentation](https://docs.arangodb.com/3.4/Manual/Appendix/Deprecated/Actions/)
|
||||
in 3.4 or older versions of the documentation.
|
||||
|
|
|
@ -424,9 +424,5 @@
|
|||
* [Modification Queries](Appendix/Deprecated/SimpleQueries/ModificationQueries.md)
|
||||
* [Geo Queries](Appendix/Deprecated/SimpleQueries/GeoQueries.md)
|
||||
* [Fulltext Queries](Appendix/Deprecated/SimpleQueries/FulltextQueries.md)
|
||||
* [Actions](Appendix/Deprecated/Actions/README.md)
|
||||
* [Delivering HTML Pages](Appendix/Deprecated/Actions/HtmlExample.md)
|
||||
* [Json Objects](Appendix/Deprecated/Actions/JsonExample.md)
|
||||
* [Modifying](Appendix/Deprecated/Actions/Modifying.md)
|
||||
* [Error codes and meanings](Appendix/ErrorCodes.md)
|
||||
* [Glossary](Appendix/Glossary.md)
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: {
|
||||
........> match: <span class="hljs-string">"/hello/world"</span>
|
||||
........> },
|
||||
........> content: {
|
||||
........> contentType: <span class="hljs-string">"text/html"</span>,
|
||||
........> body: <span class="hljs-string">"<html><body>Hello World</body></html>"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/100195"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"100195"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5ji---_"</span>
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,7 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/hello/world</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/html
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"<html><body>Hello World</body></html>"
|
|
@ -1,33 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: { <span class="hljs-attr">match</span>: <span class="hljs-string">"/hello/world"</span> },
|
||||
........> content: { <span class="hljs-attr">contentType</span>: <span class="hljs-string">"text/plain"</span>, <span class="hljs-attr">body</span>: <span class="hljs-string">"Match No 1"</span>} });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/100208"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"100208"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5jj2--_"</span>
|
||||
}
|
||||
arangosh> db._routing.save({
|
||||
........> url: { <span class="hljs-attr">match</span>: <span class="hljs-string">"/hello/:name"</span>, <span class="hljs-attr">constraint</span>: { <span class="hljs-attr">name</span>: <span class="hljs-string">"/[a-z]+/"</span> } },
|
||||
........> content: { <span class="hljs-attr">contentType</span>: <span class="hljs-string">"text/plain"</span>, <span class="hljs-attr">body</span>: <span class="hljs-string">"Match No 2"</span>} });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/100212"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"100212"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5jj6--_"</span>
|
||||
}
|
||||
arangosh> db._routing.save({
|
||||
........> url: { <span class="hljs-attr">match</span>: <span class="hljs-string">"/:something/world"</span> },
|
||||
........> content: { <span class="hljs-attr">contentType</span>: <span class="hljs-string">"text/plain"</span>, <span class="hljs-attr">body</span>: <span class="hljs-string">"Match No 3"</span>} });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/100215"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"100215"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5jj6--B"</span>
|
||||
}
|
||||
arangosh> db._routing.save({
|
||||
........> url: { <span class="hljs-attr">match</span>: <span class="hljs-string">"/hi/*"</span> },
|
||||
........> content: { <span class="hljs-attr">contentType</span>: <span class="hljs-string">"text/plain"</span>, <span class="hljs-attr">body</span>: <span class="hljs-string">"Match No 4"</span>} });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/100218"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"100218"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5jj6--D"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,28 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/hello/world</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"Match No 1"
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/hello/emil</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"Match No 2"
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/your/world</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"Match No 3"
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/hi/you</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"Match No 4"
|
|
@ -1,13 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/hello/json"</span>,
|
||||
........> content: {
|
||||
........> contentType: <span class="hljs-string">"application/json"</span>,
|
||||
........> body: <span class="hljs-string">'{"hello" : "world"}'</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102100"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102100"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5k8---_"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,9 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/hello/json</span>
|
||||
|
||||
HTTP/<span class="hljs-number">1.1</span> <span class="hljs-literal">undefined</span>
|
||||
content-type: application/json; charset=utf<span class="hljs-number">-8</span>
|
||||
x-content-type-options: nosniff
|
||||
|
||||
{
|
||||
<span class="hljs-string">"hello"</span> : <span class="hljs-string">"world"</span>
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/hello/contentType"</span>,
|
||||
........> content: {
|
||||
........> contentType: <span class="hljs-string">"text/html"</span>,
|
||||
........> body: <span class="hljs-string">"<html><body>Hello World</body></html>"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102113"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102113"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5k9m--_"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,7 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/hello/contentType</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/html
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"<html><body>Hello World</body></html>"
|
|
@ -1,11 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/hello/echo"</span>,
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"@arangodb/actions/echoRequest"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102126"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102126"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5l-2--_"</span>
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
arangosh> arango.GET_RAW(<span class="hljs-string">"/hello/echo"</span>, { <span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span> })
|
||||
{
|
||||
<span class="hljs-string">"code"</span> : <span class="hljs-number">200</span>,
|
||||
<span class="hljs-string">"error"</span> : <span class="hljs-literal">false</span>,
|
||||
<span class="hljs-string">"body"</span> : <span class="hljs-string">"{\"request\":{\"authorized\":true,\"user\":\"root\",\"database\":\"_system\",\"url\":\"/hello/echo\",\"protocol\":\"http\",\"server\":{\"address\":\"127.0.0.1\",\"port\":15674},\"client\":{\"address\":\"127.0.0.1\",\"port\":49765,\"id\":\"153563925279595\"},\"internals\":{},\"headers\":{\"host\":\"127...."</span>,
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"content-length"</span> : <span class="hljs-string">"467"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json; charset=utf-8"</span>,
|
||||
<span class="hljs-string">"server"</span> : <span class="hljs-string">"ArangoDB"</span>,
|
||||
<span class="hljs-string">"x-content-type-options"</span> : <span class="hljs-string">"nosniff"</span>
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/hello/echo"</span>,
|
||||
........> action: {
|
||||
........> controller: <span class="hljs-string">"@arangodb/actions/echoController"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102139"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102139"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lAO--_"</span>
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
arangosh> arango.GET_RAW(<span class="hljs-string">"/hello/echo"</span>, { <span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span> })
|
||||
{
|
||||
<span class="hljs-string">"code"</span> : <span class="hljs-number">200</span>,
|
||||
<span class="hljs-string">"error"</span> : <span class="hljs-literal">false</span>,
|
||||
<span class="hljs-string">"body"</span> : <span class="hljs-string">"{\"request\":{\"authorized\":true,\"user\":\"root\",\"database\":\"_system\",\"url\":\"/hello/echo\",\"protocol\":\"http\",\"server\":{\"address\":\"127.0.0.1\",\"port\":15674},\"client\":{\"address\":\"127.0.0.1\",\"port\":49765,\"id\":\"153563925279595\"},\"internals\":{},\"headers\":{\"host\":\"127...."</span>,
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"content-length"</span> : <span class="hljs-string">"467"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json; charset=utf-8"</span>,
|
||||
<span class="hljs-string">"server"</span> : <span class="hljs-string">"ArangoDB"</span>,
|
||||
<span class="hljs-string">"x-content-type-options"</span> : <span class="hljs-string">"nosniff"</span>
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/hello/echo"</span>,
|
||||
........> action: {
|
||||
........> callback: <span class="hljs-string">"function(req,res) {res.statusCode=200; res.body='Hello'}"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102152"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102152"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lBO--_"</span>
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
arangosh> arango.GET_RAW(<span class="hljs-string">"hello/echo"</span>, { <span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span> })
|
||||
{
|
||||
<span class="hljs-string">"code"</span> : <span class="hljs-number">200</span>,
|
||||
<span class="hljs-string">"error"</span> : <span class="hljs-literal">false</span>,
|
||||
<span class="hljs-string">"body"</span> : <span class="hljs-string">"Hello"</span>,
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"content-length"</span> : <span class="hljs-string">"5"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json; charset=utf-8"</span>,
|
||||
<span class="hljs-string">"server"</span> : <span class="hljs-string">"ArangoDB"</span>,
|
||||
<span class="hljs-string">"x-content-type-options"</span> : <span class="hljs-string">"nosniff"</span>
|
||||
}
|
||||
}
|
||||
arangosh> db._query(<span class="hljs-string">"FOR route IN _routing FILTER route.url == '/hello/echo' REMOVE route in _routing"</span>)
|
||||
[object ArangoQueryCursor, <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">cached</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">hasMore</span>: <span class="hljs-literal">false</span>]
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,11 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/echo"</span>,
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"@arangodb/actions/echoRequest"</span>
|
||||
........> }
|
||||
........> })
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102165"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102165"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lCS--_"</span>
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
arangosh> arango.GET_RAW(<span class="hljs-string">"/hello/echo"</span>, { <span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span> })
|
||||
{
|
||||
<span class="hljs-string">"code"</span> : <span class="hljs-number">404</span>,
|
||||
<span class="hljs-string">"error"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"errorNum"</span> : <span class="hljs-number">404</span>,
|
||||
<span class="hljs-string">"errorMessage"</span> : <span class="hljs-string">"404 Not Found"</span>,
|
||||
<span class="hljs-string">"body"</span> : <span class="hljs-string">"{\"error\":true,\"code\":404,\"errorNum\":404,\"errorMessage\":\"unknown path '/hello/echo'\"}"</span>,
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"content-length"</span> : <span class="hljs-string">"84"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json; charset=utf-8"</span>,
|
||||
<span class="hljs-string">"server"</span> : <span class="hljs-string">"ArangoDB"</span>,
|
||||
<span class="hljs-string">"x-content-type-options"</span> : <span class="hljs-string">"nosniff"</span>
|
||||
}
|
||||
}
|
||||
arangosh> db._query(<span class="hljs-string">"FOR route IN _routing FILTER route.url == '/hello/echo' REMOVE route in _routing"</span>)
|
||||
[object ArangoQueryCursor, <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">cached</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">hasMore</span>: <span class="hljs-literal">false</span>]
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,14 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/echo"</span>,
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"@arangodb/actions/echoRequest"</span>,
|
||||
........> options: {
|
||||
........> <span class="hljs-string">"Hello"</span>: <span class="hljs-string">"World"</span>
|
||||
........> }
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102174"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102174"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lDi--_"</span>
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
arangosh> arango.GET_RAW(<span class="hljs-string">"/echo"</span>, { <span class="hljs-attr">accept</span>: <span class="hljs-string">"application/json"</span> })
|
||||
{
|
||||
<span class="hljs-string">"code"</span> : <span class="hljs-number">200</span>,
|
||||
<span class="hljs-string">"error"</span> : <span class="hljs-literal">false</span>,
|
||||
<span class="hljs-string">"body"</span> : <span class="hljs-string">"{\"request\":{\"authorized\":true,\"user\":\"root\",\"database\":\"_system\",\"url\":\"/echo\",\"protocol\":\"http\",\"server\":{\"address\":\"127.0.0.1\",\"port\":15674},\"client\":{\"address\":\"127.0.0.1\",\"port\":49765,\"id\":\"153563925279595\"},\"internals\":{},\"headers\":{\"host\":\"127.0.0.1\"..."</span>,
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"content-length"</span> : <span class="hljs-string">"461"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json; charset=utf-8"</span>,
|
||||
<span class="hljs-string">"server"</span> : <span class="hljs-string">"ArangoDB"</span>,
|
||||
<span class="hljs-string">"x-content-type-options"</span> : <span class="hljs-string">"nosniff"</span>
|
||||
}
|
||||
}
|
||||
arangosh> db._query(<span class="hljs-string">"FOR route IN _routing FILTER route.url == '/echo' REMOVE route in _routing"</span>)
|
||||
[object ArangoQueryCursor, <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">cached</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">hasMore</span>: <span class="hljs-literal">false</span>]
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,14 +0,0 @@
|
|||
arangosh> db._modules.save({
|
||||
........> path: <span class="hljs-string">"/db:/ownTest"</span>,
|
||||
........> content:
|
||||
........> <span class="hljs-string">"exports.do = function(req, res, options, next) {"</span>+
|
||||
........> <span class="hljs-string">" res.body = 'test';"</span> +
|
||||
........> <span class="hljs-string">" res.responseCode = 200;"</span> +
|
||||
........> <span class="hljs-string">" res.contentType = 'text/plain';"</span> +
|
||||
........> <span class="hljs-string">"};"</span>
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_modules/102187"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102187"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lEm--_"</span>
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/ourtest"</span>,
|
||||
........> action: {
|
||||
........> controller: <span class="hljs-string">"db://ownTest"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102191"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102191"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lEq--_"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,7 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/ourtest</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"test"
|
|
@ -1 +0,0 @@
|
|||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,16 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/redirectMe"</span>,
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"@arangodb/actions/redirectRequest"</span>,
|
||||
........> options: {
|
||||
........> permanently: <span class="hljs-literal">true</span>,
|
||||
........> destination: <span class="hljs-string">"/somewhere.else/"</span>
|
||||
........> }
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102211"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102211"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lGG--_"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,8 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/redirectMe</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/html
|
||||
location: /somewhere.else/
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"<span class="hljs-tag"><<span class="hljs-name">html</span>></span><span class="hljs-tag"><<span class="hljs-name">head</span>></span><span class="hljs-tag"><<span class="hljs-name">title</span>></span>Moved<span class="hljs-tag"></<span class="hljs-name">title</span>></span><span class="hljs-tag"></<span class="hljs-name">head</span>></span><span class="hljs-tag"><<span class="hljs-name">body</span>></span><span class="hljs-tag"><<span class="hljs-name">h1</span>></span>Moved<span class="hljs-tag"></<span class="hljs-name">h1</span>></span><span class="hljs-tag"><<span class="hljs-name">p</span>></span>This page has moved to <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">\</span>"/<span class="hljs-attr">somewhere.else</span>/\"></span>/somewhere.else/<span class="hljs-tag"></<span class="hljs-name">a</span>></span>.<span class="hljs-tag"></<span class="hljs-name">p</span>></span><span class="hljs-tag"></<span class="hljs-name">body</span>></span><span class="hljs-tag"></<span class="hljs-name">html</span>></span>"
|
|
@ -1,22 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> routes: [
|
||||
........> {
|
||||
........> url: <span class="hljs-string">"/url1"</span>,
|
||||
........> content: <span class="hljs-string">"route 1"</span>
|
||||
........> },
|
||||
........> {
|
||||
........> url: <span class="hljs-string">"/url2"</span>,
|
||||
........> content: <span class="hljs-string">"route 2"</span>
|
||||
........> },
|
||||
........> {
|
||||
........> url: <span class="hljs-string">"/url3"</span>,
|
||||
........> content: <span class="hljs-string">"route 3"</span>
|
||||
........> }
|
||||
........> ]
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102224"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102224"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lHG--_"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,14 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/url2</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"route 2"
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/url3</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"route 3"
|
|
@ -1,23 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> urlPrefix: <span class="hljs-string">"/test"</span>,
|
||||
........> routes: [
|
||||
........> {
|
||||
........> url: <span class="hljs-string">"/url1"</span>,
|
||||
........> content: <span class="hljs-string">"route 1"</span>
|
||||
........> },
|
||||
........> {
|
||||
........> url: <span class="hljs-string">"/url2"</span>,
|
||||
........> content: <span class="hljs-string">"route 2"</span>
|
||||
........> },
|
||||
........> {
|
||||
........> url: <span class="hljs-string">"/url3"</span>,
|
||||
........> content: <span class="hljs-string">"route 3"</span>
|
||||
........> }
|
||||
........> ]
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102237"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102237"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lI---_"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,21 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/<span class="hljs-built_in">test</span>/url1</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"route 1"
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/<span class="hljs-built_in">test</span>/url2</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"route 2"
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/<span class="hljs-built_in">test</span>/url3</span>
|
||||
|
||||
HTTP/1.1 undefined
|
||||
content-type: text/plain
|
||||
x-content-type-options: nosniff
|
||||
|
||||
"route 3"
|
|
@ -1,15 +0,0 @@
|
|||
arangosh> db._modules.save({
|
||||
........> path: <span class="hljs-string">"/db:/OwnMiddlewareTest"</span>,
|
||||
........> content:
|
||||
........> <span class="hljs-string">"exports.logRequest = function (req, res, options, next) {"</span> +
|
||||
........> <span class="hljs-string">" console = require('console'); "</span> +
|
||||
........> <span class="hljs-string">" console.log('received request: %s', JSON.stringify(req));"</span> +
|
||||
........> <span class="hljs-string">" next();"</span> +
|
||||
........> <span class="hljs-string">" console.log('produced response: %s', JSON.stringify(res));"</span> +
|
||||
........> <span class="hljs-string">"};"</span>
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_modules/102250"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102250"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lJS--_"</span>
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> middleware: [
|
||||
........> {
|
||||
........> url: {
|
||||
........> match: <span class="hljs-string">"/subdirectory/*"</span>
|
||||
........> },
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"db://OwnMiddlewareTest/logRequest"</span>
|
||||
........> }
|
||||
........> }
|
||||
........> ]
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102254"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102254"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lJa--_"</span>
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/subdirectory/ourtest/1"</span>,
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"@arangodb/actions/echoRequest"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102258"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102258"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lJi--_"</span>
|
||||
}
|
||||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/subdirectory/ourtest/2"</span>,
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"@arangodb/actions/echoRequest"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102261"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102261"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lJi--B"</span>
|
||||
}
|
||||
arangosh> db._routing.save({
|
||||
........> url: <span class="hljs-string">"/subdirectory/ourtest/3"</span>,
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"@arangodb/actions/echoRequest"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102264"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102264"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lJi--D"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,126 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/subdirectory/ourtest/1</span>
|
||||
|
||||
HTTP/<span class="hljs-number">1.1</span> <span class="hljs-literal">undefined</span>
|
||||
content-type: application/json; charset=utf<span class="hljs-number">-8</span>
|
||||
x-content-type-options: nosniff
|
||||
|
||||
{
|
||||
<span class="hljs-string">"request"</span> : {
|
||||
<span class="hljs-string">"authorized"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"user"</span> : <span class="hljs-string">"root"</span>,
|
||||
<span class="hljs-string">"database"</span> : <span class="hljs-string">"_system"</span>,
|
||||
<span class="hljs-string">"url"</span> : <span class="hljs-string">"/subdirectory/ourtest/1"</span>,
|
||||
<span class="hljs-string">"protocol"</span> : <span class="hljs-string">"http"</span>,
|
||||
<span class="hljs-string">"server"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">15674</span>
|
||||
},
|
||||
<span class="hljs-string">"client"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">49765</span>,
|
||||
<span class="hljs-string">"id"</span> : <span class="hljs-string">"153563925279595"</span>
|
||||
},
|
||||
<span class="hljs-string">"internals"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"host"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"authorization"</span> : <span class="hljs-string">"Basic cm9vdDo="</span>,
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json"</span>
|
||||
},
|
||||
<span class="hljs-string">"requestType"</span> : <span class="hljs-string">"GET"</span>,
|
||||
<span class="hljs-string">"parameters"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"cookies"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"urlParameters"</span> : {
|
||||
}
|
||||
},
|
||||
<span class="hljs-string">"options"</span> : {
|
||||
}
|
||||
}
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/subdirectory/ourtest/2</span>
|
||||
|
||||
HTTP/<span class="hljs-number">1.1</span> <span class="hljs-literal">undefined</span>
|
||||
content-type: application/json; charset=utf<span class="hljs-number">-8</span>
|
||||
x-content-type-options: nosniff
|
||||
|
||||
{
|
||||
<span class="hljs-string">"request"</span> : {
|
||||
<span class="hljs-string">"authorized"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"user"</span> : <span class="hljs-string">"root"</span>,
|
||||
<span class="hljs-string">"database"</span> : <span class="hljs-string">"_system"</span>,
|
||||
<span class="hljs-string">"url"</span> : <span class="hljs-string">"/subdirectory/ourtest/2"</span>,
|
||||
<span class="hljs-string">"protocol"</span> : <span class="hljs-string">"http"</span>,
|
||||
<span class="hljs-string">"server"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">15674</span>
|
||||
},
|
||||
<span class="hljs-string">"client"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">49765</span>,
|
||||
<span class="hljs-string">"id"</span> : <span class="hljs-string">"153563925279595"</span>
|
||||
},
|
||||
<span class="hljs-string">"internals"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"host"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"authorization"</span> : <span class="hljs-string">"Basic cm9vdDo="</span>,
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json"</span>
|
||||
},
|
||||
<span class="hljs-string">"requestType"</span> : <span class="hljs-string">"GET"</span>,
|
||||
<span class="hljs-string">"parameters"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"cookies"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"urlParameters"</span> : {
|
||||
}
|
||||
},
|
||||
<span class="hljs-string">"options"</span> : {
|
||||
}
|
||||
}
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/subdirectory/ourtest/3</span>
|
||||
|
||||
HTTP/<span class="hljs-number">1.1</span> <span class="hljs-literal">undefined</span>
|
||||
content-type: application/json; charset=utf<span class="hljs-number">-8</span>
|
||||
x-content-type-options: nosniff
|
||||
|
||||
{
|
||||
<span class="hljs-string">"request"</span> : {
|
||||
<span class="hljs-string">"authorized"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"user"</span> : <span class="hljs-string">"root"</span>,
|
||||
<span class="hljs-string">"database"</span> : <span class="hljs-string">"_system"</span>,
|
||||
<span class="hljs-string">"url"</span> : <span class="hljs-string">"/subdirectory/ourtest/3"</span>,
|
||||
<span class="hljs-string">"protocol"</span> : <span class="hljs-string">"http"</span>,
|
||||
<span class="hljs-string">"server"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">15674</span>
|
||||
},
|
||||
<span class="hljs-string">"client"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">49765</span>,
|
||||
<span class="hljs-string">"id"</span> : <span class="hljs-string">"153563925279595"</span>
|
||||
},
|
||||
<span class="hljs-string">"internals"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"host"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"authorization"</span> : <span class="hljs-string">"Basic cm9vdDo="</span>,
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json"</span>
|
||||
},
|
||||
<span class="hljs-string">"requestType"</span> : <span class="hljs-string">"GET"</span>,
|
||||
<span class="hljs-string">"parameters"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"cookies"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"urlParameters"</span> : {
|
||||
}
|
||||
},
|
||||
<span class="hljs-string">"options"</span> : {
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
arangosh> db._routing.save({
|
||||
........> url: {
|
||||
........> match: <span class="hljs-string">"/hello/world"</span>,
|
||||
........> methods: [ <span class="hljs-string">"get"</span>, <span class="hljs-string">"post"</span>, <span class="hljs-string">"put"</span> ]
|
||||
........> },
|
||||
........> action: {
|
||||
........> <span class="hljs-keyword">do</span>: <span class="hljs-string">"@arangodb/actions/echoRequest"</span>
|
||||
........> }
|
||||
........> });
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"_routing/102298"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"102298"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_XWq5lLa--_"</span>
|
||||
}
|
||||
arangosh> <span class="hljs-built_in">require</span>(<span class="hljs-string">"internal"</span>).reloadRouting()
|
|
@ -1,146 +0,0 @@
|
|||
<span class="hljs-meta">shell></span><span class="bash"> curl --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/hello/world</span>
|
||||
|
||||
HTTP/<span class="hljs-number">1.1</span> <span class="hljs-literal">undefined</span>
|
||||
content-type: application/json; charset=utf<span class="hljs-number">-8</span>
|
||||
x-content-type-options: nosniff
|
||||
|
||||
{
|
||||
<span class="hljs-string">"request"</span> : {
|
||||
<span class="hljs-string">"authorized"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"user"</span> : <span class="hljs-string">"root"</span>,
|
||||
<span class="hljs-string">"database"</span> : <span class="hljs-string">"_system"</span>,
|
||||
<span class="hljs-string">"url"</span> : <span class="hljs-string">"/hello/world"</span>,
|
||||
<span class="hljs-string">"protocol"</span> : <span class="hljs-string">"http"</span>,
|
||||
<span class="hljs-string">"server"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">15674</span>
|
||||
},
|
||||
<span class="hljs-string">"client"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">49765</span>,
|
||||
<span class="hljs-string">"id"</span> : <span class="hljs-string">"153563925279595"</span>
|
||||
},
|
||||
<span class="hljs-string">"internals"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"host"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"authorization"</span> : <span class="hljs-string">"Basic cm9vdDo="</span>,
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json"</span>
|
||||
},
|
||||
<span class="hljs-string">"requestType"</span> : <span class="hljs-string">"GET"</span>,
|
||||
<span class="hljs-string">"parameters"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"cookies"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"urlParameters"</span> : {
|
||||
}
|
||||
},
|
||||
<span class="hljs-string">"options"</span> : {
|
||||
}
|
||||
}
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl -X POST --header <span class="hljs-string">'accept: application/json'</span> --data-binary @- --dump - http://localhost:8529/hello/world</span> <<EOF
|
||||
{hello: 'world'}
|
||||
EOF
|
||||
|
||||
HTTP/<span class="hljs-number">1.1</span> <span class="hljs-literal">undefined</span>
|
||||
content-type: application/json; charset=utf<span class="hljs-number">-8</span>
|
||||
x-content-type-options: nosniff
|
||||
|
||||
{
|
||||
<span class="hljs-string">"request"</span> : {
|
||||
<span class="hljs-string">"authorized"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"user"</span> : <span class="hljs-string">"root"</span>,
|
||||
<span class="hljs-string">"database"</span> : <span class="hljs-string">"_system"</span>,
|
||||
<span class="hljs-string">"url"</span> : <span class="hljs-string">"/hello/world"</span>,
|
||||
<span class="hljs-string">"protocol"</span> : <span class="hljs-string">"http"</span>,
|
||||
<span class="hljs-string">"server"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">15674</span>
|
||||
},
|
||||
<span class="hljs-string">"client"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">49765</span>,
|
||||
<span class="hljs-string">"id"</span> : <span class="hljs-string">"153563925279595"</span>
|
||||
},
|
||||
<span class="hljs-string">"internals"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"host"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"authorization"</span> : <span class="hljs-string">"Basic cm9vdDo="</span>,
|
||||
<span class="hljs-string">"content-length"</span> : <span class="hljs-string">"16"</span>,
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json"</span>
|
||||
},
|
||||
<span class="hljs-string">"requestType"</span> : <span class="hljs-string">"POST"</span>,
|
||||
<span class="hljs-string">"requestBody"</span> : <span class="hljs-string">"{hello: 'world'}"</span>,
|
||||
<span class="hljs-string">"parameters"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"cookies"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"urlParameters"</span> : {
|
||||
}
|
||||
},
|
||||
<span class="hljs-string">"options"</span> : {
|
||||
}
|
||||
}
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl -X PUT --header <span class="hljs-string">'accept: application/json'</span> --data-binary @- --dump - http://localhost:8529/hello/world</span> <<EOF
|
||||
{hello: 'world'}
|
||||
EOF
|
||||
|
||||
HTTP/<span class="hljs-number">1.1</span> <span class="hljs-literal">undefined</span>
|
||||
content-type: application/json; charset=utf<span class="hljs-number">-8</span>
|
||||
x-content-type-options: nosniff
|
||||
|
||||
{
|
||||
<span class="hljs-string">"request"</span> : {
|
||||
<span class="hljs-string">"authorized"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"user"</span> : <span class="hljs-string">"root"</span>,
|
||||
<span class="hljs-string">"database"</span> : <span class="hljs-string">"_system"</span>,
|
||||
<span class="hljs-string">"url"</span> : <span class="hljs-string">"/hello/world"</span>,
|
||||
<span class="hljs-string">"protocol"</span> : <span class="hljs-string">"http"</span>,
|
||||
<span class="hljs-string">"server"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">15674</span>
|
||||
},
|
||||
<span class="hljs-string">"client"</span> : {
|
||||
<span class="hljs-string">"address"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"port"</span> : <span class="hljs-number">49765</span>,
|
||||
<span class="hljs-string">"id"</span> : <span class="hljs-string">"153563925279595"</span>
|
||||
},
|
||||
<span class="hljs-string">"internals"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"headers"</span> : {
|
||||
<span class="hljs-string">"host"</span> : <span class="hljs-string">"127.0.0.1"</span>,
|
||||
<span class="hljs-string">"authorization"</span> : <span class="hljs-string">"Basic cm9vdDo="</span>,
|
||||
<span class="hljs-string">"content-length"</span> : <span class="hljs-string">"16"</span>,
|
||||
<span class="hljs-string">"connection"</span> : <span class="hljs-string">"Keep-Alive"</span>,
|
||||
<span class="hljs-string">"accept"</span> : <span class="hljs-string">"application/json"</span>,
|
||||
<span class="hljs-string">"content-type"</span> : <span class="hljs-string">"application/json"</span>
|
||||
},
|
||||
<span class="hljs-string">"requestType"</span> : <span class="hljs-string">"PUT"</span>,
|
||||
<span class="hljs-string">"requestBody"</span> : <span class="hljs-string">"{hello: 'world'}"</span>,
|
||||
<span class="hljs-string">"parameters"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"cookies"</span> : {
|
||||
},
|
||||
<span class="hljs-string">"urlParameters"</span> : {
|
||||
}
|
||||
},
|
||||
<span class="hljs-string">"options"</span> : {
|
||||
}
|
||||
}
|
||||
<span class="hljs-meta">shell></span><span class="bash"> curl -X DELETE --header <span class="hljs-string">'accept: application/json'</span> --dump - http://localhost:8529/hello/world</span>
|
||||
|
||||
HTTP/<span class="hljs-number">1.1</span> <span class="hljs-literal">undefined</span>
|
||||
content-type: application/json; charset=utf<span class="hljs-number">-8</span>
|
||||
x-content-type-options: nosniff
|
||||
|
||||
{
|
||||
<span class="hljs-string">"error"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"code"</span> : <span class="hljs-number">404</span>,
|
||||
<span class="hljs-string">"errorNum"</span> : <span class="hljs-number">404</span>,
|
||||
<span class="hljs-string">"errorMessage"</span> : <span class="hljs-string">"unknown path '/hello/world'"</span>
|
||||
}
|
Loading…
Reference in New Issue