Entities on Node.jsEntities on Node.js
/thanpolas/entity/thanpolas/entity
Entities useEntities use
CIP
​for Classical Inheritance
/thanpolas/cip
Bluebird
for the 100% Promises API
/petkaantonov/bluebird
Middlewarify
for creating middleware
/thanpolas/middlewarify
Entities extendEntities extend
events.EventEmitter
...and that's the only thing they do
Creating an EntityCreating 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
Entities AdaptorsEntities Adaptors
MongooseMongoose
MongoDB ORM
http://mongoosejs.com/
SequelizeSequelize
PostgreSQL
MySQL
MariaDB
SQLite
http://sequelizejs.com/
CRUD PrimitivesCRUD Primitives
create(data)
read(query=)
readOne(query)
readLimit(?query, offset, limit)
update(query, updateValues)
delete(query)
count(query=)
CRUD PrimitivesCRUD 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 ...
Entity HooksEntity Hooks
Middlewarify in action
before
after
last
Entity HooksEntity Hooks
beforebefore
// 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
});
Hooks are FiFoHooks are FiFo
Order MATTERSOrder MATTERS
Hooks areHooks are
MiddlewareMiddleware
Before HooksBefore Hooks
Get the exact same number or arguments
After & Last HooksAfter & Last Hooks
Gets the result plus the original number or arguments
Entity HooksEntity Hooks
AsynchronicityAsynchronicity
entity.create.before(function(data){
return promiseReturningFn(function(result) {
resolve(result + 1);
});
});
Extending EntitiesExtending Entities
adding new methodsadding new methods
Extending EntitiesExtending Entities
Just use the prototypeJust use the prototype
var Entity = require('entity');
var UserEntity = module.exports = Entity.extend();
UserEntity.prototype.report = function(userId) {
return promiseReturningAction(userId);
};
Extending EntitiesExtending 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);
};
Let's combine all upLet's combine all up
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 EntityA Production-ish Entity
Entity Hands OnEntity 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;
};
Entity Hands OnEntity 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);
});
Now let's get crazyNow let's get crazy
EntitiesEntities
++
CrudeCrude
POST /user
GET /user
GET /user/:id
PUT /user/:id
PATCH /user/:id
DELETE /user/:id
/thanpolas/crude
... but not today... but not today
Thank you
(here is where you applaud)
Thanasis Polychronakis
@thanpolas
http://www.slideshare.net/thanpolas
Questions?
Be a critic
Thanasis Polychronakis
@thanpolas
http://www.slideshare.net/thanpolas
Shameless Plug Time
Promo Code
bgwebsummit
From 60€ --> 40€
15/5/2015
@ Thessaloniki Greece
devitconf.org
Questions?
Thanasis Polychronakis
@thanpolas

More Related Content

PPTX
El sustantivo
DOC
Tipos de oraciones. funciones sintácticas. resúmenes
PPTX
El predicat
DOC
Elementos periféricos de la oración (esquema)
PPT
Gramática ESO
PDF
Intro to node.js web apps
PDF
Intro to node.js
PDF
HowTo Freelance
El sustantivo
Tipos de oraciones. funciones sintácticas. resúmenes
El predicat
Elementos periféricos de la oración (esquema)
Gramática ESO
Intro to node.js web apps
Intro to node.js
HowTo Freelance

Viewers also liked (20)

PDF
Entities, the theory
PDF
Business considerations for node.js applications
PPTX
NodeJS - Server Side JS
PDF
Tesi pozzani elena
PDF
The Evaluation of Time Performance in the Emergency Response Center in Kerman...
PPTX
Presentasi Komunitas S3-System Team 007
PDF
It asset management_wp
PDF
Ufeed estrategia de marketing responsable (1)
PDF
Lectura 2 robo en-el-almacen-de-juguetes
PPT
First Euro Case Study
PDF
Nomadic Brochure sje 2013
DOCX
Nuevo documento de microsoft word
PDF
POStudy塾 ~プロダクトオーナーシップをテーマにさまざまな技法の習熟度をさらに上げたい方のための実践塾~ 【2015/11/26(木)】
PDF
Manual de instrucciones Atica
PDF
RTA (Ready to Assemble)
DOC
Mi credo pedagógico. J.D
PDF
Actualización de la Información sobre Disponibilidad de Tuberculina como Medi...
PDF
Stock management in hospital pharmacy using chance constrained model predicti...
PDF
El argentino n# 2611 20 10-111
Entities, the theory
Business considerations for node.js applications
NodeJS - Server Side JS
Tesi pozzani elena
The Evaluation of Time Performance in the Emergency Response Center in Kerman...
Presentasi Komunitas S3-System Team 007
It asset management_wp
Ufeed estrategia de marketing responsable (1)
Lectura 2 robo en-el-almacen-de-juguetes
First Euro Case Study
Nomadic Brochure sje 2013
Nuevo documento de microsoft word
POStudy塾 ~プロダクトオーナーシップをテーマにさまざまな技法の習熟度をさらに上げたい方のための実践塾~ 【2015/11/26(木)】
Manual de instrucciones Atica
RTA (Ready to Assemble)
Mi credo pedagógico. J.D
Actualización de la Información sobre Disponibilidad de Tuberculina como Medi...
Stock management in hospital pharmacy using chance constrained model predicti...
El argentino n# 2611 20 10-111
Ad

Similar to Entities on Node.JS (20)

PPTX
Inversion of Control and Dependency Injection
PPTX
Node.js Patterns for Discerning Developers
PDF
Ekon25 mORMot 2 Server-Side Notifications
PDF
Architecture for scalable Angular applications
PDF
Testable JavaScript: Application Architecture
PPTX
Responsible DI: Ditch the Frameworks
PPTX
Microservices Primer for Monolithic Devs
PDF
Learn backend java script
PDF
Node.js for enterprise - JS Conference
PPTX
Working with LoopBack Models
PDF
2024 DAPUG Conference Arnaud Bouchez From Classes to Interfaces
KEY
How and why i roll my own node.js framework
PPTX
Introduction to Dependency Injection
PDF
JS Fest 2019 Node.js Antipatterns
PDF
Enterprise Level Application Architecture with Web APIs using Entity Framewor...
PDF
Divide and Conquer – Microservices with Node.js
PPTX
Onion Architecture / Clean Architecture
PPTX
Dependency Injection Inversion Of Control And Unity
PDF
Design patterns in javascript
PPTX
Fact, Fiction, and FP
Inversion of Control and Dependency Injection
Node.js Patterns for Discerning Developers
Ekon25 mORMot 2 Server-Side Notifications
Architecture for scalable Angular applications
Testable JavaScript: Application Architecture
Responsible DI: Ditch the Frameworks
Microservices Primer for Monolithic Devs
Learn backend java script
Node.js for enterprise - JS Conference
Working with LoopBack Models
2024 DAPUG Conference Arnaud Bouchez From Classes to Interfaces
How and why i roll my own node.js framework
Introduction to Dependency Injection
JS Fest 2019 Node.js Antipatterns
Enterprise Level Application Architecture with Web APIs using Entity Framewor...
Divide and Conquer – Microservices with Node.js
Onion Architecture / Clean Architecture
Dependency Injection Inversion Of Control And Unity
Design patterns in javascript
Fact, Fiction, and FP
Ad

Recently uploaded (20)

PPTX
Internet of Everything -Basic concepts details
PDF
Connector Corner: Transform Unstructured Documents with Agentic Automation
PDF
Convolutional neural network based encoder-decoder for efficient real-time ob...
PDF
4 layer Arch & Reference Arch of IoT.pdf
PDF
Advancing precision in air quality forecasting through machine learning integ...
DOCX
Basics of Cloud Computing - Cloud Ecosystem
PDF
Rapid Prototyping: A lecture on prototyping techniques for interface design
PDF
NewMind AI Weekly Chronicles – August ’25 Week IV
PPTX
MuleSoft-Compete-Deck for midddleware integrations
PDF
Early detection and classification of bone marrow changes in lumbar vertebrae...
PDF
Planning-an-Audit-A-How-To-Guide-Checklist-WP.pdf
PDF
MENA-ECEONOMIC-CONTEXT-VC MENA-ECEONOMIC
PDF
Transform-Your-Factory-with-AI-Driven-Quality-Engineering.pdf
PDF
Aug23rd - Mulesoft Community Workshop - Hyd, India.pdf
PDF
EIS-Webinar-Regulated-Industries-2025-08.pdf
PPTX
GROUP4NURSINGINFORMATICSREPORT-2 PRESENTATION
PDF
The-Future-of-Automotive-Quality-is-Here-AI-Driven-Engineering.pdf
PDF
Co-training pseudo-labeling for text classification with support vector machi...
PPTX
agenticai-neweraofintelligence-250529192801-1b5e6870.pptx
PDF
giants, standing on the shoulders of - by Daniel Stenberg
Internet of Everything -Basic concepts details
Connector Corner: Transform Unstructured Documents with Agentic Automation
Convolutional neural network based encoder-decoder for efficient real-time ob...
4 layer Arch & Reference Arch of IoT.pdf
Advancing precision in air quality forecasting through machine learning integ...
Basics of Cloud Computing - Cloud Ecosystem
Rapid Prototyping: A lecture on prototyping techniques for interface design
NewMind AI Weekly Chronicles – August ’25 Week IV
MuleSoft-Compete-Deck for midddleware integrations
Early detection and classification of bone marrow changes in lumbar vertebrae...
Planning-an-Audit-A-How-To-Guide-Checklist-WP.pdf
MENA-ECEONOMIC-CONTEXT-VC MENA-ECEONOMIC
Transform-Your-Factory-with-AI-Driven-Quality-Engineering.pdf
Aug23rd - Mulesoft Community Workshop - Hyd, India.pdf
EIS-Webinar-Regulated-Industries-2025-08.pdf
GROUP4NURSINGINFORMATICSREPORT-2 PRESENTATION
The-Future-of-Automotive-Quality-is-Here-AI-Driven-Engineering.pdf
Co-training pseudo-labeling for text classification with support vector machi...
agenticai-neweraofintelligence-250529192801-1b5e6870.pptx
giants, standing on the shoulders of - by Daniel Stenberg

Entities on Node.JS

  • 3. Entities useEntities use CIP ​for Classical Inheritance /thanpolas/cip Bluebird for the 100% Promises API /petkaantonov/bluebird Middlewarify for creating middleware /thanpolas/middlewarify
  • 5. Creating an EntityCreating 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
  • 6. Entities AdaptorsEntities Adaptors MongooseMongoose MongoDB ORM http://mongoosejs.com/ SequelizeSequelize PostgreSQL MySQL MariaDB SQLite http://sequelizejs.com/
  • 7. CRUD PrimitivesCRUD Primitives create(data) read(query=) readOne(query) readLimit(?query, offset, limit) update(query, updateValues) delete(query) count(query=)
  • 8. CRUD PrimitivesCRUD 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 ...
  • 9. Entity HooksEntity Hooks Middlewarify in action before after last
  • 10. Entity HooksEntity Hooks beforebefore // 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 });
  • 11. Hooks are FiFoHooks are FiFo Order MATTERSOrder MATTERS
  • 13. Before HooksBefore Hooks Get the exact same number or arguments After & Last HooksAfter & Last Hooks Gets the result plus the original number or arguments
  • 14. Entity HooksEntity Hooks AsynchronicityAsynchronicity entity.create.before(function(data){ return promiseReturningFn(function(result) { resolve(result + 1); }); });
  • 15. Extending EntitiesExtending Entities adding new methodsadding new methods
  • 16. Extending EntitiesExtending Entities Just use the prototypeJust use the prototype var Entity = require('entity'); var UserEntity = module.exports = Entity.extend(); UserEntity.prototype.report = function(userId) { return promiseReturningAction(userId); };
  • 17. Extending EntitiesExtending 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); };
  • 18. Let's combine all upLet's combine all up
  • 19. 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 EntityA Production-ish Entity
  • 20. Entity Hands OnEntity 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; };
  • 21. Entity Hands OnEntity 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); });
  • 22. Now let's get crazyNow let's get crazy
  • 23. EntitiesEntities ++ CrudeCrude POST /user GET /user GET /user/:id PUT /user/:id PATCH /user/:id DELETE /user/:id /thanpolas/crude
  • 24. ... but not today... but not today
  • 25. Thank you (here is where you applaud) Thanasis Polychronakis @thanpolas http://www.slideshare.net/thanpolas
  • 26. Questions? Be a critic Thanasis Polychronakis @thanpolas http://www.slideshare.net/thanpolas
  • 27. Shameless Plug Time Promo Code bgwebsummit From 60€ --> 40€ 15/5/2015 @ Thessaloniki Greece devitconf.org