Skip to main content

Request Matching

RMP offers flexible matching options to ensure your mocks are applied exactly when you need them.

URL

String

URL strings are matched with URLPattern-style syntax. URLPattern has a few matching rules that can differ from common glob or routing syntax, so review the URLPattern docs carefully when using wildcards or query-string patterns.

tip

Use the URL Pattern Checker to test and debug your URLPattern strings.

Full URL String

Match requests by providing a full URL string.

await mockClient.GET('https://example.com/users', /* response */);

Important: this string matches any query parameters. URLPattern treats a missing search component as *, so the mock above matches all of these requests:

https://example.com/users matches
https://example.com/users?page=1 matches
https://example.com/users?anything=here matches

Set query: null to match string URL without any query parameters:

await mockClient.GET({
url: 'https://example.com/users',
query: null,
}, /* response */);

Examples:

https://example.com/users matches
https://example.com/users? matches
https://example.com/users?page=1 does not match
https://example.com/users?anything=here does not match

The URLPattern equivalent is a trailing ?, which creates an explicit empty search component:

await mockClient.GET('https://example.com/users?', /* response */);
Named Groups

Named groups capture a part of the matched URL under a given name using :name syntax. They match any character sequence that doesn't cross a path segment boundary (i.e. stops at /).

await mockClient.GET('https://example.com/users/:id', /* response */);
https://example.com/users/123 matches (id = "123")
https://example.com/users/abc matches (id = "abc")
https://example.com/users does not match

Named groups can be used in the response body via {{ name }} substitution — see Route Parameters.

You can also use named groups in the hostname. In that case the group stops at . instead of /:

await mockClient.GET('https://:env.example.com/users', /* response */);
https://api.example.com/users matches (env = "api")
https://staging.example.com/users matches (env = "staging")
https://example.com/users does not match
Regex in URLPattern

URLPattern strings can include regex matchers inside parentheses. It can be named :name(regex) or unnamed (regex). Use them to define alternative URL parts or constraints.

Example 1: match two hostnames example.com and example.io:

await mockClient.GET('https://example.(com|io)/users', /* response */);
https://example.com/users matches
https://example.io/users matches
https://example.org/users does not match

Example 2: match only URLs with digits in user id:

await mockClient.GET('https://example.com/users/:id(\\d+)', /* response */);
https://example.com/users/123 matches
https://example.com/users/abc does not match

In JavaScript and TypeScript strings, escape regex backslashes as \\. For example, write \\d+ instead of \d+.

Wildcard

In URLPattern syntax, * matches any character sequence, not a single path segment:

await mockClient.GET('https://example.com/users/*', /* response */);
https://example.com/users/ matches
https://example.com/users/1 matches
https://example.com/users/1/posts matches
https://example.com/users does not match
https://example.com/users?page=1 does not match
https://example.com/products/1 does not match

Wildcards can also be used inside the hostname. The hostname wildcard matches any character sequence inside the hostname component, including dots:

await mockClient.GET('https://*.example.com/users', /* response */);
https://api.example.com/users matches
https://cdn.example.com/users matches
https://foo.bar.example.com/users matches
https://example.com/users does not match
https://api.example.com/users/1 does not match
https://api.example.org/users does not match

For any subdomain plus the root domain, use:

await mockClient.GET('https://{*.}?example.com', /* response */);

Trailing Slash

URLPattern does not ignore trailing slashes by default. To match both /users and /users/, use an optional group as described in the URLPattern pattern syntax docs:

await mockClient.GET('https://example.com/users{/}?', /* response */);
https://example.com/users matches
https://example.com/users/ matches

Regex

RMP accepts RegExp object instead of string, that is more predictable in some cases. This exmaple matches any URL with /users/xxx pathname:

await mockClient.GET(/\/users\/\d+$/, /* response */);

Object

The url field also accepts a matcher object — the same value matchers used for query, headers and body. This lets you match the URL by substring instead of a URLPattern:

await mockClient.GET({ url: { $$contains: '/v2/users' } }, /* response */);
https://example.com/v2/users matches
https://example.com/api/v2/users?page=1 matches
https://example.com/v1/users does not match
note

The legacy patternType: 'urlpattern' | 'regexp' sibling field is still supported but deprecated — prefer the url matcher object above.

Method

Explicitly define the HTTP method to match:

// GET
await mockClient.GET('https://api.example.com/users', /* response */);
// POST
await mockClient.POST('https://api.example.com/users', /* response */);
// Any HTTP method
await mockClient.ALL('https://api.example.com/users', /* response */);

Query

Match requests by specific URL query parameters:

await mockClient.GET({
url: 'https://api.example.com/users',
query: {
page: '1'
},
}, /* response */);

This matches query page=1 in any position:

https://api.example.com/users?page=1 matches
https://api.example.com/users?page=1&size=10 matches
https://api.example.com/users?size=10&page=1 matches
https://api.example.com/users does not match
https://api.example.com/users?size=10 does not match

To require a URL with no query params, set query to null:

await mockClient.GET({
url: 'https://api.example.com/users',
query: null,
}, /* response */);

Use a value matcher to match a query param loosely. This matches any request whose search param contains phone:

await mockClient.GET({
url: 'https://api.example.com/users',
query: {
search: { $$contains: 'phone' },
},
}, /* response */);
https://api.example.com/users?search=phone matches
https://api.example.com/users?search=smartphone matches
https://api.example.com/users?search=laptop does not match

Headers

Match requests by HTTP headers:

await mockClient.GET({
url: 'https://api.example.com/users',
headers: {
Authorization: 'Bearer test-token'
},
}, /* response */);

Use a value matcher to match a header loosely. This matches any request whose Authorization header contains Bearer, regardless of the token:

await mockClient.GET({
url: 'https://api.example.com/users',
headers: {
Authorization: { $$contains: 'Bearer' },
},
}, /* response */);

Body

Match requests by string or JSON request body.

await mockClient.POST({
url: 'https://api.example.com/users',
body: {
role: 'admin'
},
}, /* response */);

Use a value matcher to match a body field loosely. This matches any request whose email field contains @acme.com:

await mockClient.POST({
url: 'https://api.example.com/users',
body: {
email: { $$contains: '@acme.com' },
},
}, /* response */);

Combination

Combine all matchers together:

await mockClient.POST({
url: 'https://api.example.com/users',
query: {
page: '1'
},
headers: {
Authorization: 'Bearer test-token'
},
body: {
role: 'admin'
},
}, /* response */);

If multiple mocks match the same request, the most recently added matching mock is used. Mock precedence is based on registration order, not URL specificity.

Value Matchers

By default query params, headers and body fields are matched by exact equality. To match more loosely, replace any value with a RegExp or a matcher object. The same values also power the URL matcher object.

ValueExampleMatches when
string'admin'value equals admin (exact match, the default)
RegExp/admin/value matches the regular expression. A RegExp is converted under the hood to its serializable form { $$regex: '/admin/' }, so the schema stays JSON‑transferable.
$$contains{ $$contains: 'admin' }value is a string that includes the substring admin

Example code

await mockClient.POST({
url: 'https://api.example.com/users',
query: { page: /^\d+$/ }, // regular expression
headers: { Authorization: { $$contains: 'Bearer' } }, // substring
body: {
email: /.+@acme\.com$/, // regular expression
role: 'admin', // exact match
},
}, /* response */);

In body, matchers work at any nesting depth; every other field keeps the existing subset (partial) matching behavior.

note

The $$ prefix is intentional. It keeps matcher keys distinct from ordinary data, so pasting a real request/response payload that happens to contain a $contains or $regex field is matched literally and never silently turned into a fuzzy matcher.