Skip to content

Path Matching Rules ​

This chapter introduces the path matching mechanism in vite-plugin-mock-dev-server in detail, helping you precisely control which requests should be mocked.

Overview ​

The plugin uses the path-to-regexp library for path matching, the same library used by mainstream frameworks like Express and Koa, providing powerful and flexible path matching capabilities.

Basic Matching Rules ​

Static Path Matching ​

The simplest matching method requires an exact URL match:

ts
export default defineMock({
  url: '/api/users', // Only matches /api/users
  body: { list: [] },
})
Request URLMatch Result
/api/users✅ Match
/api/users/❌ No match (note trailing slash)
/api/users/123❌ No match
/API/users❌ No match (case-sensitive)

Dynamic Parameter Matching ​

Use :paramName syntax to capture dynamic parts of the URL:

ts
export default defineMock({
  url: '/api/users/:id',
  body: ({ params }) => ({
    userId: params.id, // Get captured parameter
  }),
})
Request URLMatch Resultparams Value
/api/users/123✅ Match{ id: '123' }
/api/users/abc✅ Match{ id: 'abc' }
/api/users❌ No match-
/api/users/123/posts❌ No match-

Multiple Dynamic Parameters ​

You can define multiple parameters in a single URL:

ts
export default defineMock({
  url: '/api/users/:userId/posts/:postId',
  body: ({ params }) => ({
    userId: params.userId,
    postId: params.postId,
  }),
})
Request URLparams Value
/api/users/1/posts/100{ userId: '1', postId: '100' }

Advanced Matching Rules ​

Optional Parameters ​

Use {} to wrap parameters to mark them as optional:

ts
export default defineMock({
  url: '/api/users{/:id}',
  body: ({ params }) => {
    if (params.id) {
      return { type: 'single', id: params.id }
    }
    return { type: 'list', users: [] }
  },
})
Request URLMatch Resultparams Value
/api/users✅ Match{}
/api/users/123✅ Match{ id: '123' }

Wildcard Matching ​

Use *name syntax to match one or more path segments:

ts
export default defineMock({
  url: '/api/files/*path',
  body: ({ params }) => ({
    path: params.path, // Array format
  }),
})
Request URLparams.path
/api/files/docs['docs']
/api/files/docs/guide.md['docs', 'guide.md']

Zero or More Matches

To match zero or more path segments, wrap the wildcard with an optional group:

ts
export default defineMock({
  url: '/api/files{/*path}',
  body: ({ params }) => ({
    path: params.path || [], // May be undefined or array
  }),
})
Request URLparams.path
/api/filesundefined
/api/files/docs['docs']

Any Path Matching ​

Use wildcards to match any path:

ts
export default defineMock({
  url: '/api/proxy/*path',
  body: ({ params }) => ({
    proxiedPath: params.path?.join('/'), // Access using array method
  }),
})
Request URLparams.path
/api/proxy/anything['anything']
/api/proxy/a/b/c['a', 'b', 'c']

Prefix Matching (Regex Form) ​

Use ^ at the beginning in plugin configuration to indicate regex matching:

ts
mockDevServerPlugin({
  prefix: [
    '/api', // String prefix
    '^/api/v\\d+/.*', // Regex: matches /api/v1/, /api/v2/, etc.
    '^/graphql$', // Regex: exact match /graphql
  ],
})

Path Matching Priority ​

When multiple Mock configurations match the same request, the plugin determines priority according to the following rules:

Default Priority Rules ​

  1. Static path > Dynamic parameter - /api/users takes precedence over /api/:id
  2. Fewer parameters > More parameters - /api/a/:b takes precedence over /api/:a/:b
  3. Definition order - When priority is equal, the one defined first takes precedence

Example ​

ts
export default defineMock([
  {
    url: '/api/users', // Priority 1: static path
    body: 'all users',
  },
  {
    url: '/api/users/:id', // Priority 2: one dynamic parameter
    body: 'single user',
  },
  {
    url: '/api/:resource/:id', // Priority 3: two dynamic parameters
    body: 'generic resource',
  },
])
Request URLMatched Configuration
/api/users/api/users
/api/users/123/api/users/:id
/api/posts/123/api/:resource/:id

Custom Priority ​

When default rules cannot meet your needs, you can use the priority configuration:

ts
mockDevServerPlugin({
  priority: {
    // Global priority: arranged in order, higher priority comes first
    global: [
      '/api/users/admin', // Highest priority
      '/api/users/:id',
      '/api/:resource/:id',
    ],
    // Special priority rules
    special: {
      '/api/:a/:b/c': {
        rules: ['/api/a/:b/:c'], // When conflicting with these rules
        when: ['/api/a/b/c'], // In these scenarios
      },
    },
  },
})

Multiple special rules

Every special rule that satisfies its rules / when conditions is promoted to the front. When a request hits several special rules at once, all of them are promoted and the declaration order is kept: a rule declared earlier comes before the ones declared later.

TIP

The same path matching and priority rules also apply to WebSocket mocks. When several rules match the same websocket path at the same time, the rule with the higher priority wins.

Real-world Application Scenarios ​

Scenario 1: RESTful API Design ​

ts
export default defineMock([
  // List and create
  {
    url: '/api/users',
    method: 'GET',
    body: { users: [] },
  },
  {
    url: '/api/users',
    method: 'POST',
    body: ({ body }) => ({ id: Date.now(), ...body }),
  },
  // Single resource operations
  {
    url: '/api/users/:id',
    method: 'GET',
    body: ({ params }) => ({ id: params.id }),
  },
  {
    url: '/api/users/:id',
    method: 'PUT',
    body: ({ params, body }) => ({ id: params.id, ...body }),
  },
  {
    url: '/api/users/:id',
    method: 'DELETE',
    status: 204,
  },
  // Nested resources
  {
    url: '/api/users/:userId/posts',
    body: ({ params }) => ({ userId: params.userId, posts: [] }),
  },
])

Scenario 2: File Service ​

ts
export default defineMock([
  {
    url: '/api/files/:type(images|documents|videos)/:name',
    body: ({ params }) => ({
      type: params.type,
      filename: params.name,
    }),
  },
  {
    url: '/api/download/*path',
    response: (req, res) => {
      const filePath = req.params.path?.join('/')
      // Handle file download...
    },
  },
])

Scenario 3: Versioned API ​

ts
mockDevServerPlugin({
  prefix: [
    '^/api/v\\d+/.*', // Match all versioned APIs
  ],
})

export default defineMock([
  {
    url: '/api/v1/users',
    body: { version: 'v1', users: [] },
  },
  {
    url: '/api/v2/users',
    body: { version: 'v2', users: [], meta: {} },
  },
])

Important Notes ​

  1. Case-sensitive: URL matching is case-sensitive, /api/Users and /api/users are different paths
  2. Trailing slash: /api/users and /api/users/ are treated as different paths
  3. Parameter types: All parameter values are strings, you need to manually convert to numbers or other types

Migration from Old Versions ​

path-to-regexp v8.x has the following breaking changes compared to older versions:

Old Version Syntaxv8.x SyntaxDescription
:param?{/:param}Optional parameters use curly braces
:param*{/*param}Zero or more use optional group + wildcard
:param+/*paramOne or more use wildcard
(.*)/*paramWildcard uses named parameter form

Debugging Tips ​

Enable debug logging to view the matching process:

ts
mockDevServerPlugin({
  log: 'debug', // Enable detailed logs
})

In the console you will see:

  • Request path
  • Rules being attempted to match
  • Final matching result

This helps troubleshoot path matching issues.

Released under the MIT License