服务端 API:路由(Routes)
页面摘要: 服务端 API 从服务端入口文件导出一个
routes值来暴露插件端点。仅用于隐式 admin 路由时使用数组格式,使用命名路由器格式来分隔 admin 和 Content API 路由,或者在需要动态路由配置时使用工厂回调格式。
路由暴露你插件的 HTTP 端点,并将传入请求映射到控制器操作。它们作为 routes 值从 服务端入口文件 导出。
在深入阅读本页概念之前,请确保你已经:
- 创建了一个 Strapi 插件,
- 阅读并理解了 Server API 的基础知识。
路由声明格式
数组格式
数组格式是最基础的格式:它直接导出一个路由对象数组。Strapi 默认将这些对象注册为 admin 路由,并以插件名作为前缀。
要暴露 Content API 路由,请使用带有 type: 'content-api' 的 命名路由器格式。
JavaScript
'use strict';
module.exports = [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
policies: [],
},
},
{
method: 'POST',
path: '/articles',
handler: 'article.create',
config: {
policies: [],
},
},
];
TypeScript
export default [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
policies: [],
},
},
{
method: 'POST',
path: '/articles',
handler: 'article.create',
config: {
policies: [],
},
},
];
命名路由器格式
使用命名路由器格式时,使用一个带有具名键(admin、content-api 或任何自定义名称)的对象来声明独立的路由器组。每个组是一个带有 type、可选 prefix 和 routes 数组的路由器对象。当你的插件同时暴露 admin 和 Content API 路由时,请使用此格式。
JavaScript
'use strict';
const adminRoutes = require('./admin');
const contentApiRoutes = require('./content-api');
module.exports = {
// highlight-start
admin: adminRoutes,
'content-api': contentApiRoutes,
// highlight-end
};
'use strict';
module.exports = {
type: 'admin',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
],
};
'use strict';
module.exports = {
type: 'content-api',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
policies: [],
},
},
],
};
TypeScript
import adminRoutes from './admin';
import contentApiRoutes from './content-api';
export default {
// highlight-start
admin: adminRoutes,
'content-api': contentApiRoutes,
// highlight-end
};
export default {
type: 'admin' as const,
routes: [
{
method: 'GET' as const,
path: '/articles',
handler: 'article.find',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
],
};
export default {
type: 'content-api' as const,
routes: [
{
method: 'GET' as const,
path: '/articles',
handler: 'article.find',
config: {
policies: [],
},
},
],
};
工厂回调格式
对于需要在路由配置时访问 strapi 实例的高级场景(例如,构建动态路径,或根据配置有条件地包含路由),可以导出一个工厂回调。
工厂回调必须附加到具名路由条目(例如 admin 或 content-api),而不能作为 routes/index 的根导出。
在根级别使用 module.exports = ({ strapi }) => ({ ... }) 不是有效的格式。
JavaScript
'use strict';
module.exports = {
'content-api': ({ strapi }) => ({
type: 'content-api',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
// highlight-next-line
auth: strapi.plugin('my-plugin').config('publicRead') ? false : {},
},
},
],
}),
};
TypeScript
import type { Core } from '@strapi/strapi';
const routes: Record<
string,
Core.RouterConfig | ((args: { strapi: Core.Strapi }) => Core.RouterConfig)
> = {
'content-api': ({ strapi }) => ({
type: 'content-api',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
// highlight-next-line
auth: strapi.plugin('my-plugin').config('publicRead') ? false : {},
},
},
],
}),
};
export default routes;
有关 Strapi 在注册时自动添加的内容的详细信息,请参阅 Strapi 应用的默认值。
Strapi 应用的默认值
当 Strapi 注册插件路由时,它会自动应用以下默认值:
| Property | Default value | Notes |
|---|---|---|
type | 'admin' | 在使用数组格式时应用,或在命名格式中路由器对象省略 type 时应用 |
prefix | '/<plugin-name>' | 在使用数组格式时应用,或在路由器对象省略 prefix 时应用 |
config.auth.scope | ['plugin::<plugin-name>.<handler>'] | 仅为字符串 handler 自动生成,使用 defaultsDeep,因此现有值不会被覆盖 |
以下 2 种声明是等价的。Strapi 会自动应用上表中的默认值:
JavaScript
module.exports = [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
},
];
module.exports = {
admin: {
type: 'admin',
prefix: '/my-plugin',
routes: [
{
method: 'GET',
path: '/articles',
handler: 'article.find',
config: {
auth: {
// highlight-next-line
scope: ['plugin::my-plugin.article.find'], // auto-generated from handler string
},
},
},
],
},
};
TypeScript
export default [
{
method: 'GET' as const,
path: '/articles',
handler: 'article.find',
},
];
export default {
admin: {
type: 'admin' as const,
prefix: '/my-plugin',
routes: [
{
method: 'GET' as const,
path: '/articles',
handler: 'article.find',
config: {
auth: {
// highlight-next-line
scope: ['plugin::my-plugin.article.find'], // auto-generated from handler string
},
},
},
],
},
};
路由配置参考
每个路由接受一个具有以下属性的可选 config 对象:
policies
类型: Array<string | PolicyHandler | { name: string; options?: object }>
在控制器操作之前运行的策略。每个条目可以是策略名称字符串、内联函数,或带有必需 name 和可选 options 的对象。
options 对象按原样传递给策略函数的第二个参数(策略签名中的 config)。该对象的形态取决于策略。
插件策略引用为 plugin::my-plugin.policy-name。
middlewares
类型: Array<string | MiddlewareHandler | { name: string; options?: object }>
应用于此路由的中间件。每个条目是中间件名称字符串、内联函数,或具有如下属性的对象:
name:已注册的中间件名称,options(可选):中间件选项。
在路由验证时,Strapi 对中间件/策略对象验证 { name: string; options?: object } 形态(参见 services/server/routing.ts)。
中间件解析器(services/server/middleware.ts)仍然包含对 { resolve, config } 对象的运行时支持,但对于标准插件路由声明,该形态会在解析前被路由验证拒绝。
为与验证兼容,请在路由配置中使用 { name, options }。
auth
类型: false | { scope: string[]; strategies?: string[] }
设为 false 以使路由公开。传入一个对象以定义 auth 范围,并可选择自定义 auth 策略。
在运行时,当 auth 是一个对象时,scope 必须存在。
对于 字符串 handler(例如 handler: 'article.find'),Strapi 会自动注入默认的 config.auth.scope 值,因此诸如 auth: {} 这样的模式仍然可以工作。
对于 非字符串 handler(内联函数),请勿假设会自动注入 scope。当 auth 是对象时,请显式定义 config.auth.scope。
在 admin 路由上设置 auth: false 几乎从来都不是有意为之:它会将端点暴露给未经验证的请求。
有关包含策略、公开路由、动态 URL 参数以及路径中的正则表达式的配置示例,请参阅 Routes。
最佳实践
-
当同时暴露 admin 和 Content API 端点时,使用命名路由器格式。 它使每个路由的意图明确,并避免依赖可能令人意外的
type默认值。 -
保持
handler为字符串。 字符串 handler 会自动生成 auth 范围,函数 handler 则不会。除非设置config.auth: false,否则身份验证对字符串和函数 handler 都会运行,但只有字符串 handler 会获得自动的config.auth.scope。如果你使用函数 handler 并需要路由级权限范围,请显式定义config.auth.scope。 -
将策略作用域限定在其命名空间内。 在路由中引用插件策略时,请使用完整的
plugin::my-plugin.policy-name形式。这可以避免如果应用程序其他地方存在相同短名称的策略时产生歧义。 -
不要在 admin 路由上禁用 auth。 admin 路由默认需要 admin 身份验证。在 admin 路由上禁用 auth 会将其暴露给未经验证的请求,这几乎从来都不是有意为之。
-
将相关路由分组在专用文件中。 随着插件增长,单个路由 index 文件会变得难以浏览。按资源拆分(例如
routes/article.js、routes/comment.js)并从routes/index.js重新导出。