CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rest

RESTful HTTP client library with composable interceptor architecture for Node.js and browsers

76

1.28x
Overview
Eval results
Files

interceptors.mddocs/

Interceptors

Interceptors provide a composable middleware pattern for extending rest.js client functionality. They can transform requests, responses, or both, allowing you to add features like authentication, error handling, caching, and content negotiation.

Capabilities

Base Interceptor System

Core interceptor creation and composition functionality.

const interceptor = require('rest/interceptor');

/**
 * Create a custom interceptor
 * @param {object} handlers - Interceptor handler functions
 * @param {function} [handlers.init] - One-time initialization
 * @param {function} [handlers.request] - Request transformation
 * @param {function} [handlers.response] - Response transformation
 * @param {function} [handlers.success] - Success response handler
 * @param {function} [handlers.error] - Error response handler
 * @param {Client} [handlers.client] - Default client to use
 * @returns {Interceptor} Interceptor function
 */
function interceptor(handlers)

/**
 * Complex request object for advanced interceptor scenarios
 * @param {object} properties - Request properties
 * @param {Request} properties.request - The request object
 * @param {Promise} [properties.abort] - Abort promise
 * @param {Client} [properties.client] - Override client
 * @param {any} [properties.response] - Short-circuit response
 */
function ComplexRequest(properties)

Usage Example:

const interceptor = require('rest/interceptor');

const customInterceptor = interceptor({
  request: function(request, config, meta) {
    // Transform request
    request.headers = request.headers || {};
    request.headers['X-Custom-Header'] = 'my-value';
    return request;
  },
  response: function(response, config, meta) {
    // Transform response
    console.log('Response received:', response.status.code);
    return response;
  }
});

const client = rest.wrap(customInterceptor);

Authentication Interceptors

Basic Authentication

HTTP Basic Authentication support.

const basicAuth = require('rest/interceptor/basicAuth');

/**
 * Basic Auth interceptor configuration
 * @param {object} config - Authentication config
 * @param {string} config.username - Username
 * @param {string} config.password - Password
 */

Usage Example:

const basicAuth = require('rest/interceptor/basicAuth');

const client = rest.wrap(basicAuth, {
  username: 'myuser',
  password: 'mypassword'
});

OAuth Support

OAuth authentication interceptor.

const oAuth = require('rest/interceptor/oAuth');

/**
 * OAuth interceptor for request signing
 */

Request/Response Transformation

MIME Type Conversion

Automatic serialization/deserialization based on Content-Type.

const mime = require('rest/interceptor/mime');

/**
 * MIME interceptor configuration
 * @param {object} config - MIME config
 * @param {string} [config.mime='text/plain'] - Default request MIME type
 * @param {string} [config.accept] - Accept header value
 * @param {Registry} [config.registry] - Custom MIME registry
 * @param {boolean} [config.permissive=false] - Allow unknown MIME types
 * @param {Client} [config.client] - Client for converter use
 */

Entity Interceptor (Deprecated)

Extract response entity directly.

const entity = require('rest/interceptor/entity');

// Note: This interceptor is deprecated. Use response.entity() instead.

Error Handling

Error Code Interceptor

Reject responses based on HTTP status codes.

const errorCode = require('rest/interceptor/errorCode');

/**
 * Error code interceptor configuration
 * @param {object} config - Error config
 * @param {number} [config.code=400] - Minimum error status code
 */

Usage Example:

const errorCode = require('rest/interceptor/errorCode');

const client = rest.wrap(errorCode, { code: 500 });
// Only reject on 500+ status codes

Retry Interceptor

Automatically retry failed requests.

const retry = require('rest/interceptor/retry');

/**
 * Retry interceptor for handling transient failures
 */

Timeout Interceptor

Add request timeout handling.

const timeout = require('rest/interceptor/timeout');

/**
 * Timeout interceptor configuration
 * @param {object} config - Timeout config
 * @param {number} config.timeout - Timeout in milliseconds
 */

URL and Path Manipulation

Path Prefix Interceptor

Add a prefix to all request paths.

const pathPrefix = require('rest/interceptor/pathPrefix');

/**
 * Path prefix interceptor configuration
 * @param {object} config - Prefix config
 * @param {string} config.prefix - Path prefix to add
 */

Usage Example:

const pathPrefix = require('rest/interceptor/pathPrefix');

const client = rest.wrap(pathPrefix, { prefix: '/api/v1' });
// Requests to '/users' become '/api/v1/users'

Template Interceptor

URI template expansion using RFC 6570.

const template = require('rest/interceptor/template');

/**
 * URI template interceptor for parameter expansion
 */

Parameters Interceptor (Deprecated)

Simple parameter replacement in URLs.

const params = require('rest/interceptor/params');

// Note: This interceptor is deprecated. Use template interceptor instead.

Request Configuration

Default Request Interceptor

Provide default values for request properties.

const defaultRequest = require('rest/interceptor/defaultRequest');

/**
 * Default request interceptor configuration
 * @param {object} config - Default request properties
 */

Usage Example:

const defaultRequest = require('rest/interceptor/defaultRequest');

const client = rest.wrap(defaultRequest, {
  headers: { 'User-Agent': 'MyApp/1.0' },
  method: 'POST'
});

Hypermedia and Location Handling

HATEOAS Interceptor

Hypermedia support for following links and parsing Link headers according to RFC 5988.

const hateoas = require('rest/interceptor/hateoas');

/**
 * HATEOAS interceptor configuration
 * @param {object} config - HATEOAS config
 * @param {string} [config.target=''] - Property to create on entity for links
 * @param {Client} [config.client] - Client to use for following links
 */

Usage Example:

const hateoas = require('rest/interceptor/hateoas');

const client = rest.wrap(hateoas);

client('/api/users/123').then(function(response) {
  // Links are now accessible on the entity
  if (response.entity.next) {
    // Follow the 'next' relationship
    return response.entity.next();
  }
  
  // Access link objects directly
  console.log(response.entity.nextLink); // Link object reference
});

Location Interceptor

Follow Location response headers.

const location = require('rest/interceptor/location');

/**
 * Location interceptor configuration
 * @param {object} config - Location config
 * @param {number|function} [config.code] - Status codes to follow
 */

Cross-Origin and Security

JSONP Interceptor

JSONP support for cross-origin requests.

const jsonp = require('rest/interceptor/jsonp');

/**
 * JSONP interceptor for cross-origin requests
 * @param {object} config - JSONP config
 * @param {string} [config.callback] - Callback parameter name
 */

CSRF Protection

Cross-Site Request Forgery protection.

const csrf = require('rest/interceptor/csrf');

/**
 * CSRF protection interceptor
 */

Interceptor Composition

Interceptors can be chained together to create complex client behaviors:

const mime = require('rest/interceptor/mime');
const basicAuth = require('rest/interceptor/basicAuth');
const errorCode = require('rest/interceptor/errorCode');
const pathPrefix = require('rest/interceptor/pathPrefix');

const client = rest
  .wrap(pathPrefix, { prefix: '/api/v1' })
  .wrap(basicAuth, { username: 'user', password: 'pass' })
  .wrap(mime)
  .wrap(errorCode, { code: 400 });

// This client will:
// 1. Add '/api/v1' prefix to all paths
// 2. Add Basic Auth headers
// 3. Handle MIME type conversion
// 4. Reject responses with status >= 400

Custom Interceptor Development

Create custom interceptors for specialized functionality:

const interceptor = require('rest/interceptor');

const loggingInterceptor = interceptor({
  init: function(config) {
    config.logLevel = config.logLevel || 'info';
    return config;
  },
  request: function(request, config) {
    console.log(`[${config.logLevel}] Request:`, request.method, request.path);
    return request;
  },
  response: function(response, config) {
    console.log(`[${config.logLevel}] Response:`, response.status.code);
    return response;
  },
  error: function(response, config) {
    console.error(`[${config.logLevel}] Error:`, response.status.code);
    // Return rejected promise to maintain error state
    return Promise.reject(response);
  }
});

const client = rest.wrap(loggingInterceptor, { logLevel: 'debug' });

Install with Tessl CLI

npx tessl i tessl/npm-rest

docs

index.md

interceptors.md

mime-system.md

url-building.md

tile.json