Skip to content

Instantly share code, notes, and snippets.

@LeCoupa
Last active April 27, 2025 12:52
Show Gist options
  • Select an option

  • Save LeCoupa/0664e885fd74152d1f90 to your computer and use it in GitHub Desktop.

Select an option

Save LeCoupa/0664e885fd74152d1f90 to your computer and use it in GitHub Desktop.
// Restify CheatSheet.
// More about the API: http://mcavage.me/node-restify/
// Install restify with npm install restify
// 1.1. Creating a Server.
// http://mcavage.me/node-restify/#Creating-a-Server
var restify = require('restify');
// A restify server has the following properties on it: name, version, log, acceptable, url.
// and the following methods: address(), listen(port, [host], [callback]), close(), pre(), use().
var server = restify.createServer({
certificate: null, // If you want to create an HTTPS server, pass in the PEM-encoded certificate and key
key: null, // If you want to create an HTTPS server, pass in the PEM-encoded certificate and key
formatters: null, // Custom response formatters for res.send()
log: null, // You can optionally pass in a bunyan instance; not required
name: 'node-api', // By default, this will be set in the Server response header, default is restify
spdy: null, // Any options accepted by node-spdy
version: '1.1.3', // A default version to set for all routes
handleUpgrades: false // Hook the upgrade event from the node HTTP server, pushing Connection: Upgrade requests through the regular request handling chain; defaults to false
});
server.listen(3000, function () {
console.log('%s listening at %s', server.name, server.url);
});
// 1.2. Server API.
// http://mcavage.me/node-restify/#Server-API
// Restify servers emit all the events from the node http.Server and has several other events you want to listen on.
// http://nodejs.org/docs/latest/api/http.html#http_class_http_server
server.on('NotFound', function (request, response, cb) {}); // When a client request is sent for a URL that does not exist, restify will emit this event. Note that restify checks for listeners on this event, and if there are none, responds with a default 404 handler. It is expected that if you listen for this event, you respond to the client.
server.on('MethodNotAllowed', function (request, response, cb) {}); // When a client request is sent for a URL that does exist, but you have not registered a route for that HTTP verb, restify will emit this event. Note that restify checks for listeners on this event, and if there are none, responds with a default 405 handler. It is expected that if you listen for this event, you respond to the client.
server.on('VersionNotAllowed', function (request, response, cb) {}); // When a client request is sent for a route that exists, but does not match the version(s) on those routes, restify will emit this event. Note that restify checks for listeners on this event, and if there are none, responds with a default 400 handler. It is expected that if you listen for this event, you respond to the client.
server.on('UnsupportedMediaType', function (request, response, cb) {}); // When a client request is sent for a route that exist, but has a content-type mismatch, restify will emit this event. Note that restify checks for listeners on this event, and if there are none, responds with a default 415 handler. It is expected that if you listen for this event, you respond to the client.
server.on('after', function (request, response, route, error) {}); // Emitted after a route has finished all the handlers you registered. You can use this to write audit logs, etc. The route parameter will be the Route object that ran.
server.on('uncaughtException', function (request, response, route, error) {}); // Emitted when some handler throws an uncaughtException somewhere in the chain. The default behavior is to just call res.send(error), and let the built-ins in restify handle transforming, but you can override to whatever you want here.
// 2. Use Common Handlers.
// Note that restify runs handlers in the order they are registered on a server.
// http://mcavage.me/node-restify/#Common-handlers:-server.use()
server.use(restify.fullResponse()); // sets up all of the default headers for the system
server.use(restify.bodyParser()); // remaps the body content of a request to the req.params variable, allowing both GET and POST/PUT routes to use the same interface
// 3. Routing.
// http://mcavage.me/node-restify/#Routing
// You are responsible for calling next() in order to run the next handler in the chain.
function send(req, res, next) {
res.send('hello ' + req.params.name);
return next();
}
function rm(req, res, next) {
res.send(204);
return next('foo2');
}
server.post('/hello', send);
server.put('/hello', send);
server.get('/hello/:name', send);
server.head('/hello/:name', send);
server.del('hello/:name', rm);
// You can also pass in a RegExp object and access the capture group with req.params (which will not be interpreted in any way).
server.get(/^\/([a-zA-Z0-9_\.~-]+)\/(.*)/, function(req, res, next) {
console.log(req.params[0]);
console.log(req.params[1]);
res.send(200);
return next();
});
// You can pass in a string name to next(), and restify will lookup that route, and assuming it exists will run the chain from where you left off.
server.get({
name: 'foo2',
path: '/foo/:id'
}, function (req, res, next) {
assert.equal(count, 1);
res.send(200);
next();
});
// Routes can also accept more than one handler function.
server.get(
'/foo/:id',
function(req, res, next) {
console.log('Authenticate');
return next();
},
function(req, res, next) {
res.send(200);
return next();
}
);
// Most REST APIs tend to need versioning, and restify ships with support for semver versioning in an Accept-Version header, the same way you specify NPM version dependencies
var PATH = '/hello/:name';
server.get({path: PATH, version: '1.1.3'}, sendV1);
server.get({path: PATH, version: '2.0.0'}, sendV2);
// You can default the versions on routes by passing in a version field at server creation time. Lastly, you can support multiple versions in the API by using an array:
server.get({path: PATH, version: ['2.0.0', '2.1.0']}, sendV2);
// 4. Content Negotiation.
// http://mcavage.me/node-restify/#Content-Negotiation
// If you're using res.send() restify will automatically select the content-type to respond with, by finding the first registered formatter defined.
var server = restify.createServer({
formatters: {
'application/foo': function formatFoo(req, res, body) {
if (body instanceof Error)
return body.stack;
if (Buffer.isBuffer(body))
return body.toString('base64');
return util.inspect(body);
}
}
});
// Note that if a content-type can't be negotiated, the default is application/octet-stream. Of course, you can always explicitly set the content-type.
res.setHeader('content-type', 'application/foo');
res.send({hello: 'world'});
// You don't have to use any of this magic, as a restify response object has all the "raw" methods of a node ServerResponse on it as well.
var body = 'hello world';
res.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain'
});
res.write(body);
res.end();
// 5. Error Handling.
// http://mcavage.me/node-restify/#Error-handling
// If you invoke res.send() with an error that has a statusCode attribute, that will be used, otherwise a default of 500 will be used
// You can also shorthand this in a route by doing:
server.get('/hello/:name', function(req, res, next) {
return database.get(req.params.name, function(err, user) {
if (err)
return next(err);
res.send(user);
return next();
});
});
// Alternatively, restify 2.1 supports a next.ifError API
server.get('/hello/:name', function(req, res, next) {
return database.get(req.params.name, function(err, user) {
next.ifError(err);
res.send(user);
next();
});
});
// Trigger an HTTP error
// The built-in restify errors are: RestError, BadDigestError, BadMethodError, InternalError, InvalidArgumentError, InvalidContentError, InvalidCredentialsError, InvalidHeaderError, InvalidVersionError, MissingParameterError,
// NotAuthorizedError, RequestExpiredError, RequestThrottledError, ResourceNotFoundError, WrongAcceptError
// The core thing to note about an HttpError is that it has a numeric code (statusCode) and a body. The statusCode will automatically set the HTTP response status code, and the body attribute by default will be the message.
server.get('/hello/:name', function(req, res, next) {
return next(new restify.ConflictError("I just don't like you"));
});
server.get('/hello/:name', function(req, res, next) {
return next(new restify.errors.ConflictError("I just don't like you"));
});
server.get('/hello/:name', function(req, res, next) {
return next(new restify.InvalidArgumentError("I just don't like you"));
});
// You can always add your own by subclassing restify.RestError like:
var restify = require('restify');
var util = require('util');
function MyError(message) {
restify.RestError.call(this, {
restCode: 'MyError',
statusCode: 418,
message: message,
constructorOpt: MyError
});
this.name = 'MyError';
};
util.inherits(MyError, restify.RestError);
// 6. Socket.io.
// To use socket.io with restify, just treat your restify server as if it were a "raw" node server.
// http://mcavage.me/node-restify/#Socket.IO
var server = restify.createServer();
var io = socketio.listen(server);
server.get('/', function indexHTML(req, res, next) {
fs.readFile(__dirname + '/index.html', function (err, data) {
if (err) {
next(err);
return;
}
res.setHeader('Content-Type', 'text/html');
res.writeHead(200);
res.end(data);
next();
});
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
server.listen(8080, function () {
console.log('socket.io server listening at %s', server.url);
});
@roblav96
Copy link

this is some great content here! thanks man!

@marcellodesales
Copy link

This is SUPER userful!! Thank you!

@subtubes-io
Copy link

Nice!

@gld1982ltd
Copy link

Sweet! Thanks for the awesome share!

@onesien
Copy link

onesien commented Jan 26, 2016

Thank you so much for this!!!!!

@goldenflower
Copy link

Great items for developers. Many thanks.

@spartman
Copy link

Brilliant! Thanks

@merlindorin
Copy link

\o/

@blueRegen
Copy link

I am getting an error -

C:\Ash\NJS\node_api\app.js:7
server.use(restify.acceptParser(server.acceptable));
^

TypeError: restify.acceptParser is not a function
at Object. (C:\Ash\NJS\node_api\app.js:7:20)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3

what might be the problem? - please help.

`var restify = require('restify');
var server = restify.createServer();

var users = {};
var max_user_id = 0;

server.use(restify.acceptParser(server.acceptable));
server.use(restify.bodyParser());

server.get("/", function(req, res, next) {
    res.setHeader('content-type', 'application/json');
    res.writeHead(200);
    res.end(JSON.stringify(users));
    return next();
});

server.post("/user", function(req, res, next) {
    var user = req.params;
    max_user_id++;
    user.id = max_user_id;
    users[user.id] = user;
    res.setHeader('content-type', 'application/json');
    res.writeHead(200);
    res.end(JSON.stringify(user));
    return next();
});

server.listen(8080, function() {
  console.log('%s listening at %s', server.name, server.url);
});`

@chriddyp
Copy link

this is awesome ✨

@alexcusack
Copy link

this is great! thanks for putting it together

@muhsinshodiq
Copy link

this is really helpful, thx πŸ‘

@letsjustfixit
Copy link

Thanks very much its a very helpful collection :) πŸ‘ πŸ₯‡

@budda
Copy link

budda commented Jul 23, 2017

Can you include an example of routing with optional placeholder params, please?

@imran-uk
Copy link

restify.bodyParser()); is from v5.x server.use(restify.plugins.bodyParser());

Sauce: restify/node-restify#1394

@lfreneda
Copy link

Awesome piece of work <3

@nonlogos
Copy link

very cool! thank you!

@kunle
Copy link

kunle commented May 10, 2019

Thanks for sharing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment