Nodal 0.7: GraphQL, Conditional Joins, Strong Parameters, New Architecture

It's been two weeks since our last release (0.6) and we're ready to push out 0.7. This update includes a refactor of the basic architecture, so hold tight.

We're proud to announce GraphQL Support, Conditional Joins, Strong Parameters, Sensitive Fields and a new Stateless Architecture.

If you'd like an overview on Nodal, please check out Nodal on Github.

Included in 0.7

GraphQL

To begin with, we're proud to announce that Nodal has started supporting GraphQL as an interface layer between your PostgreSQL database and your endpoints, giving the client full control over the data they retrieve (if you'd like to enable it). We're a little bit unique in our implementation and still working out some details, but querying is a go!

If you're unfamiliar with the GraphQL specification, you're welcome to check out a brief introduction to GraphQL.

Using GraphQL to fetch model data or manipulate responses is easy. In any Controller, you can just use;

const GraphQuery = Nodal.GraphQuery; GraphQuery.query(str, 5, (err, models, format) => { this.respond(err || models, format); });

Where models are the full models fetched, and format is the format (which fields to show) of your models.

If you wanted to query your users and get some data, you might do the following;

GraphyQuery.query( 'users { id, username, email }', 0, (err, models, format) => this.respond(err || models, format) );

If you wanted to choose a specific user and join in some posts...

GraphyQuery.query( 'users(id: 7) { id, username, posts { body } }', 0, (err, models, format) => this.respond(err || models, format) );

The number (0) in this case specifies the max depth to traverse. Setting 0 means queries can have unlimited depth.

Conditional Joins

In order to make sure we could support GraphQL syntax, we also enabled Conditional Joins. You can now restrict which models get joined on a query.

User.query() .where({posts__body__icontains: 'Minecraft'}) .join('posts', {body__icontains: 'Minecraft'}) .end((err, users) => { // All users who have posted about minecraft, containing their // minecraft-related posts });

Strong Parameters

In a Controller, this.params.query and this.params.body are now instances of StrongParameters meaning you can restrict which fields you'd like to have access to.

// input {name: 'Gemma', age: 45} -> this.params.query.except('name'); // -> output {age: 45} // input {name: 'Gemma', age: 45} -> this.params.query.permit('name'); // -> output {name: 'Gemma'}

You can still access the raw POST body with this.params.buffer .

Sensitive Fields

To prevent accidentally showing your users secure fields (i.e. password) by mistyping, you can secure fields with Model.hides in your Model definition file.

// Password will NEVER be shown as the output of an API response User.hides('password');

Stateless Architecture

Nodal has done away with the traditional monolithic, stateful app running in a single process. The Nodal Daemon now distributes load across cores and all Middleware / Renderware is handled by the router and individual controllers.

To specify middleware / renderware for the router (global, all controllers) use:

router.middleware.use(myMiddleware); // goes first (before controller) router.renderware.use(myRenderware); // goes last (after controller)

And for a specific controller, use the brand new before() method in your Controller definition file.

class MyController extends Nodal.Controller { before() { this.middleware.use(RateLimitMiddleware); this.renderware.use(TransformDataRenderware); } }

... and More!

This release also includes a number of minor (and major) bugfixes. We'd like to thank the community for all their support and we hope you keep enjoying Nodal!

Keep up to date at nodaljs.com as well as Nodal on GitHub.