Created
February 10, 2012 17:24
-
-
Save pixelhandler/1791080 to your computer and use it in GitHub Desktop.
Develop a RESTful API Using Node.js With Express and Mongoose - See: http://pixelhandler.com/blog/2012/02/09/develop-a-restful-api-using-node-js-with-express-and-mongoose/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var application_root = __dirname, | |
express = require("express"), | |
path = require("path"), | |
mongoose = require('mongoose'); | |
var app = express.createServer(); | |
// database | |
mongoose.connect('mongodb://localhost/ecomm_database'); | |
// config | |
app.configure(function () { | |
app.use(express.bodyParser()); | |
app.use(express.methodOverride()); | |
app.use(app.router); | |
app.use(express.static(path.join(application_root, "public"))); | |
app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); | |
}); | |
var Schema = mongoose.Schema; //Schema.ObjectId | |
// Schemas | |
var Sizes = new Schema({ | |
size: { type: String, required: true }, | |
available: { type: Number, required: true, min: 0, max: 1000 }, | |
sku: { | |
type: String, | |
required: true, | |
validate: [/[a-zA-Z0-9]/, 'Product sku should only have letters and numbers'] | |
}, | |
price: { type: Number, required: true, min: 0 } | |
}); | |
var Images = new Schema({ | |
kind: { | |
type: String, | |
enum: ['thumbnail', 'catalog', 'detail', 'zoom'], | |
required: true | |
}, | |
url: { type: String, required: true } | |
}); | |
var Variants = new Schema({ | |
color: String, | |
images: [Images], | |
sizes: [Sizes] | |
}); | |
var Categories = new Schema({ | |
name: String | |
}); | |
var Catalogs = new Schema({ | |
name: String | |
}); | |
// Product Model | |
var Product = new Schema({ | |
title: { type: String, required: true }, | |
description: { type: String, required: true }, | |
style: { type: String, unique: true }, | |
images: [Images], | |
categories: [Categories], | |
catalogs: [Catalogs], | |
variants: [Variants], | |
modified: { type: Date, default: Date.now } | |
}); | |
// validation | |
Product.path('title').validate(function (v) { | |
console.log("validate title"); | |
console.log(v); | |
return v.length > 10 && v.length < 70; | |
}); | |
Product.path('style').validate(function (v) { | |
console.log("validate style"); | |
console.log(v); | |
return v.length < 40; | |
}, 'Product style attribute is should be less than 40 characters'); | |
Product.path('description').validate(function (v) { | |
console.log("validate description"); | |
console.log(v); | |
return v.length > 10; | |
}, 'Product description should be more than 10 characters'); | |
var ProductModel = mongoose.model('Product', Product); | |
/* Product Document | |
[ | |
{ | |
"title": "My Awesome T-shirt", | |
"description": "All about the details. Of course it's black.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1234", | |
"variants": [ | |
{ | |
"color": "Black", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/thumbnail.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1234/black.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 10, | |
"sku": "CAT-1234-Blk-S", | |
"price": 99.99 | |
}, | |
{ | |
"size": "M", | |
"available": 7, | |
"sku": "CAT-1234-Blk-M", | |
"price": 109.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
} | |
] | |
*/ | |
// REST api | |
app.get('/api', function (req, res) { | |
res.send('Ecomm API is running'); | |
}); | |
// POST to CREATE | |
app.post('/api/products', function (req, res) { | |
var product; | |
console.log("POST: "); | |
console.log(req.body); | |
product = new ProductModel({ | |
title: req.body.title, | |
description: req.body.description, | |
style: req.body.style, | |
images: req.body.images, | |
categories: req.body.categories, | |
catalogs: req.body.catalogs, | |
variants: req.body.variants | |
}); | |
product.save(function (err) { | |
if (!err) { | |
return console.log("created"); | |
} else { | |
return console.log(err); | |
} | |
}); | |
return res.send(product); | |
}); | |
// PUT to UPDATE | |
// Bulk update | |
app.put('/api/products', function (req, res) { | |
var i, len = 0; | |
console.log("is Array req.body.products"); | |
console.log(Array.isArray(req.body.products)); | |
console.log("PUT: (products)"); | |
console.log(req.body.products); | |
if (Array.isArray(req.body.products)) { | |
len = req.body.products.length; | |
} | |
for (i = 0; i < len; i++) { | |
console.log("UPDATE product by id:"); | |
for (var id in req.body.products[i]) { | |
console.log(id); | |
} | |
ProductModel.update({ "_id": id }, req.body.products[i][id], function (err, numAffected) { | |
if (err) { | |
console.log("Error on update"); | |
console.log(err); | |
} else { | |
console.log("updated num: " + numAffected); | |
} | |
}); | |
} | |
return res.send(req.body.products); | |
}); | |
// Single update | |
app.put('/api/products/:id', function (req, res) { | |
return ProductModel.findById(req.params.id, function (err, product) { | |
product.title = req.body.title; | |
product.description = req.body.description; | |
product.style = req.body.style; | |
product.images = req.body.images; | |
product.categories = req.body.categories; | |
product.catalogs = req.body.catalogs; | |
product.variants = req.body.variants; | |
return product.save(function (err) { | |
if (!err) { | |
console.log("updated"); | |
} else { | |
console.log(err); | |
} | |
return res.send(product); | |
}); | |
}); | |
}); | |
// GET to READ | |
// List products | |
app.get('/api/products', function (req, res) { | |
return ProductModel.find(function (err, products) { | |
if (!err) { | |
return res.send(products); | |
} else { | |
return console.log(err); | |
} | |
}); | |
}); | |
// Single product | |
app.get('/api/products/:id', function (req, res) { | |
return ProductModel.findById(req.params.id, function (err, product) { | |
if (!err) { | |
return res.send(product); | |
} else { | |
return console.log(err); | |
} | |
}); | |
}); | |
// DELETE to DESTROY | |
// Bulk destroy all products | |
app.delete('/api/products', function (req, res) { | |
ProductModel.remove(function (err) { | |
if (!err) { | |
console.log("removed"); | |
return res.send(''); | |
} else { | |
console.log(err); | |
} | |
}); | |
}); | |
// remove a single product | |
app.delete('/api/products/:id', function (req, res) { | |
return ProductModel.findById(req.params.id, function (err, product) { | |
return product.remove(function (err) { | |
if (!err) { | |
console.log("removed"); | |
return res.send(''); | |
} else { | |
console.log(err); | |
} | |
}); | |
}); | |
}); | |
// launch server | |
app.listen(4242); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jQuery.get("/api/products", function(data, textStatus, jqXHR) { | |
var ids = []; | |
console.log("product ids:"); | |
$.each(data, function () { | |
ids.push(this._id); | |
}); | |
console.dir(ids); | |
// 0: "4f3cc9189760db17520000e6" | |
// 1: "4f3cc91f9760db17520000f0" | |
// 2: "4f3cc9279760db17520000fb" | |
// 3: "4f3cc92f9760db1752000105" | |
}); | |
/* | |
boilerplate for bulk update, replace null with product object | |
jQuery.ajax({ | |
url: "/api/products", | |
type: "PUT", | |
data: { | |
"products": [ | |
{ | |
"4f3cc9189760db17520000e6" : null | |
}, | |
{ | |
"4f3cc91f9760db17520000f0" : null | |
}, | |
{ | |
"4f3cc9279760db17520000fb" : null | |
}, | |
{ | |
"4f3cc92f9760db1752000105" : null | |
}, | |
] | |
}, | |
success: function(data, textStatus, jqXHR) { | |
console.log("PUT resposne:"); | |
console.dir(data); | |
console.log(textStatus); | |
console.dir(jqXHR); | |
} | |
}); | |
*/ | |
jQuery.ajax({ | |
url: "/api/products", | |
type: "PUT", | |
data: { | |
"products": [ | |
{ | |
"4f3cc9189760db17520000e6" : { | |
"title": "My Awesome T-shirt - UPDATED", | |
"description": "All about the details. Of course it's black.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1234", | |
"variants": [ | |
{ | |
"color": "Black", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/thumbnail.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1234/black.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 10, | |
"sku": "CAT-1234-Blk-S", | |
"price": 29.99 | |
}, | |
{ | |
"size": "M", | |
"available": 7, | |
"sku": "CAT-1234-Blk-M", | |
"price": 19.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
} | |
}, | |
{ | |
"4f3cc91f9760db17520000f0" : { | |
"title": "My Other T-shirt - UPDATED", | |
"description": "All about the details. Almost as nice as my Awesome T-Shirt", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1235/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1235", | |
"variants": [ | |
{ | |
"color": "Blue", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1235/thumbnail.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1235/blue.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 8, | |
"sku": "CAT-1235-Blu-S", | |
"price": 19.99 | |
}, | |
{ | |
"size": "M", | |
"available": 9, | |
"sku": "CAT-1235-Blu-M", | |
"price": 29.99 | |
}, | |
{ | |
"size": "L", | |
"available": 12, | |
"sku": "CAT-1235-Blu-L", | |
"price": 39.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
} | |
}, | |
{ | |
"4f3cc9279760db17520000fb" : { | |
"title": "My Gray T-shirt - UPDATED", | |
"description": "All about the details. Not too much color here, just gray.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1236/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1236", | |
"variants": [ | |
{ | |
"color": "Gray", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1236/thumbnail.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1236/gray.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 25, | |
"sku": "CAT-1236-Gra-S", | |
"price": 14.99 | |
}, | |
{ | |
"size": "L", | |
"available": 16, | |
"sku": "CAT-1236-Gra-L", | |
"price": 24.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
} | |
}, | |
{ | |
"4f3cc92f9760db1752000105" : { | |
"title": "My Red Hot T-shirt - UPDATED", | |
"description": "All about the details. Red Hot T, get 'em while they're hot.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1237/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1237", | |
"variants": [ | |
{ | |
"color": "Red", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1237/thumbnails/red.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1237/red.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 25, | |
"sku": "CAT-1237-Red-S", | |
"price": 19.99 | |
}, | |
{ | |
"size": "L", | |
"available": 16, | |
"sku": "CAT-1237-Red-L", | |
"price": 29.99 | |
} | |
] | |
}, | |
{ | |
"color": "White", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1237/thumbnails/white.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1237/white.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "M", | |
"available": 7, | |
"sku": "CAT-1237-Whi-M", | |
"price": 9.99 | |
}, | |
{ | |
"size": "L", | |
"available": 8, | |
"sku": "CAT-1237-Whi-L", | |
"price": 21.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
} | |
} | |
] | |
}, | |
success: function(data, textStatus, jqXHR) { | |
console.log("PUT resposne:"); | |
console.dir(data); | |
console.log(textStatus); | |
console.dir(jqXHR); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jQuery.post("/api/products", { | |
"title": "My Awesome T-shirt", | |
"description": "All about the details. Of course it's black.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1234", | |
"variants": [ | |
{ | |
"color": "Black", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/thumbnail.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1234/black.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 10, | |
"sku": "CAT-1234-Blk-S", | |
"price": 99.99 | |
}, | |
{ | |
"size": "M", | |
"available": 7, | |
"sku": "CAT-1234-Blk-M", | |
"price": 109.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
}, function(data, textStatus, jqXHR) { | |
console.log("Post resposne:"); console.dir(data); console.log(textStatus); console.dir(jqXHR); | |
}); | |
// --- | |
jQuery.post("/api/products", { | |
"title": "My Other T-shirt", | |
"description": "All about the details. Almost as nice as my Awesome T-Shirt", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1235/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1235", | |
"variants": [ | |
{ | |
"color": "Blue", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1235/thumbnail.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1235/blue.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 8, | |
"sku": "CAT-1235-Blu-S", | |
"price": 79.99 | |
}, | |
{ | |
"size": "M", | |
"available": 9, | |
"sku": "CAT-1235-Blu-M", | |
"price": 89.99 | |
}, | |
{ | |
"size": "L", | |
"available": 12, | |
"sku": "CAT-1235-Blu-L", | |
"price": 99.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
}, function(data, textStatus, jqXHR) { | |
console.log("Post resposne:"); console.dir(data); console.log(textStatus); console.dir(jqXHR); | |
}); | |
// --- | |
jQuery.post("/api/products", { | |
"title": "My Gray T-shirt", | |
"description": "All about the details. Not too much color here, just gray.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1236/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1236", | |
"variants": [ | |
{ | |
"color": "Gray", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1236/thumbnail.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1236/gray.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 25, | |
"sku": "CAT-1236-Gra-S", | |
"price": 19.99 | |
}, | |
{ | |
"size": "L", | |
"available": 16, | |
"sku": "CAT-1236-Gra-L", | |
"price": 29.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
}, function(data, textStatus, jqXHR) { | |
console.log("Post resposne:"); console.dir(data); console.log(textStatus); console.dir(jqXHR); | |
}); | |
// --- | |
jQuery.post("/api/products", { | |
"title": "My Red Hot T-shirt", | |
"description": "All about the details. Red Hot T, get 'em while they're hot.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1237/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1237", | |
"variants": [ | |
{ | |
"color": "Red", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1237/thumbnails/red.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1237/red.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 25, | |
"sku": "CAT-1237-Red-S", | |
"price": 19.99 | |
}, | |
{ | |
"size": "L", | |
"available": 16, | |
"sku": "CAT-1237-Red-L", | |
"price": 29.99 | |
} | |
] | |
}, | |
{ | |
"color": "White", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1237/thumbnails/white.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1237/white.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "M", | |
"available": 7, | |
"sku": "CAT-1237-Whi-M", | |
"price": 18.99 | |
}, | |
{ | |
"size": "L", | |
"available": 8, | |
"sku": "CAT-1237-Whi-L", | |
"price": 27.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
}, function(data, textStatus, jqXHR) { | |
console.log("Post resposne:"); console.dir(data); console.log(textStatus); console.dir(jqXHR); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Frontend - Backbone.js integration with API</title> | |
</head> | |
<body> | |
<section id="api"> | |
<h1>Nouns...</h1> | |
<p> | |
/products<br> | |
/products/:id | |
</p> | |
</section> | |
<section id="container"> | |
<h1>Product List</h1> | |
<p> | |
To render the product list use the route '#list' following the url for this page | |
</p> | |
</section> <!-- /container --> | |
<script type="text/template" id="product-template"> | |
<p>{{title}}</p> | |
<p>{{description}}</p> | |
</script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.1/underscore-min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.0/backbone-min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.3.0/mustache.min.js"></script> | |
<script> | |
PX = window.PX || {}; | |
// model | |
PX.Product = Backbone.Model.extend({ | |
defaults: { | |
title: null, | |
description: null | |
} | |
}); | |
// collection | |
(function () { | |
var ProductList; | |
ProductList = Backbone.Collection.extend({ | |
model: PX.Product, | |
url: '/api/products', | |
initialize: function () { | |
this.fetch({ | |
success: this.fetchSuccess, | |
error: this.fetchError | |
}); | |
this.deferred = new $.Deferred(); | |
}, | |
deferred: Function.constructor.prototype, | |
fetchSuccess: function (collection, response) { | |
collection.deferred.resolve(); | |
}, | |
fetchError: function (collection, response) { | |
throw new Error("Products fetch did get collection from API"); | |
} | |
}); | |
PX.products = new ProductList(); | |
ProductList = null; | |
}()); | |
PX.ProductView = Backbone.View.extend({ | |
tagName: "li", | |
className: "product", | |
initialize: function (options) { | |
this.template = $('#product-template').html(); | |
}, | |
render: function () { | |
var markup = Mustache.to_html(this.template, this.model.toJSON()); | |
this.$el.html(markup).attr('id',this.model.get('_id')); | |
return this; | |
} | |
}); | |
PX.ProductListView = Backbone.View.extend({ | |
tagName: "ul", | |
className: "products", | |
// initialize: function (options) { | |
// this.container = options.container; | |
// }, | |
render: function () { | |
var i, len = this.collection.length; | |
for (i=0; i < len; i++) { | |
this.renderItem(this.collection.models[i]); | |
}; | |
$(this.container).find(this.className).remove(); | |
this.$el.appendTo(this.options.container); | |
return this; | |
}, | |
renderItem: function (model) { | |
var item = new PX.ProductView({ | |
"model": model | |
}); | |
item.render().$el.appendTo(this.$el); | |
} | |
}); | |
// application | |
PX.App = Backbone.Router.extend({ | |
routes: { | |
"/": "listProducts", | |
"list": "listProducts" | |
}, | |
//initialize: function (options) {}, | |
listProducts: function () { | |
var productsList = new PX.ProductListView({ | |
"container": $('#container'), | |
"collection": PX.products | |
}); | |
PX.products.deferred.done(function () { | |
productsList.render(); | |
}); | |
} | |
}); | |
// bootstrap | |
PX.app = new PX.App(); | |
Backbone.history.start(); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>API index</title> | |
</head> | |
<body> | |
<section> | |
<h1>Nouns...</h1> | |
<p> | |
/products<br> | |
/products/:id | |
</p> | |
</section> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// jQuery snippets used in the console to use the REST api created with app.js | |
// CREATE | |
jQuery.post("/api/products", { | |
"title": "My Awesome T-shirt", | |
"description": "All about the details. Of course it's black.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1234", | |
"variants": [ | |
{ | |
"color": "Black", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/thumbnail.jpg" | |
}, | |
{ | |
"kind": "catalog", | |
"url": "images/products/1234/black.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "S", | |
"available": 10, | |
"sku": "CAT-1234-Blk-S", | |
"price": 99.99 | |
}, | |
{ | |
"size": "M", | |
"available": 7, | |
"sku": "CAT-1234-Blk-M", | |
"price": 109.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
}, function(data, textStatus, jqXHR) { | |
console.log("Post resposne:"); console.dir(data); console.log(textStatus); console.dir(jqXHR); | |
}); | |
// generated a product document with automatically assigned ID, e.g. 4f34734d21289c1c28000007 | |
// READ | |
jQuery.get("/api/products/", function(data, textStatus, jqXHR) { | |
console.log("Post resposne:"); | |
console.dir(data); | |
console.log(textStatus); | |
console.dir(jqXHR); | |
}); | |
jQuery.get("/api/products/4f34734d21289c1c28000007", function(data, textStatus, jqXHR) { | |
console.log("Post resposne:"); | |
console.dir(data); | |
console.log(textStatus); | |
console.dir(jqXHR); | |
}); | |
// UPDATE | |
jQuery.ajax({ | |
url: "/api/products/4f34734d21289c1c28000007", | |
type: "PUT", | |
data: { | |
"title": "My Awesome T-shirt", | |
"description": "All about the details. Of course it's black, and longsleeve.", | |
"images": [ | |
{ | |
"kind": "thumbnail", | |
"url": "images/products/1234/main.jpg" | |
} | |
], | |
"categories": [ | |
{ "name": "Clothes" }, | |
{ "name": "Shirts" } | |
], | |
"style": "1234", | |
"variants": [ | |
{ | |
"color": "Black", | |
"images": [ | |
{ | |
"kind": "zoom", | |
"url": "images/products/1234/zoom.jpg" | |
} | |
], | |
"sizes": [ | |
{ | |
"size": "L", | |
"available": 77, | |
"sku": "CAT-1234-Blk-L", | |
"price": 99.99 | |
} | |
] | |
} | |
], | |
"catalogs": [ | |
{ "name": "Apparel" } | |
] | |
}, | |
success: function(data, textStatus, jqXHR) { | |
console.log("PUT resposne:"); | |
console.dir(data); | |
console.log(textStatus); | |
console.dir(jqXHR); | |
} | |
}); | |
// Delete | |
jQuery.ajax({url: "/api/products/4f34734d21289c1c28000007", type: "DELETE", success: function(data, textStatus, jqXHR) { console.dir(data); }}); |
great job , thanks
I am really new with server-side JS, it will help me to link to a JSON format feed to my Schema collections and
display a nice website.
Thanks nice job indeed !
maybe you should add https://www.npmjs.org/package/connect-nocache to prevent caching
I have one question. Web page exist in my web root dir. Web service use 80 port. Nodejs RESTful servcer use 8080. I got ' No Access-Control-Allo-Origin ....'. If data is defined as 'jsonp', i got unexpected token.
very nice thanks
Nicely done, thank you
Nice nontrivial example, thanks!
good job
good job
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nicely done. Only thing I might suggest is changing the structure of your variants to an array of objects similar to:
[{" colour":"black", "size":"L", "skuid":"222222", "price":"99.99",...},..]
Again, great job