or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-api.mdindex.mdpath-template.mdresource-names.md

path-template.mddocs/

0

# Path Templates

1

2

Path template functionality provides URL pattern matching, variable extraction, and path generation capabilities essential for Google API resource name handling. This system enables type-safe manipulation of REST API resource paths with variable substitution.

3

4

## Capabilities

5

6

### PathTemplate Class

7

8

Core class for representing and processing path templates. Supports variable extraction from paths, path generation from variables, and template validation.

9

10

```java { .api }

11

/**

12

* Represents a path template which can be used to parse and serialize resource names

13

*/

14

class PathTemplate {

15

/**

16

* Creates a template from the given pattern

17

* @param template The template pattern string (e.g., "projects/{project}/topics/{topic}")

18

* @return A PathTemplate instance

19

* @throws ValidationException If the template is invalid

20

*/

21

static PathTemplate create(String template);

22

23

/**

24

* Creates a template from the given pattern without URL encoding

25

* @param template The template pattern string

26

* @return A PathTemplate instance

27

* @throws ValidationException If the template is invalid

28

*/

29

static PathTemplate createWithoutUrlEncoding(String template);

30

31

/**

32

* Matches the given resource path against this template

33

* @param path The resource path to match

34

* @return True if the path matches this template

35

*/

36

boolean matches(String path);

37

38

/**

39

* Matches the given resource path and extracts the variable values

40

* @param path The resource path to match

41

* @return A map from variable names to their values

42

* @throws ValidationException If the path does not match this template

43

*/

44

Map<String, String> match(String path);

45

46

/**

47

* Matches a full resource name (including endpoint) and extracts variables

48

* @param path The full resource path to match

49

* @return A map from variable names to their values, including $hostname if present

50

* @throws ValidationException If the path does not match this template

51

*/

52

Map<String, String> matchFromFullName(String path);

53

54

/**

55

* Matches the path and returns the variable map, with validation and custom error messaging

56

* @param path The resource path to match

57

* @param exceptionMessagePrefix The prefix for the exception message if validation fails

58

* @return A map from variable names to their values

59

* @throws ValidationException If the path does not match this template

60

*/

61

Map<String, String> validatedMatch(String path, String exceptionMessagePrefix);

62

63

/**

64

* Validates that the given path matches this template

65

* @param path The resource path to validate

66

* @param exceptionMessagePrefix The prefix for the exception message if validation fails

67

* @throws ValidationException If the path does not match this template

68

*/

69

void validate(String path, String exceptionMessagePrefix);

70

71

/**

72

* Instantiates the template using the provided variable values

73

* @param values A map from variable names to their values

74

* @return The instantiated path

75

* @throws ValidationException If required variables are missing

76

*/

77

String instantiate(Map<String, String> values);

78

79

/**

80

* Instantiates the template using the provided key-value pairs

81

* @param keysAndValues Alternating keys and values (key1, value1, key2, value2, ...)

82

* @return The instantiated path

83

* @throws ValidationException If required variables are missing or wrong number of arguments

84

*/

85

String instantiate(String... keysAndValues);

86

87

/**

88

* Instantiates the template allowing unbound variables to remain as wildcards

89

* @param values A map from variable names to their values

90

* @return The partially instantiated path with wildcards for unbound variables

91

*/

92

String instantiatePartial(Map<String, String> values);

93

94

/**

95

* Returns the set of variable names used in this template

96

* @return A set of variable names

97

*/

98

Set<String> vars();

99

100

/**

101

* Returns the parent template (template with the last segment removed)

102

* @return The parent template, or null if this template has no parent

103

*/

104

PathTemplate parentTemplate();

105

106

/**

107

* Returns a template where all variables are replaced with wildcards

108

* @return A template with wildcards instead of variables

109

*/

110

PathTemplate withoutVars();

111

112

/**

113

* Returns a sub-template for the specified variable

114

* @param varName The variable name

115

* @return The sub-template, or null if the variable doesn't exist

116

*/

117

PathTemplate subTemplate(String varName);

118

119

/**

120

* Returns the single variable name if this template has exactly one variable

121

* @return The variable name, or null if the template doesn't have exactly one variable

122

*/

123

String singleVar();

124

125

/**

126

* Returns true if this template ends with a literal string (not a variable)

127

* @return True if the template ends with a literal

128

*/

129

boolean endsWithLiteral();

130

131

/**

132

* Returns true if this template ends with a custom verb

133

* @return True if the template ends with a custom verb

134

*/

135

boolean endsWithCustomVerb();

136

137

/**

138

* Creates a TemplatedResourceName from the given path using this template

139

* @param path The resource path

140

* @return A TemplatedResourceName instance

141

* @throws ValidationException If the path does not match this template

142

*/

143

TemplatedResourceName parse(String path);

144

145

/**

146

* Encodes the given values as a path using positional matching

147

* @param values The values to encode

148

* @return The encoded path

149

*/

150

String encode(String... values);

151

152

/**

153

* Decodes a path into positional values

154

* @param path The path to decode

155

* @return A list of decoded values

156

*/

157

List<String> decode(String path);

158

}

159

```

160

161

**Constants:**

162

163

```java { .api }

164

/**

165

* Special variable name for hostname bindings in full resource names

166

*/

167

String HOSTNAME_VAR = "$hostname";

168

```

169

170

**Usage Examples:**

171

172

```java

173

import com.google.api.pathtemplate.PathTemplate;

174

import java.util.Map;

175

176

// Create a path template

177

PathTemplate template = PathTemplate.create("projects/{project}/topics/{topic}");

178

179

// Extract variables from a path

180

Map<String, String> vars = template.match("projects/my-project/topics/my-topic");

181

// vars contains: {"project": "my-project", "topic": "my-topic"}

182

183

// Generate a path from variables

184

String path = template.instantiate("project", "my-project", "topic", "my-topic");

185

// path is: "projects/my-project/topics/my-topic"

186

187

// Check if a path matches

188

boolean matches = template.matches("projects/test/topics/news");

189

// matches is true

190

191

// Get all variable names in the template

192

Set<String> variableNames = template.vars();

193

// variableNames contains: ["project", "topic"]

194

195

// Work with nested resources - get parent template

196

PathTemplate parent = template.parentTemplate();

197

// parent template is: "projects/{project}"

198

199

// Handle full resource names with endpoints

200

PathTemplate fullTemplate = PathTemplate.create("projects/{project}/topics/{topic}");

201

Map<String, String> fullVars = fullTemplate.matchFromFullName(

202

"//pubsub.googleapis.com/projects/my-project/topics/my-topic"

203

);

204

// fullVars contains: {"$hostname": "pubsub.googleapis.com", "project": "my-project", "topic": "my-topic"}

205

```

206

207

### TemplatedResourceName Class

208

209

A resource name implementation that combines a path template with variable values, implementing the `Map<String, String>` interface for easy access to variable values.

210

211

```java { .api }

212

/**

213

* A resource name that is based on a path template

214

*/

215

class TemplatedResourceName implements Map<String, String> {

216

/**

217

* Creates a TemplatedResourceName from a template and resource path

218

* @param template The path template

219

* @param path The resource path that matches the template

220

* @return A TemplatedResourceName instance

221

* @throws ValidationException If the path does not match the template

222

*/

223

static TemplatedResourceName create(PathTemplate template, String path);

224

225

/**

226

* Creates a TemplatedResourceName from a template and variable values

227

* @param template The path template

228

* @param values A map of variable names to values

229

* @return A TemplatedResourceName instance

230

* @throws ValidationException If required variables are missing

231

*/

232

static TemplatedResourceName create(PathTemplate template, Map<String, String> values);

233

234

/**

235

* Creates a TemplatedResourceName from a template and full resource name (including endpoint)

236

* @param template The path template

237

* @param path The full resource path including endpoint

238

* @return A TemplatedResourceName instance

239

* @throws ValidationException If the path does not match the template

240

*/

241

static TemplatedResourceName createFromFullName(PathTemplate template, String path);

242

243

/**

244

* Returns the path template used to create this resource name

245

* @return The path template

246

*/

247

PathTemplate template();

248

249

/**

250

* Returns true if this resource name has an endpoint

251

* @return True if an endpoint is present

252

*/

253

boolean hasEndpoint();

254

255

/**

256

* Returns the endpoint of this resource name, or null if none

257

* @return The endpoint string, or null

258

*/

259

String endpoint();

260

261

/**

262

* Creates a copy of this resource name with the specified endpoint

263

* @param endpoint The endpoint to set

264

* @return A new TemplatedResourceName with the specified endpoint

265

*/

266

TemplatedResourceName withEndpoint(String endpoint);

267

268

/**

269

* Returns the parent resource name by using the parent template

270

* @return The parent resource name, or null if this resource has no parent

271

*/

272

TemplatedResourceName parentName();

273

274

/**

275

* Returns true if this resource name starts with the given parent name

276

* @param parentName The potential parent resource name

277

* @return True if this resource is a child of the given parent

278

*/

279

boolean startsWith(TemplatedResourceName parentName);

280

281

/**

282

* Resolves this resource name to a resource object via API call

283

* @param resourceType The type of resource to resolve to

284

* @param version The API version to use

285

* @return The resolved resource

286

* @throws Exception If the resolution fails

287

*/

288

<T> T resolve(Class<T> resourceType, String version) throws Exception;

289

}

290

```

291

292

**Resource Name Resolver:**

293

294

```java { .api }

295

/**

296

* Interface for pluggable resource name resolution

297

*/

298

interface Resolver {

299

/**

300

* Resolves a resource name to a resource object

301

* @param resourceName The resource name to resolve

302

* @param resourceType The type of resource to resolve to

303

* @param version The API version to use

304

* @return The resolved resource

305

* @throws Exception If the resolution fails

306

*/

307

<T> T resolve(TemplatedResourceName resourceName, Class<T> resourceType, String version) throws Exception;

308

}

309

310

/**

311

* Registers a global resource name resolver

312

* @param resolver The resolver to register

313

*/

314

static void registerResourceNameResolver(Resolver resolver);

315

```

316

317

**Usage Examples:**

318

319

```java

320

import com.google.api.pathtemplate.PathTemplate;

321

import com.google.api.pathtemplate.TemplatedResourceName;

322

import java.util.HashMap;

323

import java.util.Map;

324

325

// Create from path and template

326

PathTemplate template = PathTemplate.create("projects/{project}/topics/{topic}");

327

TemplatedResourceName resourceName = TemplatedResourceName.create(

328

template,

329

"projects/my-project/topics/my-topic"

330

);

331

332

// Access variable values (implements Map<String, String>)

333

String project = resourceName.get("project"); // "my-project"

334

String topic = resourceName.get("topic"); // "my-topic"

335

336

// Create from template and values

337

Map<String, String> values = new HashMap<>();

338

values.put("project", "another-project");

339

values.put("topic", "another-topic");

340

TemplatedResourceName fromValues = TemplatedResourceName.create(template, values);

341

342

// Work with parent resources

343

TemplatedResourceName parent = resourceName.parentName();

344

// parent represents "projects/my-project"

345

346

boolean isChild = resourceName.startsWith(parent); // true

347

348

// Work with endpoints

349

TemplatedResourceName withEndpoint = resourceName.withEndpoint("pubsub.googleapis.com");

350

boolean hasEndpoint = withEndpoint.hasEndpoint(); // true

351

String endpoint = withEndpoint.endpoint(); // "pubsub.googleapis.com"

352

353

// Create from full name with endpoint

354

TemplatedResourceName fromFullName = TemplatedResourceName.createFromFullName(

355

template,

356

"//pubsub.googleapis.com/projects/my-project/topics/my-topic"

357

);

358

```

359

360

### ValidationException

361

362

Exception thrown when path template operations fail validation, with support for contextual error messages.

363

364

```java { .api }

365

/**

366

* Exception thrown when path template validation fails

367

*/

368

class ValidationException extends IllegalArgumentException {

369

/**

370

* Creates a ValidationException with the given message

371

* @param message The error message

372

*/

373

public ValidationException(String message);

374

375

/**

376

* Creates a ValidationException with the given message and cause

377

* @param message The error message

378

* @param cause The underlying cause

379

*/

380

public ValidationException(String message, Throwable cause);

381

382

/**

383

* Sets a validation context for the current thread

384

* @param context The validation context description

385

*/

386

static void pushCurrentThreadValidationContext(String context);

387

388

/**

389

* Clears the validation context for the current thread

390

*/

391

static void popCurrentThreadValidationContext();

392

}

393

```

394

395

**Usage Examples:**

396

397

```java

398

import com.google.api.pathtemplate.PathTemplate;

399

import com.google.api.pathtemplate.ValidationException;

400

401

PathTemplate template = PathTemplate.create("projects/{project}/topics/{topic}");

402

403

try {

404

// This will throw ValidationException because the path doesn't match

405

template.match("projects/my-project/buckets/my-bucket");

406

} catch (ValidationException e) {

407

System.err.println("Path validation failed: " + e.getMessage());

408

}

409

410

// Use validation context for better error messages

411

ValidationException.pushCurrentThreadValidationContext("Processing user input");

412

try {

413

template.validate("invalid/path", "User provided path");

414

} catch (ValidationException e) {

415

// Exception message will include context information

416

System.err.println("Validation error: " + e.getMessage());

417

} finally {

418

ValidationException.popCurrentThreadValidationContext();

419

}

420

```

421

422

## Common Patterns

423

424

### Resource Hierarchy Navigation

425

426

```java

427

// Navigate up and down resource hierarchies

428

PathTemplate projectTemplate = PathTemplate.create("projects/{project}");

429

PathTemplate topicTemplate = PathTemplate.create("projects/{project}/topics/{topic}");

430

PathTemplate subscriptionTemplate = PathTemplate.create("projects/{project}/subscriptions/{subscription}");

431

432

// Create resource names

433

TemplatedResourceName project = TemplatedResourceName.create(projectTemplate, "projects/my-project");

434

TemplatedResourceName topic = TemplatedResourceName.create(topicTemplate, "projects/my-project/topics/news");

435

436

// Check relationships

437

boolean isChild = topic.startsWith(project); // true

438

439

// Get parent

440

TemplatedResourceName topicParent = topic.parentName();

441

// topicParent represents "projects/my-project"

442

```

443

444

### Template Composition

445

446

```java

447

// Create templates for different resource types in the same project

448

PathTemplate baseTemplate = PathTemplate.create("projects/{project}");

449

Set<String> baseVars = baseTemplate.vars(); // ["project"]

450

451

// Extend templates while maintaining the base structure

452

PathTemplate topicTemplate = PathTemplate.create("projects/{project}/topics/{topic}");

453

PathTemplate subscriptionTemplate = PathTemplate.create("projects/{project}/subscriptions/{subscription}");

454

455

// Extract common variables

456

Map<String, String> topicVars = topicTemplate.match("projects/my-project/topics/news");

457

String commonProject = topicVars.get("project"); // "my-project"

458

459

Map<String, String> subVars = subscriptionTemplate.match("projects/my-project/subscriptions/alerts");

460

String sameProject = subVars.get("project"); // "my-project" (same as above)

461

```

462

463

### Partial Path Generation

464

465

```java

466

PathTemplate template = PathTemplate.create("projects/{project}/topics/{topic}/subscriptions/{subscription}");

467

468

// Generate partial paths when not all variables are known

469

Map<String, String> partialValues = new HashMap<>();

470

partialValues.put("project", "my-project");

471

partialValues.put("topic", "news");

472

// subscription is missing

473

474

String partial = template.instantiatePartial(partialValues);

475

// partial is: "projects/my-project/topics/news/subscriptions/*"

476

```