Getting started with ArangoDB and Foxx: Joifully CRUD-y in the best way.

And a little bit of isomorphic validation

Not sure how I first discovered ArangoDB but it is certainly interesting. Perhaps it was the Avocado logo and I was hungry (ArangoDB was originally called AvocadoDB; the name was dropped but the logo retained).

The first thing that you might run into with Arango is that it’s a bit of a jack-of-all-trades. It’s a NoSQL document store with a SQL-ish query language, but it’s schema-less and can do graph stuff natively. It’s also “mostly main memory.” And, oh yeah, it’s a Javascript V8-based interpreter that can host HTTP servers. Surprise! That Javascript is synchronous and users a thread pool. So, with ArangoDB, it defies definition and turns assumptions on their head.

The bit about it being synchronous really gave me pause. If you’ve been in the Node.js world for a while then you might write off ArangoDB for this, but I think you’d be a bit too hasty. Arango works in a thread pool instead of a single thread so being synchronous doesn’t mean that you’re server is blocked.

To dip by toe in, I started to read the docs. Given the broad scope of ArangoDB, the docs suffer a bit from trying to cover everything and tell you precisely what and why. It’s also helpful to download the Community Edition and install it on your dev machine. I’ve yet to find a cloud provider that will spin up a low cost instance on which to play, so you’ll need to install it. I would suggest manually starting and stopping it as the server instance isn’t terrible in memory usage, but it’s not tiny either.

Memory usage on my MacBook

A nice feature of ArangoDB is that it comes with a baked-in web management console called Ardvark. Ardvark isn’t perfect (a few crash/hiccups when I made some bone-head moves) but it helps out in the very beginning to explore the system.

On to Javascript

While ArangoDB is written primarily in C++, it integrates very tightly with Javascript. Any text-based manipulation of the database will be done with Javascript syntax. The Foxx framework that is built into ArangoDB allows you to build “microservices” in an environment that seems like and is somewhat compatible with Node.js. This is compelling for me: I really never need to leave Javascript to build a web app.

This brings me to what Arango seems to really be meant to do: build CRUD (Create, Read, Update and Delete) apps. It can seem like 95% of the web apps in the world are, at some level, just CRUD apps. The shocking thing to me is that there doesn’t seem to be an integrated solution to short-cut building this class of app. I see companies I work with often use wholly inappropriate tools when building out CRUD-based apps.

Rant: One of these inappropriate tools is Wordpress. You would be surprised the number projects that are based on Wordpress that really are just some sort of misuse of the blogging platform into a CRUD app with private C/U/D. Sometimes developers shoe horn a private, login-based system based off of bubble gum, bailing wire and the Wordpress admin panel. It very often ends in tears, or, at very least, a massively sluggish, hard to maintain and insecure website that makes no one happy. However, this type of Wordpress site is inexpensive to build and cheap to host, I guess that’s why it’s hard to ignore.

I really see ArangoDB excelling at building these basic kinds of sites as it’s pretty simple to build out CRUD operations in a few lines. The Foxx framework has support for JWT and sessions, so you’re pretty far along already to have a user login system.

Routing is very Express like. It supports the same basic path format, middleware, and the same req, res, next handler/middleware function signatures. Additionally it can use child routers in the same way as Express has mountable routers.

A challenge that people face when building CRUD sites is that validation can be a pain to the point that developers leave it out to their own peril. Foxx uses the joi module for validation on input, output and parameters. It’s very integrated and I’m okay with that. joi has a very straight forward, fluent syntax. Odds are after spending a little bit of time with joi you’ll be able to just guess the syntax correctly instead of memorizing it.

While ArangoDB and Foxx conceptually compresses your database and server stack layers, you still have the front-end to deal with. Everyone knows that you need to validate on both the front-end and back-end. The front-end validation provides a smoother experience for the user and takes some burden off of the back-end. It’s the first line of defense where the back-end validation is the real security for your server and data.

Since you’ve got Javascript on every level of our stack now, it got me thinking. Could you merge your front-end validation with your back-end validation? It’s possible! It’s isomorphic validation!

Here is the game plan:

  • Encapsulate the joi validation inside a function with joi being passed as an argument:
var myThing = function(joi) {
return joi
.object()
.keys({
exists : joi.boolean().required()
})
};

Note: It’s important that you use no other variables from outside the validation function.

  • In your Foxx microservice, setup your route’s body with this validation:
router
.post('/my-thing',function(req,res) {
...
})
.body(myThing(joi))

So far, this is just a slight modification of how the Foxx documentation outlines setting up a route.

  • Now this get’s interesting. Foxx allows you to make routes completely un-related to ArangoDB. Let’s setup a validation route and then send back the source to the function we created in the first step.
router
.get('/validator/:varName',function(req,res) {
      res.send(`var ${req.pathParams.varName} = ${myThing.toString()};`);
  });

This might look a little funny — I’m using the backticks because it’s a template string and the curly braces to interpolate varName and coercing the function myThing into a function. If you go to it ([service prefix]/validator/[anything valid as a var]), Foxx will reply back with the function. So, as an example, going to [service prefix]/validator/myValidator yields this:

var myValidator = function(joi) {
return joi
.object()
.keys({
exists : joi.boolean().required()
})
};
  • Now, Joi is normally a server-side validation library, however, using something like webpack (or browserify) and joi-browser, you can call Joi from your client-side code. Then you include the route from the previous step as a normal script tag. Finally, you run your JS as normal (after pre-processsing):
import joi from 'joi-browser';
console.log(
joi.validate({ exists : true }, myValidator(joi))
);

This technique enables you to skip duplicating validation effort and focus on building your app. Stay tuned, I’m working on some more Foxx and ArangoDB tips and tricks as my project shapes up.