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
      },
    },
  },
})

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