{"id":11946,"library":"restify","title":"Restify","description":"Restify is an opinionated Node.js web service framework optimized for building semantically correct RESTful APIs. Unlike more generalized frameworks like Express, Restify focuses purely on API development, offering built-in features for introspection, performance, DTrace support, and robust error handling. It's designed for high-throughput, scalable services and is utilized in large-scale Node.js deployments. The current stable version is 11.2.0, released in August 2023. Major releases, often introducing breaking changes or significant feature updates, occur periodically, with more frequent minor and patch updates addressing bugs and adding smaller features.","status":"active","version":"11.1.0","language":"javascript","source_language":"en","source_url":"git://github.com/restify/node-restify","tags":["javascript","REST","framework","express","DTrace"],"install":[{"cmd":"npm install restify","lang":"bash","label":"npm"},{"cmd":"yarn add restify","lang":"bash","label":"yarn"},{"cmd":"pnpm add restify","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides DTrace support for deep introspection and performance analysis. It's an optional dependency that can be skipped during installation.","package":"dtrace-provider","optional":true},{"reason":"Used for high-performance JSON logging since Restify v9.0.0, replacing Bunyan.","package":"pino","optional":false},{"reason":"A collection of HTTP and REST Error constructors for consistent error handling within Restify applications.","package":"restify-errors","optional":false}],"imports":[{"note":"The `createServer` function is typically accessed as a property of the main `restify` module object, rather than a named export, especially in CJS contexts and older ESM setups. Types for `createServer` are available for TypeScript users.","wrong":"import { createServer } from 'restify'; // createServer is not a named export from the top-level 'restify' module in all versions","symbol":"createServer","correct":"import * as restify from 'restify';\nconst server = restify.createServer({ name: 'MyApi' });"},{"note":"`plugins` is a property of the main `restify` object, containing various middleware functions like `bodyParser`, `queryParser`, etc.","wrong":"import { plugins } from 'restify'; // `plugins` is not a direct named export","symbol":"plugins","correct":"import * as restify from 'restify';\nserver.use(restify.plugins.bodyParser());"},{"note":"These types are crucial for strongly-typed Restify application development in TypeScript, ensuring correct handler signatures.","symbol":"Request, Response, Next (TypeScript types)","correct":"import { Request, Response, Next } from 'restify';"},{"note":"CommonJS `require` remains a widely supported way to import Restify, especially in existing Node.js projects, and is often shown in documentation.","wrong":"import restify from 'restify'; // While technically possible with transpilation, direct ESM usage for the main module might differ in older versions.","symbol":"CommonJS require","correct":"const restify = require('restify');\nconst server = restify.createServer();"}],"quickstart":{"code":"import * as restify from 'restify';\nimport { Request, Response, Next } from 'restify';\n\nconst server = restify.createServer({\n  name: 'MyRestifyApp',\n  version: '1.0.0'\n});\n\n// Apply common plugins\nserver.use(restify.plugins.bodyParser()); // Parses application/json, application/x-www-form-urlencoded, multipart/form-data\nserver.use(restify.plugins.queryParser()); // Parses URL query parameters into req.query\n\n// Define a GET route with a parameter\nserver.get('/hello/:name', (req: Request, res: Response, next: Next) => {\n  res.send({\n    message: `Hello, ${req.params.name}!`, // Access route parameters\n    query: req.query,\n    // body: req.body // Body is not typically present for GET requests\n  });\n  return next(); // Pass control to the next handler in the chain\n});\n\n// Define a POST route to receive data\nserver.post('/data', (req: Request, res: Response, next: Next) => {\n  if (!req.body) {\n    res.send(400, { message: 'Request body is required.' });\n    return next(false); // Stop the chain if an error occurs\n  }\n  res.send(201, {\n    received: req.body, // Access parsed request body\n    status: 'Data processed successfully.'\n  });\n  return next();\n});\n\n// Event listener for unhandled routes (404 Not Found)\nserver.on('NotFound', (req: Request, res: Response, next: Next) => {\n  res.send(404, { message: 'The requested resource was not found.' });\n  return next();\n});\n\n// Global error handler for Restify errors\nserver.on('restifyError', (req: Request, res: Response, err: Error, callback: () => void) => {\n  console.error(`Unhandled Restify error for ${req.url}:`, err);\n  // Optionally modify the error response before sending\n  // err.toJSON = () => ({ error: { name: err.name, message: err.message, code: (err as any).statusCode } });\n  return callback(); // Continue the error handling chain\n});\n\nconst port = process.env.PORT ?? 8080;\n\nserver.listen(port, () => {\n  console.log('%s listening at %s', server.name, server.url); // Server.url is populated after listen()\n});","lang":"typescript","description":"This quickstart sets up a basic Restify server with GET and POST routes, utilizing common plugins for body and query parsing. It includes basic error handling for unmatched routes and general Restify errors, demonstrating fundamental API building blocks."},"warnings":[{"fix":"Review and update any custom middleware or audit plugins that rely on `req.log` being reset or overridden by Restify's internal mechanisms. Ensure your logger is properly initialized before Restify's `.first` chain if you need it to persist.","message":"The `req.log` behavior was modified, no longer overriding existing `req.log` instances if already set during the `.first` middleware chain. The audit plugin also now uses `req.log` directly. This can affect custom logging integrations.","severity":"breaking","affected_versions":">=11.0.0"},{"fix":"Upgrade your Node.js environment to version 18.x or later. Test your application thoroughly against the new Node.js version and Restify 10+.","message":"Support for Node.js 18.x was explicitly added as a breaking change, implying older Node.js versions (e.g., 10.x, 12.x, 14.x, 16.x) may no longer be officially supported or fully compatible. `dtrace-provider` was also bumped, which might affect some environments.","severity":"breaking","affected_versions":">=10.0.0"},{"fix":"Migrate your logging configuration from Bunyan to Pino. Replace `restify-bunyan-logger` with `pino` and its Restify integration (e.g., `restify-pino-logger` if you were using an integration layer). Review logs for any format changes.","message":"Restify replaced `Bunyan` with `Pino` as its default logger. This is a significant change, requiring updates to logging configuration and potentially replacing `restify-bunyan-logger` with `restify-pino-logger` or a similar integration. Also, `RequestCaptureStream` was removed.","severity":"breaking","affected_versions":">=9.0.0"},{"fix":"Instead of `return next('route-name');`, use explicit `res.redirect()` or handle the routing logic within your application, possibly by calling another handler directly or using a custom routing mechanism.","message":"The behavior of `next()` with a string parameter for re-routing was deprecated and subsequently removed. `next('route-name')` will no longer re-route the request.","severity":"breaking","affected_versions":">=9.0.0"},{"fix":"Upgrade your Node.js environment to a supported version (e.g., Node.js 14.x, 16.x for v9, and 18.x+ for v10+).","message":"Support for Node.js 8 was dropped. This means applications running on Node.js 8 or older will no longer be compatible with Restify v9.0.0 and above.","severity":"breaking","affected_versions":">=9.0.0"},{"fix":"Always ensure `return next();` is called at the end of middleware and route handlers, unless you explicitly intend to terminate the response (e.g., `res.send()` without `next()`, or `next(false)`). When passing an error, use `return next(new restify.errors.InternalServerError('message'));` for consistent error handling.","message":"Restify extensively uses `next()` for middleware chaining. Forgetting to call `next()` or calling it incorrectly (e.g., passing a non-Error object in older versions when an error is intended) can halt the request processing or lead to unexpected behavior.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If DTrace is not needed or causing installation problems, install Restify using `npm install restify --no-optional` to skip optional dependencies like `dtrace-provider`.","message":"Restify's DTrace support, while powerful for observability, relies on `dtrace-provider` which might cause issues during installation or compilation on systems without DTrace (e.g., Windows).","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Uninstall `bunyan` and related Restify Bunyan loggers. Install `pino` and integrate it, possibly using `restify-pino-logger` or configuring Pino directly with `restify.createServer({ log: pinoInstance })`.","cause":"Upgrading Restify to v9.0.0 or later without updating logging dependencies. Restify switched from Bunyan to Pino for logging.","error":"Error: Cannot find module 'bunyan'"},{"fix":"Replace `return next('route-name');` with `res.redirect('/new-route-path');` or implement custom dispatch logic. If an error is intended, pass an `Error` object to `next()`.","cause":"Attempting to use `next('route-name')` for re-routing after upgrading to Restify v9.0.0+, where this functionality was removed.","error":"TypeError: next is not a function"},{"fix":"Increase the `maxBodySize` option in your `bodyParser` configuration (e.g., `server.use(restify.plugins.bodyParser({ maxBodySize: 1024 * 1024 * 10 }));` for 10MB). This can also be influenced by server-level configurations like Nginx or cloud load balancers.","cause":"The request body size exceeds the server's configured limit, often due to large file uploads or extensive data payloads with `bodyParser`.","error":"HTTP 413 Request Entity Too Large"},{"fix":"Ensure that every handler either calls `res.send()` to terminate the response or `return next();` (or `return next(err);` for errors) to pass control to the next middleware in the chain. Pay close attention to asynchronous operations within handlers.","cause":"A handler or middleware function completed its execution (e.g., an `async/await` operation finished) without calling `res.send()` or `next()`, leading Restify to believe the request was unhandled.","error":"{ \"code\": \"InternalServer\", \"message\": \"reached the end of the handler chain without writing a response!\" }"}],"ecosystem":"npm"}