5

I am working on an app that would greatly benefit from Arangos' multi-model capabilities. Considering the app needs for the back-end, I have concluded that most, if not all, of it could be served through a REST API as to aid cleaner design for future development and integration with others. The API would then be consumed by several web and mobile front-end frameworks to handle the rest of the logic. The project will be developed with Javascript for the whole stack, using the NodeJS ecosystem.

.

The question itself:

Should and could one use arangodb + foxx to create the complete back-end stack for serving a REST API, thus avoiding another layer/component in the stack? e.g. express/hapi/loopback etc.

.

Major back-end requirements:

  • Authentication with roles
  • Sessions
  • Encryption
  • Complex querying (root of my initial thought, as to avoid multiple hops between DB and back-end)
  • Entry parsing, validation and sanitization
  • Scheduled tasks

.

Mainly looking for:

  • Known design advantages
  • Known design limitations
  • "Hidden" bottlenecks
  • Other possible future regrets

.

Side question (that might answer some of the above): Could Foxx utilise some of the node middleware available via npm?

Thanks in advance for your time!

GRE2608
  • 51
  • 2
  • 1
    Hey @GRE2608, as you found my answer useful, could you mark it as accepted to close this question? Or is there anything else you'd need me to address in my answer for it to be acceptable? – Alan Plum Aug 23 '16 at 20:00

2 Answers2

5

You can use ArangoDB Foxx as the sole backend of your application, however it is important to keep the limitations of Foxx (compared to a general purpose JS environment like Node.js) in mind when doing this.

You mention encryption. While ArangoDB does support some cryptography (e.g. HMAC signing and PBKDF2 key derivation for passwords) the support is not as exhaustive and extensible as in Node.js. Also when using computationally expensive cryptography this will affect the performance of the database (because unlike Node.js Foxx is strictly synchronous and thus all operations should be considered blocking).

ArangoDB does not support role-based authentication out of the box but it is perfectly reasonable to implement it within ArangoDB using Foxx (just like you would implement it in Node.js, except you don't need to leave the database).

For sessions there are generally two possible approaches: you can either use a collection with session documents (using ArangoDB as your session backend) or you can keep your services stateless by using signed tokens (Foxx comes with JWT support out of the box).

Complex/stored queries and input validation (using the joi schema library originally written for hapi) are actually some of the main use cases of Foxx so those shouldn't be any problem whatsoever.

Foxx comes with its own mechanism for queueing tasks, which can also be scheduled ahead or recur periodically. However depending on your requirements an external job or message queue may be a better fit. The good thing is you can get started with the built-in job queue right away and still move on to a dedicated solution if the need arises during development.

As for middleware and NPM packages: Foxx is not fully compatible with Node.js code. While we provide a lot of compatibility code and try to keep the core modules compatible where possible, a big difference is that Node.js is generally used to perform asynchronous operations while in ArangoDB all operations are synchronous.

If you have Node.js modules that don't use crypto, file or network I/O and don't use asynchronous APIs (e.g. setTimeout, promises) they may be compatible with Foxx. A lot of utility libraries like lodash work with no problems at all. Even if you find that a module doesn't work it may be possible to write an adapter for it like we have done with mocha (integrated into Foxx) and GraphQL (via the graphql-sync package on NPM).

In my experience it is a good approach to put your Foxx service behind a thin layer of Node.js (e.g. a simple express application that mostly just proxies to your Foxx API) and/or to delegate some parts of your backend to standalone Node.js microservices (e.g. integration with non-HTTP services like e-mail or LDAP) which can be integrated in Foxx via HTTP.

One more thing: while a lot of existing express middleware likely isn't compatible with Foxx because of Node-specific dependencies and async logic, ArangoDB 3 will bring a new version of Foxx with support for middleware using a functionally express-compatible API.

Alan Plum
  • 10,814
  • 4
  • 40
  • 57
  • 1
    Thanks Alan! Having considered all your notes, I will proceed with building the base app components and hopefully by the time we need to get down to the hardcore details v3 will be already in stable branch. Still, your concept of a thin nodejs layer in front of Arango is indeed a good way to go as most likely there will be other nonDB related microservices that will need to be implemented. On your last comment, do you know if v3 will bring _native_ async or will it just be compatible to async middleware? – GRE2608 Jun 01 '16 at 19:53
  • 1
    @GRE2608 Just to clarify that point: Foxx is explicitly not compatible with anything async by default. However a lot of express middleware doesn't actually rely on async behaviour so that can often simply work with Foxx. – Alan Plum Aug 23 '16 at 19:59
4

I'm just starting to port my sails application to a FOXX application so I can answer some of your questions.

Role based authorization in ArangoDB is probably at too high a level than you want. In our case, we use an external service to authorize various web and service based applications at a very fine-grained level (much lower than a vertex or an edge). My feeling is that Authorization at that level will require you to write it yourself in javascript. If it's just CRUD on a per collection basis, then it shouldn't require much effort.

For authorization and sessions, I would look at the FOXX example found at: FOXX authorization-session example

It's not clear what you're asking about encryption. If you're talking about SSL connections, then that is natively supported (see arangodb end-points). As for internal encryption, there is a javascript crypto module ArangoDb crypto

Entry validation, etc. is supported by the javascript joi package.

Complex querying... Absolutely and getting even better in ArangoDB version 3.x. Traversals can be chained (go down using one edge collection, then up using another).

You're right on the ball when thinking about efficiency. This is the main reason we're going from sails to FOXX. In our case, we filter query results based on permissions from our external service. This means that we can't use ArangoDB native skip and limit support if these attributes are specified by the client. In sails, we have to bring back results in chunks and collect until we hit the appropriate skip and limit values. By moving to FOXX, we save a lot of network and other resources. We tested this by having sails forward the request to our prototype FOXX implementation. This scaled much better than the sails post-processing setup.

You can use NPM modules with restrictions. See Javascript Modules

ggendel
  • 403
  • 3
  • 9
  • 1
    Thank you ggendel! Please keep us updated via this question on how things will turn out when you are all done with your porting. – GRE2608 Jun 01 '16 at 19:43
  • 1
    The sails application (which is still in prototype form), has been completely ported to Foxx. Bottom line, with no significant code changes mostly changing the sails/arangojs queries to Foxx ones, Foxx is significantly faster. One testcase took 3.5 hours in sails and 29 minutes in Foxx (a 7x speedup). Since the AQL calls are virtually the same, I have to chalk it up to network traffic and reprocessing the data on the sails side. – ggendel Jun 06 '16 at 20:35