or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdinterceptors.mdmime-system.mdurl-building.md

url-building.mddocs/

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

```