0
# URL Building
1
2
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.
3
4
## Capabilities
5
6
### UrlBuilder Class
7
8
Main URL construction and manipulation utility.
9
10
```javascript { .api }
11
const UrlBuilder = require('rest/UrlBuilder');
12
13
/**
14
* Create a URL builder instance
15
* @param {string|UrlBuilder} template - Base URL template or another UrlBuilder
16
* @param {object} [params] - Default parameters
17
* @returns {UrlBuilder} URL builder instance
18
*/
19
function UrlBuilder(template, params)
20
21
/**
22
* URL builder methods
23
*/
24
interface UrlBuilder {
25
/**
26
* Append path and parameters to current URL
27
* @param {string} [template] - Path template to append
28
* @param {object} [params] - Parameters to merge
29
* @returns {UrlBuilder} New UrlBuilder instance
30
*/
31
append(template?: string, params?: object): UrlBuilder;
32
33
/**
34
* Create fully qualified URL (browser only)
35
* @returns {UrlBuilder} New UrlBuilder with fully qualified URL
36
*/
37
fullyQualify(): UrlBuilder;
38
39
/**
40
* Check if URL is absolute (has protocol or starts with /)
41
* @returns {boolean} True if URL is absolute
42
*/
43
isAbsolute(): boolean;
44
45
/**
46
* Check if URL is fully qualified (has protocol and host)
47
* @returns {boolean} True if URL is fully qualified
48
*/
49
isFullyQualified(): boolean;
50
51
/**
52
* Check if URL is cross-origin (different protocol, host, or port)
53
* @returns {boolean} True if URL is cross-origin
54
*/
55
isCrossOrigin(): boolean;
56
57
/**
58
* Parse URL into component parts
59
* @returns {UrlParts} URL components similar to window.location
60
*/
61
parts(): UrlParts;
62
63
/**
64
* Build final URL string with parameter substitution
65
* @param {object} [params] - Additional parameters to merge
66
* @returns {string} Final URL string
67
*/
68
build(params?: object): string;
69
70
/**
71
* Convert to string (alias for build)
72
* @returns {string} URL string
73
*/
74
toString(): string;
75
}
76
77
/**
78
* URL component parts (similar to window.location)
79
*/
80
interface UrlParts {
81
href: string; // Complete URL
82
protocol: string; // Protocol (http:, https:, etc.)
83
host: string; // Hostname and port
84
hostname: string; // Hostname only
85
port: string; // Port number
86
pathname: string; // Path portion
87
search: string; // Query string (including ?)
88
hash: string; // Fragment (including #)
89
origin: string; // Protocol + host
90
}
91
```
92
93
**Basic Usage Examples:**
94
95
```javascript
96
const UrlBuilder = require('rest/UrlBuilder');
97
98
// Simple URL building
99
const url = new UrlBuilder('/api/users');
100
console.log(url.build()); // "/api/users"
101
102
// URL with parameters
103
const userUrl = new UrlBuilder('/api/users/{id}', { id: 123 });
104
console.log(userUrl.build()); // "/api/users/123"
105
106
// Query string parameters
107
const searchUrl = new UrlBuilder('/api/users');
108
console.log(searchUrl.build({ limit: 10, offset: 20 }));
109
// "/api/users?limit=10&offset=20"
110
111
// Template and query combination
112
const complexUrl = new UrlBuilder('/api/users/{id}/posts', { id: 123 });
113
console.log(complexUrl.build({ status: 'published', limit: 5 }));
114
// "/api/users/123/posts?status=published&limit=5"
115
```
116
117
**URL Manipulation:**
118
119
```javascript
120
const UrlBuilder = require('rest/UrlBuilder');
121
122
// Base URL
123
const baseUrl = new UrlBuilder('https://api.example.com/v1');
124
125
// Extend URL
126
const usersUrl = baseUrl.append('/users/{id}', { id: 456 });
127
console.log(usersUrl.build()); // "https://api.example.com/v1/users/456"
128
129
// Further extension
130
const postsUrl = usersUrl.append('/posts');
131
console.log(postsUrl.build({ limit: 10 }));
132
// "https://api.example.com/v1/users/456/posts?limit=10"
133
134
// Original URLs are unchanged
135
console.log(baseUrl.build()); // "https://api.example.com/v1"
136
```
137
138
**URL Analysis:**
139
140
```javascript
141
const UrlBuilder = require('rest/UrlBuilder');
142
143
const url = new UrlBuilder('https://api.example.com:8080/v1/users?limit=10#top');
144
145
// Check URL properties
146
console.log(url.isAbsolute()); // true
147
console.log(url.isFullyQualified()); // true
148
console.log(url.isCrossOrigin()); // depends on current origin
149
150
// Parse URL parts
151
const parts = url.parts();
152
console.log(parts.protocol); // "https:"
153
console.log(parts.hostname); // "api.example.com"
154
console.log(parts.port); // "8080"
155
console.log(parts.pathname); // "/v1/users"
156
console.log(parts.search); // "?limit=10"
157
console.log(parts.hash); // "#top"
158
console.log(parts.origin); // "https://api.example.com:8080"
159
```
160
161
### URI Template Support
162
163
Advanced URI template processing using the template interceptor.
164
165
```javascript { .api }
166
const template = require('rest/interceptor/template');
167
168
/**
169
* URI template interceptor for RFC 6570 template expansion
170
* Supports complex parameter expansion patterns
171
*/
172
```
173
174
**Usage with Template Interceptor:**
175
176
```javascript
177
const rest = require('rest');
178
const template = require('rest/interceptor/template');
179
180
const client = rest.wrap(template);
181
182
// RFC 6570 URI template expansion
183
client({
184
path: '/api/users{/id}{?limit,offset}',
185
params: {
186
id: 123,
187
limit: 10,
188
offset: 20
189
}
190
}).then(function(response) {
191
// Request made to: /api/users/123?limit=10&offset=20
192
console.log(response.entity);
193
});
194
```
195
196
### URI Template Utility
197
198
Direct URI template processing utilities.
199
200
```javascript { .api }
201
const uriTemplate = require('rest/util/uriTemplate');
202
203
/**
204
* URI template expansion utilities
205
* Implements RFC 6570 URI Template specification
206
*/
207
```
208
209
### URI Encoding Utilities
210
211
URL encoding utilities with section-aware encoding.
212
213
```javascript { .api }
214
const uriEncoder = require('rest/util/uriEncoder');
215
216
/**
217
* URI encoding utilities
218
* Provides section-aware URI encoding for different URL parts
219
*/
220
```
221
222
## Integration with Interceptors
223
224
### Path Prefix Interceptor
225
226
Automatically add prefixes to all request paths:
227
228
```javascript
229
const rest = require('rest');
230
const pathPrefix = require('rest/interceptor/pathPrefix');
231
232
const client = rest.wrap(pathPrefix, { prefix: '/api/v2' });
233
234
client('/users').then(function(response) {
235
// Request made to: /api/v2/users
236
});
237
238
// Works with UrlBuilder objects too
239
const userUrl = new UrlBuilder('/users/{id}', { id: 123 });
240
client(userUrl.build()).then(function(response) {
241
// Request made to: /api/v2/users/123
242
});
243
```
244
245
### Template Interceptor
246
247
Advanced URI template expansion:
248
249
```javascript
250
const rest = require('rest');
251
const template = require('rest/interceptor/template');
252
253
const client = rest.wrap(template);
254
255
// Complex template expansion
256
client({
257
path: '/search{/category*}{?q,limit,sort*}',
258
params: {
259
category: ['electronics', 'phones'],
260
q: 'smartphone',
261
limit: 20,
262
sort: ['price', 'rating']
263
}
264
}).then(function(response) {
265
// Request made to: /search/electronics/phones?q=smartphone&limit=20&sort=price&sort=rating
266
});
267
```
268
269
## Browser Considerations
270
271
In browser environments, UrlBuilder provides additional capabilities:
272
273
```javascript
274
// Browser-only: fully qualify relative URLs
275
const url = new UrlBuilder('/api/users');
276
const fullyQualified = url.fullyQualify();
277
console.log(fullyQualified.build());
278
// "https://current-domain.com/api/users"
279
280
// Cross-origin detection
281
const externalUrl = new UrlBuilder('https://external-api.com/data');
282
console.log(externalUrl.isCrossOrigin()); // true (if different from current origin)
283
```
284
285
## Advanced URL Building Patterns
286
287
### Dynamic Base URLs
288
289
```javascript
290
const UrlBuilder = require('rest/UrlBuilder');
291
292
function createApiClient(baseUrl, version) {
293
const base = new UrlBuilder(baseUrl).append(`/v${version}`);
294
295
return {
296
users: (id) => base.append('/users/{id}', { id }),
297
posts: (userId) => base.append('/users/{userId}/posts', { userId }),
298
search: (type) => base.append('/search/{type}', { type })
299
};
300
}
301
302
const api = createApiClient('https://api.example.com', 2);
303
console.log(api.users(123).build()); // "https://api.example.com/v2/users/123"
304
console.log(api.posts(123).build({ limit: 5 }));
305
// "https://api.example.com/v2/users/123/posts?limit=5"
306
```
307
308
### URL Templates with Defaults
309
310
```javascript
311
const UrlBuilder = require('rest/UrlBuilder');
312
313
const apiTemplate = new UrlBuilder('/api/{resource}/{id}', {
314
resource: 'users' // default resource
315
});
316
317
// Use default resource
318
console.log(apiTemplate.build({ id: 123 })); // "/api/users/123"
319
320
// Override resource
321
console.log(apiTemplate.build({ resource: 'posts', id: 456 }));
322
// "/api/posts/456"
323
```