Skip to content

Variables

@t-req/core supports powerful variable interpolation with {{variable}} syntax and custom resolvers for dynamic values.

Pass variables when creating the client or running requests:

const client = createClient({
variables: {
baseUrl: 'https://api.example.com',
apiKey: 'secret-key',
},
});
// Use in .http files
// GET {{baseUrl}}/users
// Authorization: Bearer {{apiKey}}

Update variables at runtime:

// Set a single variable
client.setVariable('token', 'new-token');
// Set multiple variables
client.setVariables({ a: 1, b: 2 });
// Get all variables
console.log(client.getVariables());

Override or add variables for a specific request:

const response = await client.run('./api/user.http', {
variables: { userId: '123' },
});

Access nested properties with dot notation:

const client = createClient({
variables: {
user: { name: 'John', id: 123 },
},
});
// In .http file: GET /users/{{user.id}}

Resolvers provide dynamic values. They’re functions called with optional arguments:

const client = createClient({
resolvers: {
$env: (key) => process.env[key] || '',
$timestamp: () => String(Date.now()),
$uuid: () => crypto.randomUUID(),
$random: (min = '0', max = '100') => {
const minNum = Number(min);
const maxNum = Number(max);
return String(Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
},
},
});

Use resolvers in .http files:

POST https://api.example.com/data
Authorization: Bearer {{$env(API_KEY)}}
X-Request-ID: {{$uuid()}}
X-Timestamp: {{$timestamp()}}
{
"random_value": {{$random(1, 100)}}
}

@t-req/core provides the resolver architecture but ships with zero built-in resolvers. You must implement any resolvers you want to use. Here are common patterns:

$env: (key) => process.env[key] || ''
Authorization: Bearer {{$env(API_TOKEN)}}
$timestamp: () => String(Date.now()),
$isoDate: () => new Date().toISOString(),
X-Timestamp: {{$timestamp()}}
X-Date: {{$isoDate()}}
$uuid: () => crypto.randomUUID(),
$random: (min = '0', max = '100') => {
return String(Math.floor(Math.random() * (Number(max) - Number(min) + 1)) + Number(min));
},
$base64: (value) => Buffer.from(value).toString('base64'),
Authorization: Basic {{$base64(username:password)}}

For advanced use cases, use the interpolator directly:

import { interpolate, createInterpolator } from '@t-req/core';
// Simple interpolation
const result = interpolate('Hello {{name}}!', { name: 'World' });
// "Hello World!"
// With resolvers
const interp = createInterpolator({
resolvers: {
$timestamp: () => String(Date.now()),
},
});
const result = await interp.interpolate(
'Time: {{$timestamp()}}',
{}
);

When the same variable is defined in multiple places:

  1. Per-request variables option (highest priority)
  2. client.setVariable() / client.setVariables()
  3. Initial createClient({ variables }) (lowest priority)
const client = createClient({
variables: { env: 'dev' },
});
client.setVariable('env', 'staging');
// This uses env = 'prod'
await client.run('./api.http', {
variables: { env: 'prod' },
});

Control what happens when a variable is not found during interpolation with the undefinedBehavior option:

import { createInterpolator } from '@t-req/core';
// Default: throw an error
const strict = createInterpolator({
undefinedBehavior: 'throw', // throws Error for undefined variables
});
// Keep the placeholder as-is
const keep = createInterpolator({
undefinedBehavior: 'keep', // {{missing}} stays as "{{missing}}"
});
// Replace with empty string
const empty = createInterpolator({
undefinedBehavior: 'empty', // {{missing}} becomes ""
});
ValueBehavior
'throw'Throw an error (default)
'keep'Keep the {{variable}} placeholder unchanged
'empty'Replace with empty string

This is useful for:

  • Development: Use 'throw' to catch missing variables early
  • Templates: Use 'keep' when processing templates in stages
  • Optional values: Use 'empty' when undefined should mean “no value”