diff --git a/Documentation/UserManual/Actions.md b/Documentation/UserManual/Actions.md index 109a4ec093..f6f7620bf4 100644 --- a/Documentation/UserManual/Actions.md +++ b/Documentation/UserManual/Actions.md @@ -307,9 +307,9 @@ The simplest dynamic action is: { action: { do: "org/arangodb/actions/echoRequest" } } -It is not possible to store functions directly in the routing table, but you can -call functions defined in modules. In the above example the function can be -accessed from JavaScript as: +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: require("org/arangodb/actions").echoRequest @@ -406,6 +406,17 @@ The definition is a short-cut for a prefix controller definition. +Function Action {#UserManualActionsFunctionAction} +-------------------------------------------------- + +You can also store a function directly in the routing table. + +For example + + arangosh> db._routing.save({ + ........> url: "/hello/echo", + ........> action: { function: "function(req,res) {res.statusCode=200; res.body='Hallo'}" } }); + Requests and Responses {#UserManualActionsReqRes} ================================================= diff --git a/Documentation/UserManual/ActionsTOC.md b/Documentation/UserManual/ActionsTOC.md index 2e689127c0..de6472d33e 100644 --- a/Documentation/UserManual/ActionsTOC.md +++ b/Documentation/UserManual/ActionsTOC.md @@ -18,6 +18,7 @@ TOC {#UserManualActionsTOC} - @ref UserManualActionsContentAction - @ref UserManualActionsContentController - @ref UserManualActionsContentPrefix + - @ref UserManualActionsFunctionAction - @ref UserManualActionsReqRes - @ref UserManualActionsModify - @ref UserManualActionsHandlers diff --git a/js/client/modules/org/arangodb/deploy.js b/js/client/modules/org/arangodb/deploy.js index 2376bcd0fa..995c9698a0 100644 --- a/js/client/modules/org/arangodb/deploy.js +++ b/js/client/modules/org/arangodb/deploy.js @@ -158,6 +158,37 @@ ArangoApp.prototype._PRINT = function (route) { /// @{ //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// @brief mounts one function directly +//////////////////////////////////////////////////////////////////////////////// + +ArangoApp.prototype.mountStaticFunction = function (url, func, methods) { + if (url === "") { + url = "/"; + } + else if (url[0] !== '/') { + url = "/" + url; + } + + if (methods === undefined) { + methods = [ "GET", "HEAD" ]; + } + + pages = { + type: "StaticFunction", + key: url, + url: { match: url }, + action: { + 'function': String(func), + methods: methods, + } + }; + + this.updateRoute(pages); + + return this; +}; + //////////////////////////////////////////////////////////////////////////////// /// @brief mounts one page directly //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/modules/org/arangodb/actions.js b/js/server/modules/org/arangodb/actions.js index 970539c9a8..a358bceed0 100644 --- a/js/server/modules/org/arangodb/actions.js +++ b/js/server/modules/org/arangodb/actions.js @@ -216,6 +216,8 @@ function lookupCallbackAction (route, action) { var func; var module; var joined; + var defn; + var env; var httpMethods = { 'get': exports.GET, 'head': exports.HEAD, @@ -225,10 +227,50 @@ function lookupCallbackAction (route, action) { 'patch': exports.PATCH }; + // ............................................................................. + // short-cut for prefix controller + // ............................................................................. + if (typeof action === 'string') { return lookupCallbackAction(route, { prefixController: action }); } + // ............................................................................. + // function + // ............................................................................. + + if (action.hasOwnProperty('function')) { + defn = "func = " + action['function']; + env = {}; + + try { + internal.execute(defn, env, route); + + if (env.hasOwnProperty("func")) { + func = env.func; + } + else { + func = notImplementedFunction(route, + "could not define function '" + action['function']); + } + } + catch (err) { + func = errorFunction(route, + "an error occurred while loading function '" + + action['function'] + "': " + String(err)); + } + + return { + controller: func, + options: action.options || {}, + methods: action.methods || exports.ALL_METHODS + }; + } + + // ............................................................................. + // function from module + // ............................................................................. + if (action.hasOwnProperty('do')) { path = action['do'].split("/"); name = path.pop(); @@ -272,6 +314,10 @@ function lookupCallbackAction (route, action) { }; } + // ............................................................................. + // controller module + // ............................................................................. + if (action.hasOwnProperty('controller')) { try { module = require(action.controller); @@ -322,6 +368,10 @@ function lookupCallbackAction (route, action) { } } + // ............................................................................. + // prefix controller + // ............................................................................. + if (action.hasOwnProperty('prefixController')) { var prefixController = action.prefixController;