Presentamos Camo: un ODM ES6 basado en clases para bases de datos similares a Mongo

    驴Qu茅 es Camo?

    Camuflaje es un ODM ES6 con modelos basados 鈥嬧媏n clases. Algunas de sus caracter铆sticas principales son: declaraci贸n de esquema completamente simple, herencia de esquema intuitiva y soporte para m煤ltiples backends de base de datos.

    Un modelo de Camo simple podr铆a verse as铆:

    var Document = require('camo').Document;
    
    class Car extends Document {
    	constructor() {
    		super();
    
    		this.make = String;
    		this.miles = Number;
    		this.numWheels = {
    			type: Number;
    			default: 4
    		};
    	}
    }
    

    Para instalar, solo use:

    npm install camo --save
    
    AND
    
    npm install nedb --save
    OR
    npm install mongodb --save
    

    驴Por qu茅 otro ODM?

    Por mucho que quisiera que me gustara Mongoose, como parec铆a que todos los dem谩s, no pod铆a aceptarlo. Puede haber sido porque todav铆a era nuevo en JavaScript, y no hab铆a abrazado el aspecto de programaci贸n funcional tanto como deber铆a haberlo hecho, pero me qued茅 decepcionado con la forma en que se declararon los modelos y la falta de herencia de esquemas (o al menos sus torpeza).

    Viniendo de un fondo de Java, me gustan mucho las clases. As铆 que dise帽ar modelos sin poder usar clases o herencia f谩cilmente fue dif铆cil para m铆. Como ES6 tiene soporte tradicional de clases y herencia, me sorprendi贸 ver que ning煤n ODM de Node.js se basaba en clases.

    Por 煤ltimo, me gust贸 c贸mo en SQL se puede cambiar f谩cilmente entre bases de datos peque帽as y port谩tiles como SQLite para el desarrollo y bases de datos m谩s grandes y escalables como PostgreSQL para la producci贸n. Viendo como NeDB llena muy bien ese vac铆o para MongoDB, quer铆a un ODM que me permitiera cambiar f谩cilmente entre estas bases de datos.

    Caracter铆sticas

    Clases

    Como se mencion贸 anteriormente, Camo gira en torno a las clases ES6 para crear modelos. Cada modelo debe extender el Document clase, la EmbeddedDocument clase, u otro modelo. Los esquemas se declaran en los constructores, donde puede especificar el tipo de datos, valores predeterminados, opciones y otros validadores.

    Se pueden usar virtuales, m茅todos y est谩tica para manipular y recuperar los datos del modelo, como una clase normal no persistente.

    var Document = require('camo').Document;
    
    class Manufacturer extends Document {
    	constructor() {
    		super();
    
    		this.name = String;
    	}
    }
    
    class Car extends Document {
    	constructor() {
    		super();
    
    		this.make = Manufacturer;
    		this.model = String;
    		this.year = {
    			type: Number,
    			min: 1900,
    			max: 2015
    		};
    		this.miles = {
    			type: Number,
    			min: 0
    		};
    		this.numWheels = {
    			type: Number;
    			default: 4
    		};
    	}
    
    	get isUnderWarranty() {
    		return this.miles < 50000;
    	}
    
    	milesPerYear() {
    		return this.miles / (new Date().getFullYear() - this.year)
    	};
    }
    

    Documentos incrustados

    Una de las principales ventajas de usar MongoDB es su estructura de datos anidada, y deber铆a poder aprovecharla f谩cilmente en su ODM. Camo tiene soporte integrado para documentos incorporado, por lo que puede tratar los datos de los documentos anidados como lo har铆a con un documento normal.

    var Document = require('camo').Document;
    var EmbeddedDocument = require('camo').EmbeddedDocument;
    
    class Warranty extends EmbeddedDocument {
    	constructor() {
    		super();
    
    		this.miles = Number;
    		this.years = Number;
    		this.isUnlimitedMiles = Boolean;
    	}
    
    	isCovered(car) {
    		var thisYear = new Date().getFullYear();
    		return ((car.miles <= this.miles) || this.isUnlimitedMiles) &&
    			((thisYear - car.year) <= this.years)
    	};
    }
    
    class Manufacturer extends Document {
    	constructor() {
    		super();
    
    		this.name = String;
    
    		this.basicWarranty = Warranty;
    		this.powertrainWarranty = Warranty;
    		this.corrosionWarranty = Warranty;
    	}
    }
    

    Soporte de m煤ltiples bases de datos

    No todos los proyectos requieren una base de datos enorme con replicaci贸n, equilibrio de carga y soporte para millones de lecturas / escrituras por segundo, que es exactamente la raz贸n por la que era importante para Camo admitir m煤ltiples backends de bases de datos, como NeDB.

    La mayor铆a de los proyectos comienzan siendo peque帽os y eventualmente se convierten en productos m谩s grandes y populares que requieren bases de datos m谩s r谩pidas y s贸lidas. Con NeDB, obtiene un subconjunto de los comandos API de MongoDB m谩s utilizados sin la necesidad de configurar la base de datos completa. Es como tener el equivalente de SQLite, pero para Mongo. Para cambiar entre las bases de datos, simplemente proporcione una cadena de conexi贸n diferente.

    var connect = require('camo').connect;
    
    var uri;
    var neUri = 'nedb://memory';
    var mongoUri = 'mongodb://localhost/car-app';
    
    uri = neUri;
    if (process.env.NODE_ENV === 'production') {
    	uri = mongoUri;
    }
    
    connect(uri).then(function(db) {
    	// Ready to use Camo!
    });
    

    A partir de la versi贸n 0.5.5, Camo es compatible con MongoDB y NeDB. Estamos planeando agregar soporte para m谩s bases de datos similares a Mongo, incluyendo LokiJSy TaffyDB. Con NeDB y las adiciones de LokiJS y TaffyDB, tambi茅n puede usar Camo en el navegador.

    Herencia

    Podr铆a decirse que una de las mejores caracter铆sticas de Camo es la herencia de esquemas. Simplemente use la herencia de clases ES6 para extender un esquema.

    var Document = require('camo').Document;
    
    class Vehicle extends Document {
    	constructor() {
    		super();
    
    		this.make = String;
    		this.model = String;
    		this.year = Number;
    		this.miles = Number;
    	}
    }
    
    class Car extends Vehicle {
    	constructor() {
    		super();
    
    		this.numberOfDoors = String;
    	}
    }
    

    Las subclases pueden anular o ampliar cualquier esquema, virtual, m茅todo o est谩tica, lo que da como resultado un c贸digo m谩s legible y m谩s simple.

    驴Camo est谩 listo para la producci贸n?

    Si bien Camo ya tiene bastantes funciones y solo algunos errores conocidos, todav铆a es un trabajo en progreso. Aqu铆 hay una breve lista de las caracter铆sticas principales que a煤n queremos agregar al proyecto antes de declarar v1.0:

    • Devolver un Query objeto de findOne / buscar / eliminar / etc
    • Agregue soporte para omitir / limitar a las consultas
    • Agregue una opci贸n para completar solo las referencias especificadas
    • Agregue soporte para LokiJS y TaffyDB

    Dicho esto, Camo ya se est谩 utilizando en el c贸digo de producci贸n en Polimetr铆a (un SaaS que proporciona m茅tricas para Stripe). El c贸digo base para Polymetrics se cre贸 originalmente en Mongoose, pero luego se reemplaz贸 con Camo sin ning煤n problema. Las pruebas y el desarrollo son mucho m谩s f谩ciles ahora que podemos cambiar f谩cilmente entre bases de datos.

    Camo tambi茅n facilit贸 mucho el dise帽o de los modelos para Polymetrics. Gran parte de los datos que necesitamos descargar y guardar de Stripe tienen los mismos campos (como fechas, metadatos, etc.), por lo que extender un esquema com煤n nos permiti贸 escribir menos c贸digo, adem谩s de permitirnos solo tener que cambiar la base. esquema en lugar de tener que realizar el mismo cambio en muchos archivos.

    Conclusi贸n

    Dir铆gete al npm o Github p谩ginas y ver el proyecto. El README es actualmente la mejor fuente de documentaci贸n., as铆 que si falta algo, h谩gamelo saber.

    Como siempre, cualquier sugerencia, pregunta, comentario o solicitud de extracci贸n es bienvenida. No dude en ponerse en contacto conmigo a trav茅s de Gorjeo, Github, o correo electr贸nico.

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *