RESTful HTTP client library with composable interceptor architecture for Node.js and browsers
76
rest.js provides powerful URL construction and manipulation capabilities through the UrlBuilder class and URI template support. This enables dynamic URL generation with parameter substitution, query string building, and cross-origin detection.
Main URL construction and manipulation utility.
const UrlBuilder = require('rest/UrlBuilder');
/**
* Create a URL builder instance
* @param {string|UrlBuilder} template - Base URL template or another UrlBuilder
* @param {object} [params] - Default parameters
* @returns {UrlBuilder} URL builder instance
*/
function UrlBuilder(template, params)
/**
* URL builder methods
*/
interface UrlBuilder {
/**
* Append path and parameters to current URL
* @param {string} [template] - Path template to append
* @param {object} [params] - Parameters to merge
* @returns {UrlBuilder} New UrlBuilder instance
*/
append(template?: string, params?: object): UrlBuilder;
/**
* Create fully qualified URL (browser only)
* @returns {UrlBuilder} New UrlBuilder with fully qualified URL
*/
fullyQualify(): UrlBuilder;
/**
* Check if URL is absolute (has protocol or starts with /)
* @returns {boolean} True if URL is absolute
*/
isAbsolute(): boolean;
/**
* Check if URL is fully qualified (has protocol and host)
* @returns {boolean} True if URL is fully qualified
*/
isFullyQualified(): boolean;
/**
* Check if URL is cross-origin (different protocol, host, or port)
* @returns {boolean} True if URL is cross-origin
*/
isCrossOrigin(): boolean;
/**
* Parse URL into component parts
* @returns {UrlParts} URL components similar to window.location
*/
parts(): UrlParts;
/**
* Build final URL string with parameter substitution
* @param {object} [params] - Additional parameters to merge
* @returns {string} Final URL string
*/
build(params?: object): string;
/**
* Convert to string (alias for build)
* @returns {string} URL string
*/
toString(): string;
}
/**
* URL component parts (similar to window.location)
*/
interface UrlParts {
href: string; // Complete URL
protocol: string; // Protocol (http:, https:, etc.)
host: string; // Hostname and port
hostname: string; // Hostname only
port: string; // Port number
pathname: string; // Path portion
search: string; // Query string (including ?)
hash: string; // Fragment (including #)
origin: string; // Protocol + host
}Basic Usage Examples:
const UrlBuilder = require('rest/UrlBuilder');
// Simple URL building
const url = new UrlBuilder('/api/users');
console.log(url.build()); // "/api/users"
// URL with parameters
const userUrl = new UrlBuilder('/api/users/{id}', { id: 123 });
console.log(userUrl.build()); // "/api/users/123"
// Query string parameters
const searchUrl = new UrlBuilder('/api/users');
console.log(searchUrl.build({ limit: 10, offset: 20 }));
// "/api/users?limit=10&offset=20"
// Template and query combination
const complexUrl = new UrlBuilder('/api/users/{id}/posts', { id: 123 });
console.log(complexUrl.build({ status: 'published', limit: 5 }));
// "/api/users/123/posts?status=published&limit=5"URL Manipulation:
const UrlBuilder = require('rest/UrlBuilder');
// Base URL
const baseUrl = new UrlBuilder('https://api.example.com/v1');
// Extend URL
const usersUrl = baseUrl.append('/users/{id}', { id: 456 });
console.log(usersUrl.build()); // "https://api.example.com/v1/users/456"
// Further extension
const postsUrl = usersUrl.append('/posts');
console.log(postsUrl.build({ limit: 10 }));
// "https://api.example.com/v1/users/456/posts?limit=10"
// Original URLs are unchanged
console.log(baseUrl.build()); // "https://api.example.com/v1"URL Analysis:
const UrlBuilder = require('rest/UrlBuilder');
const url = new UrlBuilder('https://api.example.com:8080/v1/users?limit=10#top');
// Check URL properties
console.log(url.isAbsolute()); // true
console.log(url.isFullyQualified()); // true
console.log(url.isCrossOrigin()); // depends on current origin
// Parse URL parts
const parts = url.parts();
console.log(parts.protocol); // "https:"
console.log(parts.hostname); // "api.example.com"
console.log(parts.port); // "8080"
console.log(parts.pathname); // "/v1/users"
console.log(parts.search); // "?limit=10"
console.log(parts.hash); // "#top"
console.log(parts.origin); // "https://api.example.com:8080"Advanced URI template processing using the template interceptor.
const template = require('rest/interceptor/template');
/**
* URI template interceptor for RFC 6570 template expansion
* Supports complex parameter expansion patterns
*/Usage with Template Interceptor:
const rest = require('rest');
const template = require('rest/interceptor/template');
const client = rest.wrap(template);
// RFC 6570 URI template expansion
client({
path: '/api/users{/id}{?limit,offset}',
params: {
id: 123,
limit: 10,
offset: 20
}
}).then(function(response) {
// Request made to: /api/users/123?limit=10&offset=20
console.log(response.entity);
});Direct URI template processing utilities.
const uriTemplate = require('rest/util/uriTemplate');
/**
* URI template expansion utilities
* Implements RFC 6570 URI Template specification
*/URL encoding utilities with section-aware encoding.
const uriEncoder = require('rest/util/uriEncoder');
/**
* URI encoding utilities
* Provides section-aware URI encoding for different URL parts
*/Automatically add prefixes to all request paths:
const rest = require('rest');
const pathPrefix = require('rest/interceptor/pathPrefix');
const client = rest.wrap(pathPrefix, { prefix: '/api/v2' });
client('/users').then(function(response) {
// Request made to: /api/v2/users
});
// Works with UrlBuilder objects too
const userUrl = new UrlBuilder('/users/{id}', { id: 123 });
client(userUrl.build()).then(function(response) {
// Request made to: /api/v2/users/123
});Advanced URI template expansion:
const rest = require('rest');
const template = require('rest/interceptor/template');
const client = rest.wrap(template);
// Complex template expansion
client({
path: '/search{/category*}{?q,limit,sort*}',
params: {
category: ['electronics', 'phones'],
q: 'smartphone',
limit: 20,
sort: ['price', 'rating']
}
}).then(function(response) {
// Request made to: /search/electronics/phones?q=smartphone&limit=20&sort=price&sort=rating
});In browser environments, UrlBuilder provides additional capabilities:
// Browser-only: fully qualify relative URLs
const url = new UrlBuilder('/api/users');
const fullyQualified = url.fullyQualify();
console.log(fullyQualified.build());
// "https://current-domain.com/api/users"
// Cross-origin detection
const externalUrl = new UrlBuilder('https://external-api.com/data');
console.log(externalUrl.isCrossOrigin()); // true (if different from current origin)const UrlBuilder = require('rest/UrlBuilder');
function createApiClient(baseUrl, version) {
const base = new UrlBuilder(baseUrl).append(`/v${version}`);
return {
users: (id) => base.append('/users/{id}', { id }),
posts: (userId) => base.append('/users/{userId}/posts', { userId }),
search: (type) => base.append('/search/{type}', { type })
};
}
const api = createApiClient('https://api.example.com', 2);
console.log(api.users(123).build()); // "https://api.example.com/v2/users/123"
console.log(api.posts(123).build({ limit: 5 }));
// "https://api.example.com/v2/users/123/posts?limit=5"const UrlBuilder = require('rest/UrlBuilder');
const apiTemplate = new UrlBuilder('/api/{resource}/{id}', {
resource: 'users' // default resource
});
// Use default resource
console.log(apiTemplate.build({ id: 123 })); // "/api/users/123"
// Override resource
console.log(apiTemplate.build({ resource: 'posts', id: 456 }));
// "/api/posts/456"Install with Tessl CLI
npx tessl i tessl/npm-restevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10