简体   繁体   中英

ArangoDB with custom JS

Hello is there any way to use JS environment built in ArangoDB to execute custom JS? I'd like to set up path to my JS files which would be executed instead of foxx application files.

Via GitHub: https://github.com/arangodb/arangodb/issues/1723#issuecomment-183289699

You are correct that modules are cached independently of the routing cache. Clearing the module cache (or preventing a module from being cached) is currently not supported.

The actions mechanism is really only intended as an internal API and only supported for backwards compatibility with early ArangoDB versions and some edge cases.

As you may have noticed while digging through the ArangoDB source code, Foxx provides a per-service module cache which is cleared whenever a Foxx service is reloaded. I would strongly encourage you to see whether Foxx fits your use case before continuing to dig into the actions mechanism.

It's actually possible to create a Foxx service with just two files (a manifest and a controller file) and without using repositories or models (you can just use the same APIs available in actions).

You just need a controller file like this (eg ctrl.js ):

 'use strict'; const Foxx = require('org/arangodb/foxx'); const ctrl = new Foxx.Controller(applicationContext); ctrl.get('/', function (req, res) { res.send('Hello World'); }); 

with a manifest.json like this:

 { "name": "my-foxx", "version": "0.0.0", "controllers": "ctrl.js", "defaultDocument": "", "engines": {"arangodb": "^2.8.0"} } 

You can then mount the service (upload a zip bundle) at a path like /db and access it:

 curl http://localhost:8529/_db/_system/db 

The upcoming 3.0 release will remove a lot of the existing conceptual overhead of Foxx which will hopefully make it even easier to get started with it.

Yes, this can be done with User Actions . Foxx was created as a more comfortable alternative and is likely a better choice for non-trivial applications. The documentation can be intimidating but Foxx services can actually be very lightweight and simple (see my other answer). If you really don't want to use Foxx for this, here's how to do it manually:

First create a virtual module in the _modules system collection:

var db = require('org/arangodb').db;
db._modules.save({
  path: '/db:/ownTest',
  content: `
    exports.do = function (req, res, options, next) {
      res.body = 'test';
      res.responseCode = 200;
      res.contentType = 'text/plain';
    };
  `
});

Then create a route that uses it:

db._routing.save({
  url: '/ourtest', 
  action: {
    controller: 'db://ownTest'
  }
});

Finally, tell ArangoDB to update its routing cache so it notices the new route:

require('internal').reloadRouting();

If you install your JavaScript module to the js/common/ or the js/server/ directory you can use the module name (eg myOnDiskModule ) instead of the virtual module name "db://owntest" in the controller .

For smaller modules you can just define the function inline using callback instead of controller :

db._routing.save({ 
  url: '/hello/echo',
  action: { 
    callback: `
      function (req, res) {
        res.statusCode = 200;
        res.body = require('js-yaml').safeDump({
          Hello: 'World',
          are: 'you here?'
        });
      }
    `
  } 
});

Remember to always update the routing cache after changes to the routing collection:

require('internal').reloadRouting();

Note: the callback implementation in 2.8 has a bug that will be fixed in 2.8.3. If you want to apply the fix manually, it's in commit b714dc5 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM