RESTful HTTP client library with composable interceptor architecture for Node.js and browsers
npx @tessl/cli install tessl/npm-rest@2.0.0rest.js is a RESTful HTTP client library designed for both Node.js and browser environments. It provides a composable architecture where the core client functionality can be extended through interceptors that wrap request and response handling, allowing developers to add features like authentication, error handling, MIME type conversion, and more.
npm install restconst rest = require('rest');For ES modules:
import rest from 'rest';Browser-specific client:
const rest = require('rest/browser');Node.js-specific client:
const rest = require('rest/node');const rest = require('rest');
// Simple GET request
rest('/api/users').then(function(response) {
console.log('Status:', response.status.code);
console.log('Data:', response.entity);
});
// POST request with data
rest({
path: '/api/users',
method: 'POST',
entity: { name: 'John', email: 'john@example.com' },
headers: { 'Content-Type': 'application/json' }
}).then(function(response) {
console.log('Created user:', response.entity);
});rest.js is built around several key components:
Core client functionality for making HTTP requests with configurable defaults and platform-specific implementations.
/**
* Make an HTTP request
* @param {string|Request} request - URL string or request object
* @returns {ResponsePromise<Response>} Promise that resolves to HTTP response
*/
function rest(request)
interface Request {
method?: string; // HTTP method (default: 'GET')
path?: string; // URL path template
params?: object; // URL parameters and query string
headers?: object; // HTTP headers
entity?: any; // Request body
canceled?: boolean; // Cancellation flag
cancel?: function; // Cancellation function
originator?: Client; // Originating client reference
}
interface Response {
request: Request; // Original request object
raw: any; // Platform-specific response object
status: { // HTTP status information
code: number; // Status code (200, 404, etc.)
text: string; // Status text
};
headers: object; // Response headers
entity: any; // Response body
}Build custom clients by wrapping with interceptors for authentication, error handling, content negotiation, and more.
/**
* Wrap a client with an interceptor
* @param {Interceptor} interceptor - Interceptor function
* @param {object} [config] - Configuration for the interceptor
* @returns {Client} New wrapped client
*/
client.wrap(interceptor, config)
/**
* Access the underlying client (when wrapped)
* @returns {Client} Target client
*/
client.skip()Automatic serialization and deserialization of request/response entities based on Content-Type headers, with support for JSON, form data, and custom converters.
const mime = require('rest/interceptor/mime');
const client = rest.wrap(mime);Powerful URL construction with parameter substitution, query string building, and template support.
const UrlBuilder = require('rest/UrlBuilder');
/**
* Create a URL builder
* @param {string} template - URL template
* @param {object} [params] - Default parameters
* @returns {UrlBuilder} URL builder instance
*/
function UrlBuilder(template, params)All client requests return enhanced promises with HTTP-specific helper methods:
interface ResponsePromise<T> extends Promise<T> {
/** Get response status code */
status(): Promise<number>;
/** Get all response headers */
headers(): Promise<object>;
/** Get specific response header */
header(name: string): Promise<string>;
/** Get response entity/body */
entity(): Promise<any>;
/** Follow hypermedia relationships */
follow(rels: string | object | Array): ResponsePromise<Response>;
}Usage Examples:
rest('/api/user/123')
.status().then(function(code) {
console.log('Status code:', code);
});
rest('/api/user/123')
.entity().then(function(user) {
console.log('User data:', user);
});
rest('/api/user/123')
.header('content-type').then(function(type) {
console.log('Content type:', type);
});// Set default client
rest.setDefaultClient(customClient);
// Get current default client
const currentClient = rest.getDefaultClient();
// Reset to platform default
rest.resetDefaultClient();rest.js provides first-class support for declarative configuration using wire.js dependency injection.
const wirePlugin = require('rest/wire');
/**
* Wire.js plugin for rest client factory
* Provides 'rest' factory for declarative client composition
*/Usage Example:
// wire.js spec
{
client: {
rest: [
{ module: 'rest/interceptor/mime' },
{ module: 'rest/interceptor/errorCode', config: { code: 500 } }
]
},
$plugins: [{ module: 'rest/wire' }]
}
// Alternative syntax with parent client
{
apiClient: {
rest: {
parent: { $ref: 'customClient' },
interceptors: [
{ module: 'rest/interceptor/pathPrefix', config: { prefix: '/api/v1' } },
{ module: 'rest/interceptor/mime' }
]
}
},
$plugins: [{ module: 'rest/wire' }]
}