Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Entities on Node.js

Entities on Node.js

The Node.js implementation of Entities

Thanos Polychronakis

December 04, 2014
Tweet

More Decks by Thanos Polychronakis

Other Decks in Technology

Transcript

  1. Entities use Entities use CIP ​for Classical Inheritance /thanpolas/cip Bluebird

    for the 100% Promises API /petkaantonov/bluebird Middlewarify for creating middleware /thanpolas/middlewarify @thanpolas
  2. Creating an Entity Creating an Entity var entity = require('entity');

    var EntityChild = entity.extend(function() { this.a = 1; }); var EntityGrandChild = EntityChild.extend(); entity.extend var entity = require('entity'); var UserEntity = entity.extendSingleton(function() {}); /* ... */ var userEnt = UserEntity.getInstance(); entity.extendSingleton @thanpolas
  3. Entities Adaptors Entities Adaptors Mongoose Mongoose MongoDB ORM http://mongoosejs.com/ Sequelize

    Sequelize PostgreSQL MySQL MariaDB SQLite http://sequelizejs.com/ @thanpolas
  4. CRUD Primitives CRUD Primitives create() create() entity.create({name: 'thanasis'}) .then(function(udo) {

    udo.name === 'thanasis'; // true }) .catch(function(error) { // deal with error. }); ... so on and so forth ... @thanpolas
  5. Entity Hooks Entity Hooks before before // a middleware with

    synchronous resolution entity.read.before(function(data){ if (!data.name) { throw new TypeError('No go my friend'); } }); // then... entity.read({}).then(function(document) { // you'll never get here }, function(err) { err instanceof Error; // true err.message === 'No go my friend'; // true }); @thanpolas
  6. Before Hooks Before Hooks Get the exact same number or

    arguments After & Last Hooks After & Last Hooks Gets the result plus the original number or arguments @thanpolas
  7. Extending Entities Extending Entities Just use the prototype Just use

    the prototype var Entity = require('entity'); var UserEntity = module.exports = Entity.extend(); UserEntity.prototype.report = function(userId) { return promiseReturningAction(userId); }; @thanpolas
  8. Extending Entities Extending Entities Using method() Using method() var Entity

    = require('entity'); var UserEntity = module.exports = Entity.extend(function() { this.method('report', this._report.bind(this)); this.report.before(this._checkUserId.bind(this)); this.report.after(this._normalize.bind(this)); }); UserEntity.prototype._report = function(userId) { return promiseReturningAction(userId); }; @thanpolas
  9. var ClipEntity = module.exports = EntityBase.extendSingleton(function() { this.setModel(clipModel.Model); this.method('readOneApi', this.readOne);

    this.method('readLimitApi', this.readLimit); this.method('updateApi', this.update); this.method('readApi', this.read); // Apply system wide (global) filters this.readLimitApi.before(this.systemFilter.bind(this)); this.readOneApi.before(this.systemFilter.bind(this)); // Clip Creation middleware this.create.before(this._populateActiveEvent.bind(this)); this.create.after(this._processNewClip.bind(this)); // Record sanitization middleware this.updateApi.after(helpers.skipArgs(this.sanitizeResult, 2, this)); this.readLimitApi.after(helpers.skipArgs(this.sanitizeResults, 3, this)); this.readOneApi.after(helpers.skipArgs(this.sanitizeResult, 1, this)); }); A Production-ish Entity A Production-ish Entity @thanpolas
  10. Entity Hands On Entity Hands On this.readLimitApi.before(this.systemFilter.bind(this)); /** * Apply

    system filters in all incoming READ queries * to exclude deleted and corrupt items. * * @param {Object} query The query. */ ClipEntity.prototype.systemFilter = function(query) { query.notFound = { ne: true }; query.processed = true; }; @thanpolas
  11. Entity Hands On Entity Hands On this.create.after(this._processNewClip.bind(this)); /** * Post

    creation clip processing. * * @param {Object} data Item used to create the record. * @param {app.entity.ClipProcess} processEnt The process entity. * @param {mongoose.Document} clipItem The result. * @return {Promise} A promise. * @private */ ClipEntity.prototype._processNewClip = Promise.method(function(data, processEnt, clipItem) { processEnt.clipId = clipItem.id; log.finest('_processNewClip() :: Clip Saved to DB, starting FS save...', clipItem.id); return this._checkWatermarkAndStore(processEnt, clipItem) .bind(processEnt) .then(processEnt.createThumbnail) .then(processEnt.checkS3) .then(processEnt.updateDatabase) .then(function() { log.fine('_processNewClip() :: Clip processing finished:', processEnt.sourceFilePath); }) .catch(processEnt.moveToTrash) .catch(processEnt._deleteRecord); }); @thanpolas
  12. Entities Entities + + Crude Crude POST /user GET /user

    GET /user/:id PUT /user/:id PATCH /user/:id DELETE /user/:id /thanpolas/crude @thanpolas
  13. Shameless Plug Time Promo Code bgwebsummit From 60€ --> 40€

    15/5/2015 @ Thessaloniki Greece devitconf.org