auto-crud

A simple tool for automatically generating REST APIs with json schemas and mongodb.

auto-crud

auto-crud is an abstraction layer for generating REST routes to perform basic CRUD operations. It glues together express, mongo and json-schema validation. The end goal is to define CRUD APIs in a declarative and uniform way instead of writing route handlers directly.

The auto-crud module exports a single function which takes a configuration object as its only input.

autocrud({
    app: app,                   // The express application object. 
    collection: mongo.hoosit,   // The collection object generated by the mongo driver. 
    name: 'hoosit',             // The name of the object (this will be appended to the end of path). 
    path: '/api',               // The root URL path that this API should be generated at. 
    schema: {                   // The json schema that should be used for validation 
        type: 'object',
        properties: {
            name: {type: 'string', required: true},
            description: {type: 'string'},
            rating: {type: 'integer'},
            comments: {type: 'array', items: {type: 'string'}}
        },
        additionalProperties: false
    }
});

  • app The express application object. This is used to generate REST routes for GET, POST, PUT and DELETE.
  • collection The mongo collection object. This is where the API will store its data. NOTE: this tool will not ensure indexes.
  • name The name of this API's objects, this will also be appended to the end of the path param when generating routes.
  • path The root path for the routes generated by this API.
  • schema The json-schema that will be used to validate objects given to the API by POST and PUT.

It is often that input data from a client application differs from how you want to store data in your database. So, auto-crud allows you to specify transformation functions, which will be called after the input object has been validated, but before a database insert or update.

autocrud({
    ... // Default options 
    postTransformfunction (body) {
        if (!body.rating) body.rating = 1;
    }
});

Transform functions take a single parameter, which is the message body after it has been validated.

  • defaultTransform If specified, this transform function will be applied to both POST and PUT operations.
  • postTransform If specified, this function will be used for POST operations, overriding the defaultTransform.
  • putTransform If specified, this function will be used for PUT operations, overriding the defaultTransform.

No API would be complete without having an authentication mechanism. This is supported by adding an express middleware function to the configuration object. This allows auto-crud to be agnostic about how users are authenticated. I tend to prefer passport, so that is what is shown in the example.

autocrud({
    ... // Default options 
    defaultAuthenticationfunction (reqresnext) {
        if (req.isAuthenticated() && _.contains(req.user.roles, 'administrator')) next();
        else res.send(401, 'Unauthenticated');
    }
});
  • defaultAuthentication If specified, this middleware will by applied to all HTTP methods on the auto-curd route.
  • getAuthentication If specified, this middleware will be applied to the GET HTTP method. Overrides default.
  • postAuthentication If specified, this middleware will be applied to the POST HTTP method. Overrides default.
  • putAuthentication If specified, this middleware will be applied to the PUT HTTP method. Overrides default.
  • deleteAuthentication If specified, this middleware will be applied to the DELETE HTTP method. Overrides default.

Often, the API doesn't need to authenticate users based on any sort of roles, but upon what objects are actually owned by the user. auto-crud provides a facility to automatically tag mongo documents with a value representing the owner. Typically this is the ObjectID of the user in question.

autocrud({
    ... // Default options 
    ownerIdFromReqfunction (req) {
        return new ObjectID(req.user._id);
    },
    ownerField: 'owner'
});

NOTE: Both of the following fields must be provided for object ownership to be enabled.

  • ownerIdFromReq A function that extracts the user id value from the request object. This is passed as the first param.
  • ownerField The name of the field in each mongo document that holds the owner id.