路由 Routes

Strapi 路由处理对您的内容的请求,并根据您的内容类型自动生成。路由可以根据您的需求进行定制。

通过任何 URL 发送到 Strapi 的请求都由路由处理。默认情况下,Strapi 会为所有内容类型生成路由(请参阅 REST API 文档)。可以 添加 和配置路由:

  • 使用 策略,这是一种阻止访问路由的方法,
  • 以及使用 中间件,这是一种控制和更改请求流和请求本身的方法。

一旦路由存在,到达该路由就会执行由控制器处理的一些代码(请参阅 控制器文档)。要查看所有现有路由及其层次顺序,您可以运行 yarn strapi routes:list(请参阅 CLI 参考)。

简化的 Strapi 后端图,其中突出显示了路由 该图表示请求如何通过 Strapi 后端的简化版本,其中突出显示了路由。后端定制介绍页面包含一个完整的交互式图表

实施

实施新路由包括在 ./src/api/[apiName]/routes 文件夹内的路由器文件中定义它(参见项目结构)。

根据使用情况,有两种不同的路由器文件结构:

配置核心路由器

核心路由器(即 findfindOnecreateupdatedelete)对应于 Strapi 在创建新 内容类型 时自动创建的 默认路由

Strapi 提供了一个 createCoreRouter 工厂函数,可自动生成核心路由器并允许:

核心路由器文件是一个 JavaScript 文件,它使用以下参数导出对“createCoreRouter”的调用结果:

参数说明类型
prefix允许传入自定义前缀以添加到此模型的所有路由器(例如 /testString
only仅会加载的核心路由

此数组中不包含的任何内容都将被忽略。
Array
except不应加载的核心路由

这在功能上与 only 参数相反。
Array
config用于处理路由的 策略中间件公共可用性 的配置Object
js
JavaScript
js
// ./src/api/[apiName]/routes/[routerName].js
// e.g './src/api/restaurant/routes/restaurant.js'
const { createCoreRouter } = require('@strapi/strapi').factories

module.exports = createCoreRouter('api::restaurant.restaurant', {
  prefix: '',
  only: ['find', 'findOne'],
  except: [],
  config: {
    find: {
      auth: false,
      policies: [],
      middlewares: [],
    },
    findOne: {},
    create: {},
    update: {},
    delete: {},
  },
})

通用实现示例:

js
JavaScript
js
// ./src/api/restaurant/routes/restaurant.js
const { createCoreRouter } = require('@strapi/strapi').factories

module.exports = createCoreRouter('api::restaurant.restaurant', {
  only: ['find'],
  config: {
    find: {
      auth: false,
      policies: [],
      middlewares: [],
    }
  }
})

这仅允许从核心“find”控制器对“/restaurants”路径发出“GET”请求,无需身份验证。

要查看自定义路由的可能用法,请阅读后端自定义示例手册的routes页面。

创建自定义路由器

创建自定义路由器包括创建一个导出对象数组的文件,每个对象都是具有以下参数的路由:

参数说明类型
method与路由关联的方法(即“GET”、“POST”、“PUT”、“DELETE”或“PATCH”)String
path要到达的路径,以正斜杠开头(例如 /articlesString
handler到达路由时执行的函数。
应遵循以下语法:<controllerName>.<actionName>
String
config

可选
用于处理路由的策略中间件公共可用性的配置

Object

可以使用参数和正则表达式创建动态路由。这些参数将在 ctx.params 对象中公开。有关更多详细信息,请参阅 PathToRegex 文档。

路由文件按字母顺序加载。要在核心路由之前加载自定义路由,请确保适当地命名自定义路由(例如 01-custom-routes.js02-core-routes.js)。

使用 URL 参数和正则表达式进行路由的自定义路由器示例

在下面的示例中,自定义路由文件名以 01- 为前缀,以确保在核心路由之前到达该路由。

js
JavaScript
js
// ./src/api/restaurant/routes/01-custom-restaurant.js
module.exports = {
  routes: [
    { // 使用 URL 参数定义的路径
      method: 'POST',
      path: '/restaurants/:id/review',
      handler: 'restaurant.review',
    },
    { // 使用正则表达式定义的路径
      method: 'GET',
      path: '/restaurants/:category([a-z]+)', // 仅当 URL 参数由小写字母组成时才匹配
      handler: 'restaurant.findByCategory',
    }
  ]
}

配置

核心路由器自定义路由器 具有相同的配置选项。路由配置在 config 对象中定义,可用于处理 策略中间件使路由公开

策略

策略 可以添加到路由配置中:

  • 通过指向 ./src/policies 中注册的策略,可以传递或不传递自定义配置
  • 或者直接声明策略实现,将其作为一个函数,该函数以 policyContext 为参数来扩展 Koa 的上下文 (ctx) 和 strapi 实例(参见 策略文档

Core router policy

js
JavaScript
js
// ./src/api/restaurant/routes/restaurant.js
const { createCoreRouter } = require('@strapi/strapi').factories

module.exports = createCoreRouter('api::restaurant.restaurant', {
  config: {
    find: {
      policies: [
        // 指向已注册的策略
        'policy-name',

        // 指向具有一些自定义配置的已注册策略
        { name: 'policy-name', config: {} },

        // 直接传递策略实现
        (policyContext, config, { strapi }) => {
          return true
        },
      ]
    }
  }
})

Custom router policy

js
JavaScript
js
// ./src/api/restaurant/routes/custom-restaurant.js
module.exports = {
  routes: [
    {
      method: 'GET',
      path: '/articles/customRoute',
      handler: 'api::api-name.controllerName.functionName', // 或针对插件特定控制器的“plugin::plugin-name.controllerName.functionName”
      config: {
        policies: [
          // 指向已注册的策略
          'policy-name',

          // 指向具有某些自定义配置的已注册策略
          { name: 'policy-name', config: {} },

          // 直接传递策略实现
          (policyContext, config, { strapi }) => {
            return true
          },
        ]
      },
    },
  ],
}

Middlewares

中间件 可以添加到路由配置中:

  • 通过指向 ./src/middlewares 中注册的中间件,可以传递或不传递自定义配置
  • 或者直接声明中间件实现,将其作为以 Koa 的上下文 (ctx) 和 strapi 实例为参数的函数:

Core router middleware

js
JavaScript
js
// ./src/api/restaurant/routes/restaurant.js
const { createCoreRouter } = require('@strapi/strapi').factories

module.exports = createCoreRouter('api::restaurant.restaurant', {
  config: {
    find: {
      middlewares: [
        // 指向已注册的中间件
        'middleware-name',

        // 指向具有一些自定义配置的已注册中间件
        { name: 'middleware-name', config: {} },

        // 直接传递中间件实现
        (ctx, next) => {
          return next()
        },
      ]
    }
  }
})

Custom router middleware

js
JavaScript
js
// ./src/api/restaurant/routes/custom-restaurant.js
module.exports = {
  routes: [
    {
      method: 'GET',
      path: '/articles/customRoute',
      handler: 'api::api-name.controllerName.functionName', // 或针对插件特定控制器的“plugin::plugin-name.controllerName.functionName”
      config: {
        middlewares: [
          // 指向已注册的中间件
          'middleware-name',

          // 指向具有某些自定义配置的已注册中间件
          { name: 'middleware-name', config: {} },

          // 直接传递中间件实现
          (ctx, next) => {
            return next()
          },
        ],
      },
    },
  ],
}

Public routes

默认情况下,路由受 Strapi 身份验证系统的保护,该系统基于 API 令牌 或使用 用户和权限插件

在某些情况下,公开路由并控制正常 Strapi 身份验证系统之外的访问会很有用。这可以通过将路由的 auth 配置参数设置为 false 来实现:

具有公共路由的核心路由器

js
JavaScript
js
// ./src/api/restaurant/routes/restaurant.js
const { createCoreRouter } = require('@strapi/strapi').factories

module.exports = createCoreRouter('api::restaurant.restaurant', {
  config: {
    find: {
      auth: false
    }
  }
})

具有公共路由的自定义路由器

js
JavaScript
js
// ./src/api/restaurant/routes/custom-restaurant.js
module.exports = {
  routes: [
    {
      method: 'GET',
      path: '/articles/customRoute',
      handler: 'api::api-name.controllerName.functionName', // 或 'plugin::plugin-name.controllerName.functionName' 用于插件特定的控制器
      config: {
        auth: false,
      },
    },
  ],
}