Skip to main content

服务器 API:路由

🌐 Server API: Routes

Page summary:

服务器 API 从服务器入口文件导出一个 routes 值以公开插件端点。仅对隐式管理路由使用数组格式,使用命名路由格式分离管理和内容 API 路由,或使用工厂回调格式进行动态路由配置。

路由会公开你的插件的 HTTP 端点,并将传入请求映射到控制器操作。它们从 服务器入口文件 导出,作为一个 routes 值。

🌐 Routes expose your plugin's HTTP endpoints and map incoming requests to controller actions. They are exported from the server entry file as a routes value.

Prerequisites

在深入了解本页的概念之前,请确保你已经:

🌐 Before diving deeper into the concepts on this page, please ensure you have:

路由声明格式

🌐 Route declaration formats

Which format should I use?
  • 数组格式 只需要管理员路由且具有默认注册行为的简单插件
  • **命名路由格式:**暴露管理员和内容 API 路由的插件,或者需要显式类型控制的插件。推荐在大多数情况下使用。
  • 工厂回调格式 高级情况,其中路由配置依赖于 strapi 实例(例如,读取插件配置)。

数组格式

🌐 Array format

数组格式是最基本的格式:它直接导出路由对象的数组。Strapi 默认将这些对象注册为管理路由,插件名称作为前缀。

🌐 The array format is the most basic format: it exports an array of route objects directly. Strapi registers these objects as admin routes by default, with the plugin name as prefix.

Tip

要公开内容 API 路由,请使用带有 type: 'content-api'命名路由格式

🌐 To expose Content API routes, use the named router format with type: 'content-api'.

/src/plugins/my-plugin/server/src/routes/index.js
'use strict';

module.exports = [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
policies: [],
},
},
{
method: 'POST',
path: '/articles',
handler: 'article.create',
config: {
policies: [],
},
},
];

命名路由格式

🌐 Named router format

使用命名路由格式时,使用具有命名键(admincontent-api 或任何自定义名称)的对象来声明单独的路由组。每个组都是一个路由对象,包含 type、可选的 prefix 和一个 routes 数组。当你的插件同时暴露管理和内容 API 路由时使用此格式。

🌐 With the named router format, use an object with named keys (admin, content-api, or any custom name) to declare separate router groups. Each group is a router object with a type, optional prefix, and a routes array. Use this format when your plugin exposes both admin and Content API routes.

/src/plugins/my-plugin/server/src/routes/index.js
'use strict';

const adminRoutes = require('./admin');
const contentApiRoutes = require('./content-api');

module.exports = {
admin: adminRoutes,
'content-api': contentApiRoutes,
};
/src/plugins/my-plugin/server/src/routes/admin/index.js
'use strict';

module.exports = {
type: 'admin',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
],
};
/src/plugins/my-plugin/server/src/routes/content-api/index.js
'use strict';

module.exports = {
type: 'content-api',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
policies: [],
},
},
],
};

工厂回调格式

🌐 Factory callback format

对于需要在路由配置时访问 strapi 实例的高级情况(例如,用于构建动态路径或根据配置有条件地包含路由),你可以导出一个工厂回调。

🌐 For advanced cases where you need access to the strapi instance at route configuration time (for example, to build dynamic paths or conditionally include routes based on configuration), you can export a factory callback.

Note

工厂回调必须附加到命名路由条目(例如 admincontent-api),而不是作为 routes/index 的根导出。

🌐 The factory callback must be attached to a named route entry (such as admin or content-api), not exported as the root of routes/index.

module.exports = ({ strapi }) => ({ ... }) 在根级别不是有效的格式。

/src/plugins/my-plugin/server/src/routes/index.js
'use strict';

module.exports = {
'content-api': ({ strapi }) => ({
type: 'content-api',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
auth: strapi.plugin('my-plugin').config('publicRead') ? false : {},
},
},
],
}),
};

有关 Strapi 在注册时自动添加的内容的详细信息,请参见 Strapi 应用的默认值

🌐 For details on what Strapi adds automatically at registration time, see Defaults applied by Strapi.

Strapi 应用的默认设置

🌐 Defaults applied by Strapi

当 Strapi 注册插件路由时,它会自动应用以下默认设置:

🌐 When Strapi registers plugin routes, it applies the following defaults automatically: | 属性 | 默认值 | 说明 || --- | --- | --- || type | 'admin' | 在使用数组格式时应用,或者在命名格式中路由对象省略 type 时应用 || prefix | '/<plugin-name>' | 在使用数组格式时应用,或者在路由对象中省略 prefix 时应用 || config.auth.scope | ['plugin::<plugin-name>.<handler>'] | 仅对字符串处理器自动生成,使用 defaultsDeep,以避免覆盖现有值 |

以下两条声明是等效的。Strapi 会自动应用上表中的默认值:

🌐 The following 2 declarations are equivalent. Strapi applies the defaults from the table above automatically:

Implicit (array format, defaults applied by Strapi)
module.exports = [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
},
];
Equivalent explicit declaration (named router format)
module.exports = {
admin: {
type: 'admin',
prefix: '/my-plugin',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
auth: {
scope: ['plugin::my-plugin.article.find'], // auto-generated from handler string
},
},
},
],
},
};

路由配置参考

🌐 Route configuration reference

每条路由都可以接受一个可选的 config 对象,该对象具有以下属性:

🌐 Each route accepts an optional config object with the following properties:

policies

类型: Array<string | PolicyHandler | { name: string; options?: object }>

在控制器动作之前运行的策略。每一项要么是策略名称字符串,要么是内联函数,或者是包含必需的 name 和可选的 options 的对象。

🌐 Policies to run before the controller action. Each item is either a policy name string, an inline function, or an object with required name and optional options.

options 对象将原样传递给策略函数的第二个参数(策略签名中的 config)。该对象的形状取决于策略。

🌐 The options object is passed as-is to the policy function's second argument (config in policy signatures). The shape of this object depends on the policy.

插件政策被引用为 plugin::my-plugin.policy-name

🌐 Plugin policies are referenced as plugin::my-plugin.policy-name.

middlewares

类型: Array<string | MiddlewareHandler | { name: string; options?: object }>

要应用到此路由的中间件。每个项目可以是中间件名称字符串、内联函数或具有以下属性的对象:

🌐 Middlewares to apply to this route. Each item is a middleware name string, an inline function, or an object with:

  • name:已注册的中间件名称,
  • options(可选):中间件选项。
Route middlewares vs. global server middlewares

在路由验证时,Strapi 会根据 { name: string; options?: object } 验证中间件/策略对象(参见 services/server/routing.ts)。

🌐 At route validation time, Strapi validates middleware/policy objects against { name: string; options?: object } (see services/server/routing.ts).

中间件解析器(services/server/middleware.ts)仍然包含对 { resolve, config } 对象的运行时支持,但在标准插件路由声明解析之前,此形状会被路由验证拒绝。

🌐 The middleware resolver (services/server/middleware.ts) still contains runtime support for { resolve, config } objects, but this shape is rejected by route validation before resolution for standard plugin route declarations.

在路由配置中使用 { name, options } 以兼容验证。

🌐 Use { name, options } in route configs for compatibility with validation.

auth

类型: false | { scope: string[]; strategies?: string[] }

设置为 false 以使路由公开。传递一个对象以定义认证范围,并可选择自定义认证策略。

🌐 Set to false to make the route public. Pass an object to define the auth scope and, optionally, custom auth strategies.

在运行时,当 auth 是对象时,必须存在 scope

🌐 At runtime, scope must be present when auth is an object.

Note

对于字符串处理器(例如,handler: 'article.find'),Strapi 会自动注入一个默认的 config.auth.scope 值,因此像 auth: {} 这样的模式仍然可以工作。

🌐 For string handlers (for example, handler: 'article.find'), Strapi auto-injects a default config.auth.scope value, so patterns such as auth: {} can still work.

对于非字符串处理器(内联函数),不要假设自动作用域注入。当 auth 是对象时,必须显式定义 config.auth.scope

🌐 For non-string handlers (inline functions), do not assume auto-scope injection. Define config.auth.scope explicitly when auth is an object.

Caution

在管理员路由上设置 auth: false 几乎从来不是故意的:它会使该端点暴露给未认证的请求。

🌐 Setting auth: false on an admin route is almost never intentional: it exposes the endpoint to unauthenticated requests.

General backend customization examples

有关包含策略、公共路由、动态 URL 参数和路径中正则表达式的配置示例,请参见 Routes

🌐 For configuration examples including policies, public routes, dynamic URL parameters, and regular expressions in paths, see Routes.

最佳实践

🌐 Best practices

  • 在同时公开管理和内容 API 端点时,请使用命名路由格式。 这样可以明确每个路由的意图,避免依赖可能令人意外的 type 默认值。
  • 保持 handler 为字符串。 字符串处理程序会自动生成授权范围,而函数处理程序不会。除非你设置了 config.auth: false,否则身份验证仍会针对字符串和函数处理程序运行,但只有字符串处理程序会自动获得 config.auth.scope。如果你使用函数处理程序并且需要路由级权限范围,请显式定义 config.auth.scope
  • 将策略的作用范围限定到其命名空间。 在路由中引用插件策略时,请使用完整的 plugin::my-plugin.policy-name 形式。如果应用中其他地方存在同名的短名策略,这可以避免歧义。
  • 不要在管理路由上禁用身份验证。 管理路由默认需要管理员身份验证。在管理路由上禁用身份验证会使其暴露给未经过身份验证的请求,这几乎从来都不是有意为之。
  • 将相关的路由分组到专用文件中。 随着插件的增长,单个路由索引文件变得难以导航。按资源拆分(例如,routes/article.jsroutes/comment.js),并从 routes/index.js 重新导出。