LoopBack is a highly-extensible, open-source Node.js framework that enables developers to create dynamic end-to-end REST APIs with minimal coding.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
LoopBack's Express-compatible middleware system provides request processing capabilities with LoopBack-specific middleware for REST APIs, authentication, error handling, and request lifecycle management through configurable middleware phases.
Essential middleware for REST API functionality and request processing.
/**
* REST API middleware for exposing models as REST endpoints
* @param {Object} options - REST middleware options
* @param {string} options.restApiRoot - REST API base path (default: '/api')
* @param {boolean} options.handleErrors - Handle errors automatically
* @param {boolean} options.handleUnknownPaths - Handle unknown paths
* @returns {Function} Express middleware function
*/
loopback.rest(options);
/**
* Status endpoint middleware for health checks
* @param {Object} options - Status middleware options
* @param {string} options.endpoint - Status endpoint path (default: '/status')
* @returns {Function} Express middleware function
*/
loopback.status(options);Usage Example:
const app = loopback();
// Enable REST API
app.use(loopback.rest({
restApiRoot: '/api',
handleErrors: true
}));
// Add status endpoint
app.use(loopback.status({
endpoint: '/health'
}));
// Start server
app.listen(3000);
// Now available: GET /api/books, POST /api/books, etc.
// Health check: GET /healthToken-based authentication middleware for securing API endpoints.
/**
* Token authentication middleware
* @param {Object} options - Token middleware options
* @param {boolean} options.enableDoublecheck - Enable double-check mode
* @param {boolean} options.overwriteExistingToken - Overwrite existing token
* @param {string[]} options.searchDefaultTokenKeys - Default token search keys
* @param {Object} options.cookies - Cookie options
* @param {Object} options.headers - Header options
* @param {Object} options.params - Parameter options
* @returns {Function} Express middleware function
*/
loopback.token(options);
/**
* Context middleware for maintaining request context
* @deprecated Removed in LoopBack 3.0
* @param {Object} options - Context options
* @returns {Function} Express middleware function
*/
loopback.context(options);Usage Example:
const app = loopback();
// Enable request context - DEPRECATED (removed in v3.0)
// app.use(loopback.context());
// Enable token authentication
app.use(loopback.token({
searchDefaultTokenKeys: ['access_token', 'authorization'],
cookies: ['access_token'],
headers: ['authorization', 'x-access-token'],
params: ['access_token']
}));
// Protected routes will now require valid access token
app.use('/api', loopback.rest());Comprehensive error handling and formatting for API responses.
/**
* Error handler middleware for formatting and logging errors
* @deprecated Use 'strong-error-handler' package instead
* @param {Object} options - Error handler options
* @param {boolean} options.debug - Enable debug mode
* @param {boolean} options.log - Enable error logging
* @param {Function} options.defaultType - Default error type
* @param {Object} options.rootProperty - Root property for error response
* @returns {Function} Express error middleware function
*/
loopback.errorHandler(options);
/**
* 404 Not Found handler for unmatched routes
* @param {Object} options - URL not found options
* @returns {Function} Express middleware function
*/
loopback.urlNotFound(options);Usage Example:
const app = loopback();
// Application routes
app.use('/api', loopback.rest());
// 404 handler (before error handler)
app.use(loopback.urlNotFound());
// Error handler (should be last) - DEPRECATED
// Use 'strong-error-handler' package instead:
// const errorHandler = require('strong-error-handler');
// app.use(errorHandler({ debug: process.env.NODE_ENV !== 'production' }));
app.use(loopback.errorHandler({
debug: process.env.NODE_ENV !== 'production',
log: true
}));Static file serving with LoopBack-specific enhancements.
/**
* Static file serving middleware (Express static with LoopBack enhancements)
* @param {string} root - Root directory for static files
* @param {Object} options - Static middleware options
* @param {boolean} options.dotfiles - How to treat dotfiles
* @param {string} options.etag - ETag generation
* @param {string[]} options.extensions - File extensions
* @param {boolean} options.fallthrough - Continue to next middleware on 404
* @param {boolean} options.immutable - Set immutable cache header
* @param {string|number} options.maxAge - Cache max age
* @returns {Function} Express middleware function
*/
loopback.static(root, options);
/**
* Favicon middleware for serving favicon files
* @param {string|Buffer} icon - Path to favicon or favicon buffer
* @param {Object} options - Favicon options
* @param {string|number} options.maxAge - Cache max age
* @returns {Function} Express middleware function
*/
loopback.favicon(icon, options);Usage Example:
const path = require('path');
const app = loopback();
// Serve favicon
app.use(loopback.favicon(loopback.faviconFile));
// Serve static files
app.use('/public', loopback.static(path.join(__dirname, 'public'), {
maxAge: '1d',
etag: true
}));
// Default favicon from LoopBack
app.use(loopback.favicon(loopback.faviconFile));Configure middleware execution phases for fine-grained control over request processing.
/**
* Define middleware phases for the application
* @param {string|string[]} nameOrArray - Phase name or array of phase names
*/
app.defineMiddlewarePhases(nameOrArray);
/**
* Register middleware in a specific phase
* @param {string} phase - Middleware phase name
* @param {string|string[]|RegExp} paths - Optional paths to apply middleware to
* @param {Function} handler - Middleware function
*/
app.middleware(phase, paths, handler);
/**
* Register middleware from configuration object
* @param {Function} factory - Middleware factory function
* @param {Object} config - Middleware configuration
* @param {string} config.phase - Phase to register in
* @param {string[]} config.paths - Paths to apply to
* @param {Object} config.params - Parameters for factory function
*/
app.middlewareFromConfig(factory, config);Built-in Middleware Phases (in order):
initial - First phase for initialization and request setupsession - Session handling and user session managementauth - Authentication and authorization checksparse - Request body parsing and data transformationroutes - Application routes and REST API endpointsfiles - Static file serving and asset deliveryfinal - Error handling and response finalizationUsage Example:
const app = loopback();
// Define custom middleware phases
app.defineMiddlewarePhases(['validation', 'transform', 'logging']);
// Register middleware in specific phases
app.middleware('initial', (req, res, next) => {
console.log('Request started:', req.method, req.url);
next();
});
app.middleware('auth', '/api', loopback.token());
app.middleware('validation', '/api', (req, res, next) => {
// Custom validation logic
if (!req.body) {
return res.status(400).json({ error: 'Request body required' });
}
next();
});
app.middleware('routes', loopback.rest());
app.middleware('final', loopback.errorHandler());Utilities for configuring remote method exposure.
/**
* Configure remote method on a function
* @param {Function} fn - Function to make remote
* @param {Object} options - Remote method options
* @param {Object[]} options.accepts - Input parameters
* @param {Object} options.returns - Return value description
* @param {Object} options.http - HTTP configuration
* @param {string} options.http.verb - HTTP verb (get, post, put, delete)
* @param {string} options.http.path - HTTP path
* @param {number} options.http.status - HTTP status code
*/
loopback.remoteMethod(fn, options);Usage Example:
// Define a custom remote method
function customOperation(input, callback) {
// Custom logic here
callback(null, { result: input.toUpperCase() });
}
// Configure as remote method
loopback.remoteMethod(customOperation, {
accepts: [
{ arg: 'input', type: 'string', required: true }
],
returns: [
{ arg: 'result', type: 'object' }
],
http: {
verb: 'post',
path: '/custom-operation'
}
});
// Add to model
const MyModel = loopback.createModel('MyModel');
MyModel.customOperation = customOperation;Template rendering utilities for server-side rendering.
/**
* Create template renderer function
* @param {string} file - Path to template file
* @returns {Function} Template rendering function
*/
loopback.template(file);Usage Example:
const path = require('path');
// Create template renderer
const renderWelcome = loopback.template(
path.join(__dirname, 'views', 'welcome.ejs')
);
// Use in route
app.get('/welcome', (req, res) => {
const html = renderWelcome({
name: req.query.name || 'Guest',
title: 'Welcome to LoopBack'
});
res.send(html);
});Type definitions for middleware configuration objects.
/**
* Middleware configuration object
*/
interface MiddlewareConfig {
phase: string; // Middleware phase name
paths?: string | string[]; // Paths to apply middleware to
params?: Object; // Parameters for middleware factory
enabled?: boolean; // Whether middleware is enabled
optional?: boolean; // Whether middleware is optional
}
/**
* Remote method configuration
*/
interface RemoteMethodOptions {
accepts?: Array<{ // Input parameters
arg: string; // Parameter name
type: string; // Parameter type
required?: boolean; // Whether parameter is required
default?: any; // Default value
description?: string; // Parameter description
http?: Object; // HTTP-specific options
}>;
returns?: Array<{ // Return values
arg: string; // Return value name
type: string; // Return value type
description?: string; // Return value description
root?: boolean; // Whether this is the root return value
}>;
http?: { // HTTP configuration
verb: string; // HTTP verb
path?: string; // HTTP path
status?: number; // HTTP status code
errorStatus?: number; // Error status code
};
description?: string; // Method description
notes?: string; // Additional notes
documented?: boolean; // Whether to include in documentation
accessType?: string; // Access type for ACL
}
/**
* Error handler options
*/
interface ErrorHandlerOptions {
debug?: boolean; // Enable debug mode
log?: boolean; // Enable error logging
safeFields?: string[]; // Safe fields to include in error response
defaultType?: string; // Default error type
negotiateContentType?: boolean; // Negotiate content type
rootProperty?: string; // Root property for error response
}
/**
* Token middleware options
*/
interface TokenOptions {
enableDoublecheck?: boolean; // Enable double-check mode
overwriteExistingToken?: boolean; // Overwrite existing token
searchDefaultTokenKeys?: string[]; // Default token search keys
cookies?: string | string[]; // Cookie names to search
headers?: string | string[]; // Header names to search
params?: string | string[]; // Parameter names to search
bearerTokenBase64Encoded?: boolean; // Whether bearer token is base64 encoded
}