Building MVC Node.js Apps with Couchbase Server: Couchbase Connect 2015

Post on 26-Jul-2015

435 views 4 download

Transcript of Building MVC Node.js Apps with Couchbase Server: Couchbase Connect 2015

BUILDING MVC NODEJS APPLICATIONS WITH COUCHBASE AND OTTOMAN

Todd Greenstein, Couchbase

ArchitectureLet’s design an application

©2015 Couchbase Inc. 3

Concept – What are we doing?

New Motorcycle Dealership Application - Requirements• Inventory Control System• Integrate Easily with Existing Systems• Rapid Development and Maintainability is

essential• Work Less, Ride More

©2015 Couchbase Inc. 4

Concept - Components

System Components• Node.js + Express• Ottoman• Couchbase Node.js SDK• Couchbase

©2015 Couchbase Inc. 5

Concept – Ottoman, what’s that?

Ottoman is:• Couchbase’s ODM for Node.js• Work natively in objects• Rapidly prototype and define your data model and objects• Letting someone else handle the heavy lifting, and the mundane:

• Supports many existing datatypes• Supports custom datatypes, including custom verifiers• Allows for embedding objects natively or references• Provides support for generic finds• Supports multiple strategies for Indexing• Allows for Data Model Mobility• Control and enforce the data model from within the

application.• Awesome.

©2015 Couchbase Inc. 6

Concept – Back to our Application Architecture

Service Based Architecture:• REST API for all interaction with system• Decoupled Front End Framework• Simplified Object Model

Code WalkthroughLets build an application

©2015 Couchbase Inc. 8

Code – Bootstrap The Application: package.json

{ "name": "bikeShop-cb", "version": "0.0.1", "description": "Sample Application for Couchbase, Node.js, Ottoman, and Express", "homepage": "http://www.couchbase.com", "repository": { "type": "git", "url": "git://github.com/ToddGreenstein/bikeShop-cb" }, "license": "Apache2", "author": { "name": "Todd Greenstein", "email": "todd@couchbase.com" }, "dependencies": { "express": "*", "couchbase": "*", "body-parser": "*”, "ottoman":"git+https://github.com/couchbaselabs/node-ottoman.git#refactor" }, "contributors": [ { "name": "Todd Greenstein", "email": "todd@couchbase.com" } ]}

dependencies": { "express": "*", "couchbase": "*", "body-parser": "*", "ottoman":"git+https://github.com/couchbaselabs/node-ottoman.git#refactor”}

©2015 Couchbase Inc. 9

Code – Create the Data Model: Couchbase Instance

// Instantiate Couchbase and Ottomanvar couchbase=require('couchbase');var ottoman=require('ottoman');

// Build my cluster object and open a new clustervar myCluster = new couchbase.Cluster('localhost:8091');var myBucket = myCluster.openBucket('bikeShop');ottoman.bucket=myBucket;

// Build my "schema" from my model filesrequire('./model/employee');require('./model/customer');require('./model/bike');

// Build the necessary indexes to functionottoman.ensureIndices(function(){});

©2015 Couchbase Inc. 10

Code – Create the Data Model: Bike Model

IDE Presentation

©2015 Couchbase Inc. 11

Code – Create the Data Model: Bike Model- Dependencies

var db = require('./../db.js');var ottoman = require('ottoman');

var BikeMdl = ottoman.model('Bike', { stockID: {type:'string', auto:'uuid', readonly:true}, acquiredON: {type: 'Date', default:function(){return new Date()}}, vin:'string', make: 'string', model: 'string', year: 'integer', description: 'string', condition: 'string', price: 'number', status: 'string', mileage: 'integer', photos:[{type:'string'}],

©2015 Couchbase Inc. 12

Code – Create the Data Model: Bike Model - Declare

var db = require('./../db.js');var ottoman = require('ottoman');

var BikeMdl = ottoman.model('Bike', { stockID: {type:'string', auto:'uuid', readonly:true}, acquiredON: {type: 'Date', default:function(){return new Date()}}, vin:'string', make: 'string', model: 'string', year: 'integer', description: 'string', condition: 'string', price: 'number', status: 'string', mileage: 'integer', photos:[{type:'string'}],

©2015 Couchbase Inc. 13

Code – Create the Data Model: Bike Model -Types

var db = require('./../db.js');var ottoman = require('ottoman');

var BikeMdl = ottoman.model('Bike', { stockID: {type:'string', auto:'uuid', readonly:true}, acquiredON: {type: 'Date', default:function(){return new Date()}}, vin:'string', make: 'string', model: 'string', year: 'integer', description: 'string', condition: 'string', price: 'number', status: 'string', mileage: 'integer', photos:[{type:'string'}],

©2015 Couchbase Inc. 14

Code – Create the Data Model: Bike Model – Types

var db = require('./../db.js');var ottoman = require('ottoman');

var BikeMdl = ottoman.model('Bike', { stockID: {type:'string', auto:'uuid', readonly:true}, acquiredON: {type: 'Date', default:function(){return new Date()}}, vin:'string', make: 'string', model: 'string', year: 'integer', description: 'string', condition: 'string', price: 'number', status: 'string', mileage: 'integer', photos:[{type:'string'}],

©2015 Couchbase Inc. 15

Code – Create the Data Model: Bike Model - References

rides: [{ customer:{ref:'Customer'}, employee:{ref:'Employee'}, date:'Date', miles:'number'}],sale:{ customer:{ref:'Customer'}, employee:{ref:'Employee'}, amount:'number', warranty:'number', date:{type: 'Date', default:function(){return new Date()}}}},

©2015 Couchbase Inc. 16

Code – Create the Data Model: Bike Model - References

rides: [{ customer:{ref:'Customer'}, employee:{ref:'Employee'}, date:'Date', miles:'number'}],sale:{ customer:{ref:'Customer'}, employee:{ref:'Employee'}, amount:'number', warranty:'number', date:{type: 'Date', default:function(){return new Date()}}}},

©2015 Couchbase Inc. 17

Code – Create the Data Model: Bike Model - References

rides: [{ customer:{ref:'Customer'}, employee:{ref:'Employee'}, date:'Date', miles:'number'}],sale:{ customer:{ref:'Customer'}, employee:{ref:'Employee'}, amount:'number', warranty:'number', date:{type: 'Date', default:function(){return new Date()}}}},

©2015 Couchbase Inc. 18

Code – Create the Data Model: Bike Model - Indexes

index: { findByStockID: { type: 'refdoc', by: 'stockID' }, findByMake:{ by: 'make' }, findByYear:{ by:'year' }, findByCondition:{ by:'condition' }, findByStatus:{ by:'status' }, findByVin:{ type:'refdoc', by:'vin' }

©2015 Couchbase Inc. 19

Code – Create the Data Model: Bike Model - Indexes

index: { findByStockID: { type: 'refdoc', by: 'stockID' }, findByMake:{ by: 'make' }, findByYear:{ by:'year' }, findByCondition:{ by:'condition' }, findByStatus:{ by:'status' }, findByVin:{ type:'refdoc', by:'vin' }

©2015 Couchbase Inc. 20

Code – Create the Data Model: Bike Model - Indexes

index: { findByStockID: { type: 'refdoc', by: 'stockID' }, findByMake:{ by: 'make' }, findByYear:{ by:'year' }, findByCondition:{ by:'condition' }, findByStatus:{ by:'status' }, findByVin:{ type:'refdoc', by:'vin' }

©2015 Couchbase Inc. 21

Code – Create the Data Model: Bike Model - Create

BikeMdl.createAndSaveLongform = function(vin,year,make,model,description,condition,mileage,price,done){

var bike=new BikeMdl();

bike.vin=vin; bike.year=year; bike.make=make; bike.model=model bike.description=description; bike.condition=condition; bike.mileage=mileage; bike.price=price;

bike.save(function(err){ if(err){ done(err,null); return; } done(null,bike) });}

module.exports=BikeMdl;

BikeMdl.createAndSave = function (vin, year, make, model,

description, condition, mileage, price, done) { this.create({ vin: vin, year: year, make: make, model: model,

description: description, condition: condition,

mileage: mileage, price: price }, done);}

Easy Shorthand for Constructing and Saving Object Instances!!

©2015 Couchbase Inc. 22

Code – Create The Routes – Generic Find

Easy Shorthand for Query Methods onYour Objects!!

//// ▶▶ BIKE generic find ◀◀ ////app.get('/api/bike/find',function(req,res) { bike.find(req.query, function (err, done) { if (err) { res.status = 400; res.send(err); return; } res.status = 202; res.send(done); });});

Generic Finds:• Use N1QL• Use 2I

(Secondary Indexes)

• Are ridiculously flexible (more on this in a moment)

©2015 Couchbase Inc. 23

Code – Create The Routes – Find One//// ▶▶ BIKE find one◀◀ ////app.get('/api/bike/findOne/:id',function(req,res) { bike.findByStockID(req.params.id,function(err,stock){ if (err) { res.status = 400; res.send(err); return; } if(stock && stock.length>0){ res.status = 202; res.send(stock); return; }else{ bike.findByVin(req.params.id,function(err,vin){ if (err) { res.status = 400; res.send(err); return; } if(vin && vin.length>0){ res.status = 202; res.send(vin); return; }else{ res.status = 202; res.send("{not found}"); return; } }); } });});

©2015 Couchbase Inc. 24

Code – Create The Routes – Find One//// ▶▶ BIKE find one◀◀ ////app.get('/api/bike/findOne/:id',function(req,res) { bike.findByStockID(req.params.id,function(err,stock){ if (err) { res.status = 400; res.send(err); return; } if(stock && stock.length>0){ res.status = 202; res.send(stock); return; }else{ bike.findByVin(req.params.id,function(err,vin){ if (err) { res.status = 400; res.send(err); return; } if(vin && vin.length>0){ res.status = 202; res.send(vin); return; }else{ res.status = 202; res.send("{not found}"); return; } }); } });});

//// ▶▶ BIKE find one◀◀ ////app.get('/api/bike/findOne/:id',function(req,res) { bike.findByStockID(req.params.id,function(err,stock){ if (err) { res.status = 400; res.send(err); return; } if(stock && stock.length>0){ res.status = 202; res.send(stock); return;

Defined In the “Bike” Model

©2015 Couchbase Inc. 25

Summary – What Can CB + Ottoman Do For You?

• Couchbase’s ODM for Node.js• Work natively in objects• Rapidly prototype and define your data model and objects• Letting someone else handle the heavy lifting, and the mundane:

• Supports many existing datatypes - even custom validators• Allows for embedding objects natively or references• Provides support for generic finds• Supports multiple strategies for Indexing• Query Methods are build dynamically• Allows for Data Model Mobility• Control and enforce the data model from within the application• Referential integrity is maintained by the application• A Powerful Pattern Language starts to emerge in your application design

DemoLets see it work

©2015 Couchbase Inc. 27

Demo – What we’ll doRun the application, and simulate traffic from a front end application using CURL commands:

• Add a new Bike into the database• Show different methods for retrieving that bike

• Add a new Customer• Show different methods for retrieving that customer including embedded fields

• Add another new customer• Add an Employee• Create some test rides for the bike we created above, and the customers.

• Show how embedded references are created• Find and load embedded references so we can see the flexibility of the data model

More Infowww.couchbase.comwww.ottomanjs.com