npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

restcat

v0.1.3

Published

A RESTFUL api with Express.js and Mongoose

Downloads

4

Readme

node-restcat

This library provides a REST interface based on mongoose and express.js, which is inspired by Tastypie of django.

Getting started

First of all, please make sure your express and mongoose have been properly installed. In your shell, install with npm:

npm install restcat

Configure mongoose schemas in your code:

//models/index.js
//------------------------------

var mongoose = require('mongoose');

var userSchema = new mongoose.Schema({
	username: String,
	password: String
});
exports.user = mongoose.model('User', userSchema);

var blogSchema = new mongoose.Schema({
	title: String,
	content: String,
	created: { type: Date, default: Date.now },
	isExist: { type: Boolean, default: true },
	authorId: mongoose.Schema.Types.ObjectId
});
exports.blog = mongoose.model('Blog', blogSchema);

Create a file called cattery.js(whatever you want to name) from root directory, for configuration of restful api.

//cattery.js
//------------------------------

var restcat = require('restcat');
var model = require('./model');

//configure restcat, for url called
restcat.configure({namespace:'/restful/api'});

var userCattery = restcat.create({
	catteryName:'userlist', //configure specified url
	querySet: model.user.find({}), //querySet with no filter
	model:model.user //model
});

var blogCattery = restcat.create({
	catteryName: 'bloglist',
	querySet: model.blog.find({isExist:true}), //querySet with existed blogs
	model: model.blog,
});

exports.blog = blogCattery;
exports.user = userCattery;

After deploying model and restcat, invoke in app.js.

//app.js
//------------------------------

var http = require('http');
var express = require('express');
var mongoose = require('mongoose');

//bring in cattery.js
var cattery = require('./cattery');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');

var app = express();
app.configure(function(){
	app.use(express.bodyParser());
	app.use(express.methodOverride());
	
	//register router
	app.use(cattery.blog.register());
	app.use(cattery.user.register());
});

http.createServer(app).listen(3000, function() {
	console.log("Express server listening on port 3000");
});

Then you can excute the following queries:

GET http://localhost:3000/restful/api/userlist/
GET http://localhost:3000/restful/api/bloglist/            #for getting all blogs
GET http://localhost:3000/restful/api/bloglist/:id
POST http://localhost:3000/restful/api/bloglist/           #for creating blog
POST http://localhost:3000/restful/api/bloglist/:id        #for updating blog

GET http://localhost:3000/restful/api/bloglist/?title=Restcat      #for getting blogs with specified title, and this query set will base on the one you defined in cattery.js
GET http://localhost:3000/restful/api/bloglist/?limit=3     #for getting first three blogs
GET http://localhost:3000/restful/api/bloglist/?limit=3&offset=3     #for getting three blogs beginning at 4 (offset means skip)

Configuration Options

namespace (Required)

Avoids conflit with other routes


restcat.configure({namespace:'/restful/api'});

Cattery Options

catteryName (Required)

Generates the url referring to certain model based on cattery name.

querySet (Required)

The initiated query set you want to be queried.

example:

querySet: collection.find({}) //find all the data

/* OR */
querySet: collection.find({outdate: false}) //find the data which isn't outdated

model (Required)

The collection or table referring to this cattery.

foreignKeys (Optional)

Provides relative infomation for foreignkeys, and the result will show the foreign tables recusively

example:
foreignKeys: [
	{
		fieldName: 'user',  //the attribute name you like to display in the result data
		keyName: 'authorId', //the foreign key field
		cattery: userCattery  //the cattery referring to the foreign table or collection, which must be defined before this cattery
	}
]

It can be more than one foreign key in one collection or table, so this option would be an array.

authentication (Optional)

Add authentication for accessing to the data this cattery referring to.

generate authentication instance
// cattery.js
// assuming you require restcat module
//-----------------------------------------
var oAuth = restcat.authGenerator('authentication');  //default name and pass are 'admin' for authentication, and authentication would be checked only when the request method isn't 'GET'

/* OR */
var oAuth = restcat.authGenerator('authentication', function(username, password){

	// code goes here...
	// check user and password through database
	// return value must be BOOL (if username and password match database, return true. Otherwise, return false) 

});
example
// cattery.js
// assuming you require restcat module
//-----------------------------------------

var users = {
	root: 'root', //name: pass
	foo: 'bar' 
}

// define authentication instance
var oAuth = restcat.authGenerator('authentication', function(user, pass){
	if(users[user] && users[user] == pass)
		return true;

	return false;
});


var userCattery = restcat.create({
	catteryName:'userlist', //configure specified url
	querySet: model.user.find({}), //querySet with no filter
	model:model.user, //model
	authentication: oAuth
});
overwrite authenticate method

The authentication for each cattery or each route can be varied.

example
// cattery.js
// assuming you require restcat module
//-----------------------------------------

var basicAuth = require('basic-auth'); // npm install basic-auth, for parsing header authorization

var users = {
	root: 'root', //name: pass
	foo: 'bar' 
}

// define authentication instance
var blogOAuth = restcat.authGenerator('authentication', function(user, pass){
	if(users[user] && users[user] == pass)
		return true;

	return false;
});

//redefine the authenticate middleware
blogOAuth.authenticate = function(req, res, next) {
	
	//always allows for GET
	if (req.method == "GET") return next();

	function unauthorized(res) {
		res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
		return res.send(401);
	};

	var user = basicAuth(req);
	if (!user || !user.name || !user.pass) {
		return unauthorized(res);
	};

	// authCheck is the property of auth instance, which is the parameter of authGenerator
	if (this.authCheck(user.name,user.pass)) { 
		return next();
	} else {
		return unauthorized(res);
	};
}

var blogCattery = restcat.create({
	catteryName: 'bloglist',
	querySet: model.entity.find({isExist:true}), //find exist
	model: model.entity,
	authentication:blogOAuth
});

authorization (Optional)

Add authorization for accessing to the data this cattery referring to, which is kind of the same as authentication

generate authorization instance
// cattery.js
// assuming you require restcat module
//-----------------------------------------
var generalAnthorization = restcat.authGenerator('authorization');  //default always pass

/* Customize your anthorization method */
generalAnthorization.anthorize = function(req, res, next) {
	
	// code goes here...
	// middleware
}
example
// cattery.js
// assuming you require restcat module
//-----------------------------------------

var basicAuth = require('basic-auth'); // npm install basic-auth, for parsing header authorization

var users = {
	root: 'root', //name: pass
	foo: 'bar' 
}

// define authentication instance
var blogOAuth = restcat.authGenerator('authentication', function(user, pass){
	if(users[user] && users[user] == pass)
		return true;

	return false;
});
var blogAuthorization = restcat.authGenerator('authorization');

//customize authorization method
blogAuthorization.authorize = function(req, res, next) {
	if (!req.session.user_id) {
		res.send('You are not authorized to view this page');
	} else {
		next();
	}
}


var blogCattery = restcat.create({
	catteryName: 'bloglist',
	querySet: model.entity.find({isExist:true}), //find exist
	model: model.entity,
	authentication:blogOAuth,
	authorization:blogAuthorization
});

Data Operation

Meta