# Account billing details
Source: https://docs.strapi.io/cloud/account/account-billing
# Account billing & invoices
Through the *Profile* page, accessible by clicking on your profile picture on the top right hand corner of the interface then clicking on **Profile**, you can access the [ *Billing*](#account-billing) and [ *Invoices*](#account-invoices) tabs.
## Account billing
The *Billing* tab displays and enables you to modify the billing details and payment method set for the account.
The *Payment method* section of the *Billing* tab allows you to manage the credit cards that can be used for the Strapi Cloud projects. The *Billing details* section requires to be filled in, at least for the mandatory fields, as this information will be the default billing details for all Strapi Cloud projects related to your account.
### Adding a new credit card
1. In the *Payment method* section of the *Billing* tab, click on the **Add card** button.
2. Fill in the following fields:
| Field name | Description |
| --- | --- |
| Card Number | Write the number of the credit card to add as payment method. |
| Expires | Write the expiration date of the credit card. |
| CVC | Write the 3-numbers code displayed at the back of the credit card. |
3. Click on the **Save** button.
:::tip
The first credit card to be added as payment method for the account will by default be the primary one. It is however possible to define another credit card as primary by clicking on the icon, then **Switch as primary**.
:::
### Deleting a credit card
To remove a credit card from the list of payment methods for the account:
1. Click on the icon of the credit card you wish to delete.
2. Click **Remove card**. The card is immediately deleted.
:::note
You cannot delete the primary card as at least one credit card must be available as payment method, and the primary card is by default that one. If the credit card you wish to delete is currently the primary card, you must first define another credit card as primary, then delete it.
:::
## Account invoices
The *Invoices* tab displays the complete list of invoices for all your Strapi Cloud projects.
:::strapi Invoices are also available per project.
In the *Settings > Invoices* tab of any project, you will find the invoices for that project only. Feel free to check the [dedicated documentation](/cloud/projects/settings#invoices).
:::
# Profile settings
Source: https://docs.strapi.io/cloud/account/account-settings
# Profile settings
The *Profile* page enables you to manage your account details and preferences. It is accessible by clicking on your profile picture, on the top right hand corner of the interface, and **Profile**.
There are 3 tabs available in the *Profile* interface: [*General*](#general), *Billing* and Invoices (the last 2 are documented in the [Account billing details](/cloud/account/account-billing) section of this documentation).
## General
The *General* tab enables you to edit the following details for your account profile:
- Details: to see the name associated with your account.
- Connected accounts: to manage Google, GitHub, GitLab and email accounts connected with your Strapi Cloud account (see [Managing connected accounts](#managing-connected-accounts)).
- Delete account: to permanently delete your Strapi Cloud account (see [Deleting Strapi Cloud account](#deleting-strapi-cloud-account)).
### Managing connected accounts
You can connect a Google, GitLab, GitHub and email account to your Strapi Cloud account. The _Connected accounts_ section lists accounts that are currently connected to your Strapi Cloud account. From there you can also connect a new Google, GitLab, GitHub and email account if one is not already connected.
To connect a new Google, GitLab, GitHub or email account to your Strapi Cloud account, click on the **Connect account** button and follow the next steps on the corresponding website.
You can also click on the three dots button of a connected account and click on the "Manage on" button to manage your GitHub, GitLab or Google account directly on the corresponding website.
### Deleting Strapi Cloud account
You can delete your Strapi Cloud account, but it will be permanent and irreversible. All associated projects and their data will be deleted as well and the subscriptions for the projects will automatically be canceled.
1. In the *Delete account* section of the *General* tab, click on the **Delete account** button.
2. In the dialog, type `DELETE` in the textbox.
3. Confirm the deletion of your account by clicking on the **Delete** button.
# Database
Source: https://docs.strapi.io/cloud/advanced/database
# Database
Strapi Cloud provides a pre-configured PostgreSQL database by default. However, you can also configure it to utilize an external SQL database, if needed.
:::prerequisites
- A local Strapi project running on `v4.8.2+`.
- Credentials for an external database.
- If using an existing database, the schema must match the Strapi project schema.
:::
:::caution
While it's possible to use an external database with Strapi Cloud, you should do it while keeping in mind the following considerations:
- Strapi Cloud already provides a managed database that is optimized for Strapi.
- Using an external database may result in unexpected behavior and/or performance issues (e.g., network latency may impact performance). For performance reasons, it's recommended to host your external database close to the region where your Strapi Cloud project is hosted. You can find where your Strapi Cloud project is hosted in your Project Settings (see [Project Settings > General > Selected Region](/cloud/projects/settings#general)).
- Strapi can't provide security or support with external databases used with Strapi Cloud.
:::
:::warning
Any environment variable added to your project that starts with `DATABASE_` will cause Strapi Cloud to assume that you will be using an external database and all Strapi Cloud specific database variables will not be injected!
:::
## Configuration
The project `./config/database.js` or `./config/database.ts` file must match the configuration found in the [environment variables in database configurations](https://docs.strapi.io/cms/configurations/database#environment-variables-in-database-configurations) section.
Before pushing changes, add environment variables to the Strapi Cloud project:
1. Log into Strapi Cloud and click on the corresponding project on the Projects page.
2. Click on the **Settings** tab and choose **Variables** in the left menu.
3. Add the following environment variables:
| Variable | Value | Details |
| ---------------------------------- | ---------------- |----------|
| `DATABASE_CLIENT` | your_db | Should be one of `mysql`, `postgres`, or `sqlite`. |
| `DATABASE_HOST` | your_db_host | The URL or IP address of your database host |
| `DATABASE_PORT` | your_db_port | The port to access your database |
| `DATABASE_NAME` | your_db_name | The name of your database |
| `DATABASE_USERNAME` | your_db_username | The username to access your database |
| `DATABASE_PASSWORD` | your_db_password | The password associated to this username |
| `DATABASE_SSL_REJECT_UNAUTHORIZED` | false | Whether unauthorized connections should be rejected |
| `DATABASE_SCHEMA` | public | - |
4. Click **Save**.
:::caution
To ensure a smooth deployment, it is recommended to not change the names of the environment variables.
:::
## Deployment
To deploy the project and utilize the external database, push the changes from earlier. This will trigger a rebuild and new deployment of the Strapi Cloud project.
Once the application finishes building, the project will use the external database.
## Reverting to the default database
To revert back to the default database, remove the previously added environment variables related to the external database from the Strapi Cloud project dashboard, and save. For the changes to take effect, you must redeploy the Strapi Cloud project.
# Email Provider
Source: https://docs.strapi.io/cloud/advanced/email
# Email Provider
Strapi Cloud comes with a basic email provider out of the box. However, it can also be configured to utilize another email provider, if needed.
:::caution
Please be advised that Strapi is unable to provide support for third-party email providers.
:::
:::prerequisites
- A local Strapi project running on `v4.8.2+`.
- Credentials for another email provider (see
:::caution
The file structure must match the above path exactly, or the configuration will not be applied to Strapi Cloud.
:::
Each provider will have different configuration settings available. Review the respective entry for that provider in the
:::tip
Before pushing the above changes to GitHub, add environment variables to the Strapi Cloud project to prevent triggering a rebuild and new deployment of the project before the changes are complete.
:::
### Strapi Cloud Configuration
1. Log into Strapi Cloud and click on the corresponding project on the Projects page.
2. Click on the **Settings** tab and choose **Variables** in the left menu.
3. Add the required environment variables specific to the email provider.
4. Click **Save**.
**Example:**
## Deployment
To deploy the project and utilize another party email provider, push the changes from earlier. This will trigger a rebuild and new deployment of the Strapi Cloud project.
Once the application finishes building, the project will use the new email provider.
:::strapi Custom Provider
If you want to create a custom email provider, please refer to the [Email providers](/cms/features/email#providers) documentation in the CMS Documentation.
:::
# Upload Provider
Source: https://docs.strapi.io/cloud/advanced/upload
# Upload Provider
Strapi Cloud comes with a local upload provider out of the box. However, it can also be configured to utilize a third-party upload provider, if needed.
:::caution
Please be advised that Strapi is unable to provide support for third-party upload providers.
:::
:::prerequisites
- A local Strapi project running on `v4.8.2+`.
- Credentials for a third-party upload provider (see
:::caution
The file structure must match the above path exactly, or the configuration will not be applied to Strapi Cloud.
:::
Each provider will have different configuration settings available. Review the respective entry for that provider in the
### Configure the Security Middleware
Due to the default settings in the Strapi Security Middleware you will need to modify the `contentSecurityPolicy` settings to properly see thumbnail previews in the Media Library.
To do this in your Strapi project:
1. Navigate to `./config/middleware.js` or `./config/middleware.ts` in your Strapi project.
2. Replace the default `strapi::security` string with the object provided by the upload provider.
**Example:**
:::tip
Before pushing the above changes to GitHub, add environment variables to the Strapi Cloud project to prevent triggering a rebuild and new deployment of the project before the changes are complete.
:::
### Strapi Cloud Configuration
1. Log into Strapi Cloud and click on the corresponding project on the Projects page.
2. Click on the **Settings** tab and choose **Variables** in the left menu.
3. Add the required environment variables specific to the upload provider.
4. Click **Save**.
**Example:**
## Deployment
To deploy the project and utilize the third-party upload provider, push the changes from earlier. This will trigger a rebuild and new deployment of the Strapi Cloud project.
Once the application finishes building, the project will use the new upload provider.
:::strapi Custom Provider
If you want to create a custom upload provider, please refer to the [Providers](/cms/features/media-library#providers) documentation in the CMS Documentation.
:::
# Command Line Interface (CLI)
Source: https://docs.strapi.io/cloud/cli/cloud-cli
# Command Line Interface (CLI)
Strapi Cloud comes with a Command Line Interface (CLI) which allows you to log in and out, and to deploy a local project without it having to be hosted on a remote git repository. The CLI works with both the `yarn` and `npm` package managers.
:::note
It is recommended to install Strapi locally only, which requires prefixing all of the following `strapi` commands with the package manager used for the project setup (e.g `npm run strapi help` or `yarn strapi help`) or a dedicated node package executor (e.g. `npx strapi help`).
:::
## strapi login
**Alias:** `strapi cloud:login`
Log in Strapi Cloud.
```bash
strapi login
```
This command automatically opens a browser window to first ask you to confirm that the codes displayed in both the browser window and the terminal are the same. Then you will be able to log into Strapi Cloud via Google, GitHub or GitLab. Once the browser window confirms successful login, it can be safely closed.
If the browser window doesn't automatically open, the terminal will display a clickable link as well as the code to enter manually.
## strapi deploy
**Alias:** `strapi cloud:deploy`
Deploy a new local project (< 100MB) in Strapi Cloud.
```bash
strapi deploy
```
This command must be used after the `login` one. It deploys a local Strapi project on Strapi Cloud, without having to host it on a remote git repository beforehand. The terminal will inform you when the project is successfully deployed on Strapi Cloud.
Deploying a Strapi project through the CLI creates a project on the Free plan.
Once the project is first deployed on Strapi Cloud with the CLI, the `deploy` command can be reused to trigger a new deployment of the same project.
:::note
Once you deployed your project, if you visit the Strapi Cloud dashboard, you may see some limitations as well as impacts due to creating a Strapi Cloud project that is not in a remote repository and which was deployed with the CLI.
- Some areas in the dashboard that are usually reserved to display information about the git provider will be blank.
- Some buttons, such as the **Trigger deploy** button, will be greyed out and unclickable since, unless you have [connected a git repository to your Strapi Cloud project](/cloud/getting-started/deployment-cli#automatically-deploying-subsequent-changes).
:::
## strapi link
**Alias:** `strapi cloud:link`
Links project in the current folder to an existing project in Strapi Cloud.
```bash
strapi link
```
This command connects your local project in the current directory with an existing project on your Strapi Cloud account. You will be prompted to select the project you wish to link from a list of available projects hosted on Strapi Cloud.
## strapi projects
**Alias:** `strapi cloud:projects`
Lists all Strapi Cloud projects associated with your account.
```bash
strapi projects
```
This command retrieves and displays a list of all projects hosted on your Strapi Cloud account.
## strapi logout
**Alias:** `strapi cloud:logout`
Log out of Strapi Cloud.
```bash
strapi logout
```
This command logs you out of Strapi Cloud. Once the `logout` command is run, a browser page will open and the terminal will display a confirmation message that you were successfully logged out. You will not be able to use the `deploy` command anymore.
# Caching & Performance
Source: https://docs.strapi.io/cloud/getting-started/caching
# Caching & Performance
For Strapi Cloud applications with large amounts of cacheable content, such as images, videos, and other static assets, enabling CDN (Content Delivery Network) caching via the
# Strapi Cloud fundamentals
Source: https://docs.strapi.io/cloud/getting-started/cloud-fundamentals
# Strapi Cloud fundamentals
Before going any further into this Strapi Cloud documentation, we recommend you to acknowledge the main concepts below. They will help you to understand how Strapi Cloud works, and ensure a smooth Strapi Cloud experience.
- **Hosting Platform** Strapi Cloud is a hosting platform that allows to deploy already existing Strapi projects created with Strapi CMS (Content Management System). Strapi Cloud is *not* the SaaS () version of Strapi CMS and should rather be considered as a PaaS (). Feel free to refer to the [CMS documentation](https://docs.strapi.io/cms/intro) to learn more about Strapi CMS.
- **Strapi Cloud Pricing Plans** As a Strapi Cloud user you have the choice between 4 plans: Free, Essential, Pro and Scale. Depending on the plan, you have access to different functionalities, support and customization options (see [Pricing page](https://strapi.io/pricing-cloud) for more details). In this Strapi Cloud documentation, the , , and badges can be displayed below a section's title to indicate that the feature is only available starting from the corresponding paid plan. If no badge is shown, the feature is available on the Free plan.
- **Types of Strapi Cloud users** There can be 2 types of users on a Strapi Cloud project: owners and maintainers. The owner is the one who has created the project and has therefore access to all features and options for the project. Maintainers are users who have been invited to contribute to an already created project by its owner. Maintainers, as documented in the [Collaboration](/cloud/projects/collaboration) page, cannot view and access all features and options from the Strapi Cloud dashboard.
- **Support** The level of support provided by the Strapi Support team depends on the Strapi Cloud plan you subscribed for. The Free plan does not include access to support. The Essential and Pro plans include Basic support while the Scale plan includes Standard support. Please refer to the [dedicated support article](https://support.strapi.io/support/solutions/articles/67000680833-what-is-supported-by-the-strapi-team#Not-Supported) for all details regarding support levels.
- **API access in Strapi Cloud vs self-hosted** The REST and GraphQL APIs behave the same on Strapi Cloud and on self-hosted servers. The only differences are the URLs:
- Base API domain: On Strapi Cloud, your API uses the domain of the environment (e.g. `https://.strapiapp.com/api/...`), or your custom domain if you set one (see [Domains documentation](/cloud/projects/settings#domains)). A self-hosted project would use whatever domain you expose.
- Media Library URLs: Media fields in REST and GraphQL responses from Strapi Cloud always use the project media domain (e.g. `.media.strapiapp.com`), even when you access the API through a custom domain. Self-hosted projects return URLs from the configured upload provider, so the domain can match your own site or CDN. When you move a project from self-hosted to Strapi Cloud, make sure your frontend reads the absolute URLs returned by the API or accepts the Strapi Cloud media domain.
# Strapi Cloud - Dashboard deployment
Source: https://docs.strapi.io/cloud/getting-started/deployment
# Project deployment with the Cloud dashboard
This is a step-by-step guide for deploying your project on Strapi Cloud for the first time, using the Cloud dashboard.
:::prerequisites
Before you can deploy your Strapi application on Strapi Cloud using the Cloud dashboard, you need to have the following prerequisites:
* Strapi version `4.8.2` or higher
* Project database must be compatible with PostgreSQL. Strapi does not support and does not recommend using any external databases, though it's possible to configure one (see [advanced database configuration](/cloud/advanced/database)).
* Project source code hosted on
5. Set up your Strapi Cloud project.
5.a. Fill in the following information:
| Setting name | Instructions |
|--------------|---------------------------------------------------------------------------------------------------------|
| Display name | Write the name of your Strapi app, this is fetched from the repository name but can be edited. It is automatically converted to slug format (`my-strapi-app`). |
| Git branch | Choose from the drop-down the branch you want to deploy. |
| Deploy on push | Tick this box to automatically trigger a deployment when changes are pushed to your selected branch. When disabled, you will need to manually deploy the latest changes. |
| Region | Choose the geographic location of the servers where your Strapi application is hosted. Selected region can either be US (East), Europe (West), Asia (Southeast) or Oceania. |
:::note
The Git branch and "Deploy on push" settings can be modified afterwards through the project's settings, however the hosting region can only be chosen during the creation of the project (see [Project Settings](/cloud/projects/settings)).
:::
5.b. (optional) Click on **Show advanced settings** to fill in the following options:
| Setting name | Instructions |
|--------------|---------------------------------------------------------------------------------------------------------|
| Base directory | Write the name of the directory where your Strapi app is located in the repository. This is useful if you have multiple Strapi apps in the same repository or if you have a monorepo. |
| Environment variables | Click on **Add variable** to add environment variables used to configure your Strapi app (see [Environment variables](/cms/configurations/environment/) for more information). You can also add environment variables to your Strapi application by adding a `.env` file to the root of your Strapi app directory. The environment variables defined in the `.env` file will be used by Strapi Cloud. |
| Node version | Choose a Node version from the drop-down. The default Node version will automatically be chosen to best match the version of your Strapi project. If you manually choose a version that doesn't match with your Strapi project, the build will fail but the explanation will be displayed in the build logs. |
:::strapi Using Environment Variables
You can use environment variable to connect your project to an external database rather than the default one used by Strapi Cloud (see [database configuration](/cms/configurations/database#environment-variables-in-database-configurations) for more details). If you would like to revert and use Strapi's default database again, you have to remove your `DATABASE_` environment variables (no automatic migration implied).
You can also set up here a custom email provider. Sendgrid is set as the default one for the Strapi applications hosted on Strapi Cloud (see [providers configuration](/cms/features/email#providers) for more details).
:::
## Setting up billing details
:::strapi No billing step for the Free plan
If you chose the free plan, this billing step will be skipped as you will not be asked to share your credit card details at the creation of the project.
To upgrade your project to a paid plan, you will need to fill in your billing information in the **Billing** section of your Profile.
Skip to step 5 of the section below to finalize the creation of your project.
:::
1. Click on the **Continue to billing** button. You will directly be redirected to the second and final project deployment interface. There you can review all your new project setup information, enter payment & billing details and receive your invoice.
2. Review your project: make sure the plan and setup information are correct. If needed, click the **Edit** button to navigate back to the first step of the project creation and fix any mistake.
3. In the Payment section, fill in at least all mandatory elements for *Payment method* and *Billing information*.
4. Check your invoice which informs you of what should be paid now and the following month. Optionally, you can enter a *Discount code* if you have one.
5. Click on the **Create project** button to finalize the creation of your new Strapi Cloud project.
## Deploying your project
After confirming the project creation, you will be redirected to your *Project dashboard* where you will be able to follow its creation and first deployment.
While your project is deploying, you can already start configuring some of your [project settings](/cloud/projects/settings).
:::note
If an error occurs during the project creation, the progress indicator will stop and display an error message. You will see a **Retry** button next to the failed step, allowing you to restart the creation process.
:::
Once you project is successfully deployed, the creation tracker will be replaced by your deployments list and you will be able to visit your Cloud hosted project. Don't forget to create the first Admin user before sharing your Strapi project.
## What to do next?
Now that you have deployed your project via the Cloud dashboard, we encourage you to explore the following ideas to have an even more complete Strapi Cloud experience:
- Invite other users to [collaborate on your project](/cloud/projects/collaboration).
- Check out the [deployments management documentation](/cloud/projects/deploys) to learn how to trigger new deployments for your project.
# Strapi Cloud - CLI deployment
Source: https://docs.strapi.io/cloud/getting-started/deployment-cli
# Project deployment with the Command Line Interface (CLI)
This is a step-by-step guide for deploying your project on Strapi Cloud for the first time, using the Command Line Interface.
:::prerequisites
Before you can deploy your Strapi application on Strapi Cloud using the Command Line Interface, you need to have the following prerequisites:
- Have a Google, GitHub or GitLab account.
- Have an already created Strapi project (see [Installing from CLI in the CMS Documentation](/cms/installation/cli)), stored locally. The project must be less than 100MB.
- Have available storage in your hard drive where the temporary folder of your operating system is stored.
:::
## Logging in to Strapi Cloud
1. Open your terminal.
2. Navigate to the folder of your Strapi project, stored locally on your computer.
3. Enter the following command to log into Strapi Cloud:
4. In the browser window that opens automatically, confirm that the code displayed is the same as the one written in the terminal message.
5. Still in the browser window, choose whether to login via Google, GitHub or GitLab. The window should confirm the successful login soon after.
## Deploying your project
1. From your terminal, still from the folder of your Strapi project, enter the following command to deploy the project:
2. Follow the progression bar in the terminal until confirmation that the project was successfully deployed with Strapi Cloud.
Deploying the project will create a new Strapi Cloud project on the Free plan.
### Automatically deploying subsequent changes
By default, when creating and deploying a project with the Cloud CLI, you need to manually deploy again all subsequent changes by running the corresponding `deploy` command everytime you make a change.
Another option is to enable automatic deployment through a git repository. To do so:
1. Host your code on a git repository, such as or .
2. Connect your Strapi Cloud project to the repository (see the _Connected repository_ setting in [Projects Settings > General](/cloud/projects/settings#general)).
3. Still in _Projects Settings > General_ tab, tick the box for the "Deploy the project on every commit pushed to this branch" setting. From now on, a new deployment to Strapi Cloud will be triggered any time a commit is pushed to the connected git repository.
:::note
Automatic deployment is compatible with all other deployment methods, so once a git repository is connected, you can trigger a new deployment to Strapi Cloud [from the Cloud dashboard](/cloud/projects/deploys), [from the CLI](/cloud/cli/cloud-cli#strapi-deploy), or by pushing new commits to your connected repository.
:::
## ⏩ What to do next?
Now that you have deployed your project via the Command Line Interface, we encourage you to explore the following ideas to have an even more complete Strapi Cloud experience:
- Visit the Cloud dashboard to follow [insightful metrics and information](/cloud/projects/overview) on your Strapi project.
- Check out the full [Command Line Interface documentation](/cloud/cli/cloud-cli) to learn about the other commands available.
# Project deployment
Source: https://docs.strapi.io/cloud/getting-started/deployment-options
# Project deployment with Strapi Cloud
You have 2 options to deploy your project with Strapi Cloud:
- either with the user interface (UI), meaning that you will perform all the actions directly on the Strapi Cloud dashboard,
- or using the Cloud Comment Line Interface (CLI), meaning that you will only interact with a terminal.
The guides below will guide you through all the steps for each of the deployment options.
# Welcome to the Strapi Cloud Documentation!
Source: https://docs.strapi.io/cloud/getting-started/intro
# Welcome to the Strapi Cloud Documentation!
The Strapi Cloud documentation contains all information related to the setup, deployment, update and customization of your Strapi Cloud account and applications.
:::strapi What is Strapi Cloud?
built on top of Strapi, the open-source headless CMS.
:::
:::prerequisites
The typical workflow, which is recommended by the Strapi team, is:
1. Create your Strapi application locally (v4.8.2 or later).
2. Optionally, extend the application with plugins or custom code.
3. Version the application's codebase through your git provider (GitHub or GitLab).
4. Deploy the application with Strapi Cloud.
:::
The Strapi Cloud documentation is organised in topics in a order that should correspond to your journey with the product. The following cards, on which you can click, will redirect you to the main topics and steps.
:::strapi Welcome to the Strapi community!
Strapi Cloud is built on top of Strapi, an open-source, community-oriented project. The Strapi team has at heart to share their vision and build the future of Strapi with the Strapi community. This is why the is open: as all insights are very important and will help steer the project in the right direction. Any community member is most welcome to share ideas and opinions there.
You can also join , the , and the and benefit from the years of experience, knowledge, and contributions by the Strapi community as a whole.
:::
# Information on billing & usage
Source: https://docs.strapi.io/cloud/getting-started/usage-billing
# Information on billing & usage
This page contains general information related to the usage and billing of your Strapi Cloud account and projects.
Strapi Cloud offers 1 Free plan and 3 paid plans: Essential, Pro and Scale (see [Pricing page](https://strapi.io/pricing-cloud)). The table below summarizes Strapi Cloud usage-based pricing plans, for general features and usage:
| Feature | Free | Essential | Pro | Scale |
| -------------------------------- | ----- | --------- | --- | ----- |
| **Database Entries** | 500 | Unlimited* | Unlimited* | Unlimited* |
| **Asset Storage** | 10GB | 50GB | 250GB | 1,000GB |
| **Asset Bandwidth (per month)** | 10GB | 50GB | 500GB | 1,000GB |
| **API Requests (per month)** | 10,000 | 100,000 | 1,000,000 | 10,000,000 |
| | | | | |
| **Backups** | N/A | N/A | Weekly | Daily |
| **Custom domains** | N/A | Included | Included | Included |
| **Environments** | N/A | N/A | 0 included (up to 99 extra) | 1 included (up to 99 extra) |
| **Emails (per month)** | 100 | Unlimited* | Unlimited* | Unlimited* |
:::strapi Additional information on usage and features
- General features & usage:
- Database entries are the number of entries in your database.
- Asset storage is the amount of storage used by your assets.
- Asset bandwidth is the amount of bandwidth used by your assets.
- API requests are the number of requests made to your APIs. This includes requests to the GraphQL and REST APIs, excluding requests for file and media assets counted towards CDN bandwidth and storage.
- Cloud specific feature:
- Backups refers to the automatic backups of Strapi Cloud projects (see [Backups documentation](/cloud/projects/settings#backups) for more information on the feature).
- Custom domains refer to the ability to define a custom domain for your Strapi Cloud (see [Custom domains](/cloud/projects/settings#connecting-a-custom-domain)).
- Environments refers to the number of environments included in the plan on top of the default production environment (see [Environments](/cloud/projects/settings#environments) documentation for more information on the feature).
:::
:::caution The Free Plan is for personal, non-commercial use only
Commercial use means any project made for financial gain, including:
- Accepting or processing payments on your site
- Accepting or receiving payment to create, update, or host the site
- Advertising, promoting, or selling products or services
- Hosting or serving advertisements for any 3rd party
For more information, visit [Strapi Cloud-Legal](https://strapi.io/cloud-legal)
:::
:::info Scale-to-zero and cold start on the Free plan
On the Free plan, projects automatically scale down to zero after a short period of inactivity. When the application is accessed again—either through the frontend or via an API request—it may take a few seconds (up to a minute) before a response is returned.
Upgrading to a paid plan disables scaling to zero and cold starts, resulting in instant response times at all times.
:::
## Environments management
Environments are isolated instances of your Strapi Cloud project. All projects have a default production environment, but other additional environments can be configured for projects on a Pro or Scale plan, from the *Environments* tab of a project's settings (see [Environments](/cloud/projects/settings#environments)). There is no limit to the number of additional environments that can be configured for a Strapi Cloud project.
The usage limits of additional environments are the same as for the project's production environment (e.g. an additional environment on the Pro plan will be limited at 250GB for asset storage, and overages will be charged the same way as for the production environment). Note however that the asset bandwidth and API calls are project-based, not environment-based, so these usage limits do not change even with additional environments.
## Billing
Billing is based on the usage of your Strapi Cloud account and projects. You will be billed monthly for the usage of your account and applications. You can view your usage and billing information in the section of your Strapi Cloud account.
### Overages
:::caution
Overages are not allowed on the Free plan.
:::
If you exceed the limits of your plan for API Requests, Asset Bandwidth, or Asset Storage, you will be charged for the corresponding overages.
For example, if you exceed the 500GB limit in asset bandwidth of the Pro plan, you will be charged for the excess bandwidth at the end of the current billing period or on project deletion. Overages are not prorated and are charged in full.
Overages are charged according to the following rates:
| Feature | Rate |
| --- | --- |
| **API Requests** | $1.50 / 25k requests |
| **Asset Bandwidth** | $30.00 / 100GB |
| **Asset Storage** | $0.60 / GB per month |
### Project suspension
Projects may end up in a **Suspended** state for various reasons, including: not paying the invoice, exceeding the limits of your free plan, or violating the .
If your project is suspended, you will no longer be able to access the application or trigger new deployments. You will also be unable to access the Strapi admin panel.
You can view the status of your project in the section of your Strapi Cloud account and you will be notified by email.
:::warning
If you do not resolve the issue within 30 days, your suspended project will be deleted and all data will be permanently lost. To avoid this situation, you will be sent a first email when your project becomes suspended, then another email every 5 days until one week left, to remind you to solve the issue. The last week before the deletion of the project, you will be sent 3 more emails: 6 days, 3 days and 1 day before your project is finally deleted.
:::
#### Project suspension for exceeding the Free plan limits
When a project hosted with the Free plan exceeds either the API requests or the Asset Bandwidth limits, it will be suspended until the monthly allowance resets at the beginning of the following month.
While the project is suspended:
- Users cannot trigger new deployments
- Access to the application is blocked
- Users cannot make changes to the project’s settings
To reactivate the project immediately, users can upgrade to a paid plan.
#### Project suspension after subscription cancellation
If you don't pay the invoice, then after few payment attempts the subscription of your project will automatically be canceled and the project will be suspended.
To reactivate your project, you can click on a *Reactivate subscription* button visible in the *Settings > Billing & Usage* tab of your suspended project (to reactivate the subscription you are on)
#### Project suspension for other reasons
If your project was suspended for reasons other than unpaid invoice leading to subscription cancellation, you may not have the possibility to reactivate your project yourself. You should receive an email with instructions on how to resolve the issue. If you do not receive the email notification, please contact [Strapi Support](mailto:support@strapi.io).
### Subscription cancellation
If you want to cancel your Strapi Cloud subscription, you have 2 options:
- either change your project's subscription to the free plan (see [Downgrading to another plan](/cloud/projects/settings#downgrading-to-another-plan) documentation),
- or completely delete your project (see [Deleting Strapi Cloud project](/cloud/projects/settings#deleting-strapi-cloud-project) documentation).
# Collaboration
Source: https://docs.strapi.io/cloud/projects/collaboration
# Collaboration on projects
Projects are created by a user via their Strapi Cloud account. Strapi Cloud users can share their projects to anyone else, so these new users can have access to the project dashboard and collaborate on that project, without the project owner to ever have to share their credentials.
Users invited to collaborate on a project, called maintainers, do not have the same permissions as the project owner. Contrary to the project owner, maintainers:
- Cannot share the project themselves to someone else
- Cannot delete the project from the project settings
- Cannot access the *Billing* section of project settings
## Sharing a project
To invite a new maintainer to collaborate on a project:
1. From the *Projects* page, click on the project of your choice to be redirected to its dashboard.
2. Click on the **Share** button located in the dashboard's header.
3. In the *Share [project name]* dialog, type the email address of the person to invite in the textbox. A dropdown indicating "Invite [email address]" should appear.
4. Click on the dropdown: the email address should be displayed in a purple box right below the textbox.
5. (optional) Repeat steps 3 and 4 to invite more people. Email addresses can only entered one by one but invites can be sent to several email addresses at the same time.
6. Click on the **Send** button.
New maintainers will be sent an email containing a link to click on to join the project. Once a project is shared, avatars representing the maintainers will be displayed in the project dashboard's header, next to the **Share** button, to see how many maintainers collaborate on that project and who they are.
:::tip
Avatars use GitHub, Google or GitLab profile pictures, but for pending users only initials will be displayed until the activation of the maintainer account. You can hover over an avatar to display the full name of the maintainer.
:::
## Managing maintainers
From the *Share [project name]* dialog accessible by clicking on the **Share** button of a project dashboard, projects owners can view the full list of maintainers who have been invited to collaborate on the project. From there, it is possible to see the current status of each maintainer and to manage them.
Maintainers whose full name is displayed are users who did activate their account following the invitation email. If however there are maintainers in the list whose email address is displayed, it means they haven't activated their accounts and can't access the project dashboard yet. In that case, a status should be indicated right next to the email address to explain the issue:
- Pending: the invitation email has been sent but the maintainer hasn't acted on it yet.
- Expired: the email has been sent over 72 hours ago and the invitation expired.
For Expired statuses, it is possible to send another invitation email by clicking on the **Manage** button, then **Resend invite**.
### Revoking maintainers
To revoke a maintainer's access to the project dashboard:
1. Click on the **Share** button in the project dashboard's header.
2. In the list of *People with access*, find the maintainer whose access to revoke and click on the **Manage** button.
3. Click on the **Revoke** button.
4. In the confirmation dialog, click again on the **Revoke** button.
The revoked maintainer will completely stop having access to the project dashboard.
:::note
Maintainers whose access to the project has been revoked do not receive any email or notification.
:::
# Deployments management
Source: https://docs.strapi.io/cloud/projects/deploys
# Deployments management
The creation of a new Strapi Cloud project automatically trigger the deployment of that project. After that, deployments can be:
- manually triggered whenever needed, [from the Cloud dashboard](#triggering-a-new-deployment) or [from the CLI](/cloud/cli/cloud-cli#strapi-deploy),
- or automatically triggered everytime a new commit is pushed to the branch, if the Strapi Cloud project is connected to a git repository and the "deploy on push" option is enabled (see [Project settings](/cloud/projects/settings#modifying-git-repository--branch)).
Ongoing deployments can also be [manually canceled](#cancelling-a-deployment) if needed.
## Triggering a new deployment
To manually trigger a new deployment for your project, click on the **Trigger deployment** button always displayed in the right corner of a project dashboard's header. This action will add a new card in the *Deployments* tab, where you can monitor the status and view the deployment logs live (see [Deploy history and logs](/cloud/projects/deploys-history)).
## Cancelling a deployment
If for any reason you want to cancel an ongoing and unfinished deployment:
1. Go to the *Deployment details* page of the latest triggered deployment (see [Accessing log details](/cloud/projects/deploys-history#accessing-deployment-details--logs)).
2. Click on the **Cancel deployment** button in the top right corner. The status of the deployment will automatically change to *Canceled*.
:::tip
You can also cancel a deployment from the *Deployments* tab which lists the deployments history. The card of ongoing deployment with the *Building* status will display a  button for cancelling the deployment.
:::
# Deployment history & logs
Source: https://docs.strapi.io/cloud/projects/deploys-history
# Deployment history and logs {#deploy-history-and-logs}
For each Strapi Cloud project, you can access the history of all deployments that occurred and their details including build and deployment logs. This information is available in the *Deployments* tab.
## Viewing the deployment history {#viewing-deploy-history}
In the *Deployments* tab is displayed a chronological list of cards with the details of all historical deployments for your project.
, with a direct link to your git provider, and commit message
- Deployment status:
- *Deploying*
- *Done*
- *Canceled*
- *Build failed*
- *Deployment failed*
- Last deployment time (when the deployment was triggered and the duration)
- Branch
## Accessing deployment details & logs
From the *Deployments* tab, you can hover a deployment card to make the  **Show details** button appear. Clicking on this button will redirect you to the *Deployment details* page which contains the deployment's detailed logs.
, with a direct link to your git provider, and commit message used for this deployment
- *Status*, which can be *Building*, *Deploying*, *Done*, *Canceled*, *Build failed*, or *Deployment failed*
- *Source*: the branch and commit message for this deployment
- *Duration*: the amount of time the deployment took and when it occurred
# Notifications
Source: https://docs.strapi.io/cloud/projects/notifications
# Notifications
The Notification center can be opened by clicking the bell icon in the top navigation of the Cloud dashboard.
It displays a list of the latest notifications for all your existing projects. Clicking on a notification card from the list will redirect you to the *Log details* page of the corresponding deployment (more information in [Deploy history & logs](/cloud/projects/deploys-history#accessing-deployment-details--logs)).
The following notifications can be listed in the Notifications center:
- *deployment completed*: when a deployment is successfully done.
- *Build failed*: when a deployment fails during the build stage.
- *deployment failed*: when a deployment fails during the deployment stage.
- *deployment triggered*: when a deployment is triggered by a new push to the connected repository. This notification is however not sent when the deployment is triggered manually.
:::note
All notifications older than 30 days are automatically removed from the Notification center.
:::
# Projects overview
Source: https://docs.strapi.io/cloud/projects/overview
# Projects overview
The *Projects* page displays a list of all your Strapi Cloud projects. From here you can manage your projects and access the corresponding applications.
Each project card displays the following information:
* the project name
* the last successful deployment’s date of the Production environment
* the current status of the project:
* *Disconnected*, if the project repository is not connected to Strapi Cloud
* *Suspended*, if the project has been suspended (refer to [Project suspension](/cloud/getting-started/usage-billing#project-suspension) to reactivate the project)
* *Incompatible version*, if the project is using a Strapi version that is not compatible with Strapi Cloud
Each project card also displays a menu icon to access the following options:
* **Visit App**: to be redirected to the application
* **Go to Deployments**: to be redirected to the [*Deployment*](/cloud/projects/deploys) page
* **Go to Settings**: to be redirected to the [*Settings*](/cloud/projects/settings) page
:::tip
Click on the * Product updates* button in the navigation bar to check out the latest features and fixes released.
:::
## Accessing a project's dashboard
From the *Projects* page, click on any project card to access its dashboard. It displays the project and environment details and gives access to the deployment history and all available settings.
From the dashboard's header of a chosen project, you can:
- use the **Share** button to invite users to collaborate on the project (see [Collaboration](/cloud/projects/collaboration)) and see the icons of those who have already been invited ,
- use the **Settings** button to access the settings of the project and its existing environments ,
- choose which environment to visualise for the project or add a new environment ,
- trigger a new deployment (see [Deployments management](/cloud/projects/deploys)) and visit your application .
Your project's dashboard also displays:
- the *Deployments* and *Runtime logs* tabs, to see the deployments history (more details in [Deploy history and logs](/cloud/projects/deploys-history)) and the runtime logs of the project (see [dedicated documentation page](/cloud/projects/runtime-logs))
- the project and environment details in a box on the right of the interface , including:
- the number of API calls,
- the current usage for asset bandwidth and storage,
- the name of the branch and a **Manage** button to be redirect to the branch settings (see [Modifying git repository & branch](/cloud/projects/settings#modifying-git-repository--branch)),
- the name of the base directory,
- the Strapi version number,
- the Strapi app's url.
# Runtime logs
Source: https://docs.strapi.io/cloud/projects/runtime-logs
# Runtime logs
From a chosen project's dashboard, the *Runtime logs* tab displays the live logs of the project.
:::note
- The *Runtime logs* are only accessible once the project is successfully deployed.
- Runtime logs are not live for projects on the Free plan and are reset each time the application is scaled to zero due to inactivity.
:::
# Project settings
Source: https://docs.strapi.io/cloud/projects/settings
# Project settings
From a chosen project's dashboard, the **Settings** button, located in the header, enables you to manage the configurations and settings for your Strapi Cloud project and its environments.
The settings' menu on the left side of the interface is separated into 2 categories: the settings for the entire project and the settings specific to any configured environment for the project.
## Project-level settings
There are 5 tabs available for the project's settings:
- [*General*](#general),
- [*Environments*](#environments),
- [*Billing & Usage*](#billing--usage),
- [Plans](#plans),
- and [Invoices](#invoices).
### General
The *General* tab for the project-level settings enables you to check and update the following options for the project:
- *Basic information*, to see:
- the name of your Strapi Cloud project — used to identify the project on the Cloud Dashboard, Strapi CLI, and deployment URLs — and change it (see [Renaming project](#renaming-project)).
- the chosen hosting region for your Strapi Cloud project, meaning the geographical location of the servers where the project and its data and resources are stored. The hosting region is set at project creation (see [Project creation](/cloud/getting-started/deployment)) and cannot be modified afterwards.
- the project's metadata, including the Production app internal name and the Subscription ID, which can be useful for debugging & support purposes.
- *Strapi CMS license key*: to enable and use some CMS features directly on your Cloud project (see [Pricing page](https://strapi.io/pricing-self-hosted) to purchase a license).
- *Connected Git repository*: to change the repository and branch used for your project (see [Modifying git repository & branch](#modifying-git-repository--branch)). Also allows to enable/disable the "deploy on push" option.
- *Danger zone*, with:
- *Transfer ownership*: for the project owner to transfer the ownership of the Cloud project to an already existing maintainer (see [Transferring project ownership](#transferring-project-ownership)).
- *Delete project*: to permanently delete your Strapi Cloud project (see [Deleting Strapi Cloud project](#deleting-strapi-cloud-project)).
#### Renaming project
The project name is set at project creation (see [Project creation](/cloud/getting-started/deployment)) and can be modified afterwards via the project's settings.
1. In the *Basic information* section of the *General* tab, click on the edit button.
2. In the dialog, write the new project name of your choice in the *Project name* textbox.
3. Click on the **Rename** button to confirm the project name modification.
#### Adding a CMS license key {#adding-cms-license-key}
A CMS license key can be added and connected to a Strapi Cloud project to unlock additional Strapi CMS features across all of the project’s environments. The CMS features that will be accessible via the license key depend on the type of license that was purchased: please refer to the for more information and/or to purchase a license.
:::note
If you don't see the *Strapi CMS license key* section, it probably means that your subscription is a legacy one and does not support custom CMS licenses. It means that you already have one that is automatically included on your project.
:::
1. In the *Strapi CMS license key* section, click on the **Add license** button.
2. In the dialog, paste your license key in the field.
3. Click on the **Save & deploy** button for the changes to take effect.
To remove the Strapi CMS license from your Strapi Cloud project, you can click on the **Unlink license** button. This will also remove access and usage to the CMS features included in the previously added license.
:::note
The license key is applied to all the environments in the project.
:::
#### Modifying git repository & branch
The GitHub or GitLab repository, branch and base directory for a Strapi Cloud project are by default chosen at the creation of the project (see [Creating a project](/cloud/getting-started/deployment)). After the project's creation, via the project's settings, it is possible to update the project's repository or switch to another git provider.
:::caution
Updating the git repository could result in the loss of the project and its data, for instance if the wrong repository is selected or if the data schema between the old and new repository doesn't match.
:::
1. In the *Connected git repository* section of the *General* tab, click on the **Update repository** button. You will be redirected to another interface.
2. (optional) If you wish to not only update the repository but switch to another git provider, click on the **Switch Git provider** button at the top right corner of the interface. You will be redirected to the chosen git provider's authorization settings before getting back to the *Update repository* interface.
3. In the *Update repository* section, fill in the 2 available settings:
| Setting name | Instructions |
| --------------- | ------------------------------------------------------------------------ |
| Account | Choose an account from the drop-down list. |
| Repository | Choose a repository from the drop-down list. |
4. In the *Select Git branches* section, fill in the available settings for any of your environments. Note that the branch can be edited per environment via its own settings, see [General (environment)](#environments).
| Setting name | Instructions |
| --------------- | ------------------------------------------------------------------------ |
| Branch | Choose a branch from the drop-down list. |
| Base directory | Write the path of the base directory in the textbox. |
| Auto-deploy | Tick the box to automatically trigger a new deployment whenever a new commit is pushed to the selected branch. Untick it to disable the option. |
5. Click on the **Save & deploy** button for the changes to take effect.
#### Transferring project ownership {#transferring-project-ownership}
The ownership of the Strapi Cloud project can be transferred to another user, as long as they're a maintainer of the project. It can either be at the initiative of the current project owner, or can be requested by a project maintainer. Once the ownership is transferred, it is permanent until the new owner decides to transfer the ownership again to another maintainer.
:::prerequisites
For the ownership of a project to be transferred, the following requirements must be met:
- The project must be on a paid plan, with no currently expired card and/or unpaid bills.
- The maintainer must have filled their billing information.
- No already existing ownership transfer must be pending for the project.
Note that ownership transfers might fail when done the same day of subscription renewal (i.e. 1st of every month). If the transfer fails that day, but all prerequisites are met, you should wait a few hours and try again.
:::
1. In the *Danger zone* section of the *General* tab, click on the **Transfer ownership** button.
2. In the dialog:
- If you are the project owner: choose the maintainer who should be transferred the ownership by clicking on **...** > **Transfer ownership** associated with their name.
- If you are a maintainer: find yourself in the list and click on **...** > **Transfer ownership** associated with your name.
3. Confirm the transfer/request in the new dialog by clicking on the **Transfer ownership** button.
An email will be sent to both users. The person who needs to transfer the ownership or inherit it will have to click on the **Confirm transfer** button in the email. Once done, the previous owner will receive a confirmation email that the transfer has successfully been done.
:::tip
As long as the ownership transfer or request hasn't been confirmed, there is the option to cancel in the same dialog that the maintainer was chosen.
:::
:::note
Once the ownership transfer is done, the project will be disconnected from Strapi Cloud. As new owner, make sure to go to the *General* tab of project settings to reconnect the project.
:::
#### Deleting Strapi Cloud project
You can delete any Strapi Cloud project, but it will be permanent and irreversible. Associated domains, deployments and data will be deleted as well and the subscription for the project will automatically be canceled.
1. In the *Danger zone* section of the *General* tab, click on the **Delete project** button.
2. In the dialog, select the reason why you are deleting your project. If selecting "Other" or "Missing feature", a textbox will appear to let you write additional information.
3. Confirm the deletion of your project by clicking on the **Delete project** button at the bottom of the dialog.
### Environments {#environments}
The *Environments* tab allows to see all configured environments for the Strapi Cloud project, as well as to create new ones. Production is the default environment, which cannot be deleted. Other environments can be created (depending on the subscription plan for your project) to work more safely on isolated instances of your Strapi Cloud project (e.g. a staging environment where tests can be made before being available on production).
:::tip
Clicking on the **Manage** button for any environment will redirect you to the environment's own general settings, where it is possible to change the Node version, edit the git branches and delete or reset the environment. Please [refer to the dedicated documentation](#environments) for more information.
:::
:::tip
A new environment can also be added from the [project dashboard](/cloud/projects/overview#accessing-a-projects-dashboard).
:::
To create a new environment:
1. Click on the **Add a new environment** button.
2. In the dialog that opens, you can see the price for the new environment and the date of the next invoice.
3. Fill in the available settings:
| Setting name | Instructions |
| ---------------- | ------------------------------------------------------------------------ |
| Environment name | (mandatory) Write a name for your project's new environment. |
| Git branch | (mandatory) Select the right branch for your new environment. |
| Base directory | Write the name of the base directory of your new environment. |
| Import variables | Tick the box to import variable names from an existing environment. Values will not be imported, and all variables will remain blank. |
| Deploy on push | Tick this box to automatically trigger a deployment when changes are pushed to your selected branch. When disabled, you will need to manually deploy the latest changes. |
4. Click on the **Add environment** button to create your project's new environment. You will then be redirected to your *Project dashboard* where you will be able to follow your new environment's creation and first deployment.
:::note
If an error occurs during the environment creation, the progress indicator will stop and display an error message. You will see a **Retry** button next to the failed step, allowing you to restart the creation process.
:::
### Billing & Usage
The *Billing & Usage* displays your next estimated payment, all information on the current subscription plan and a detailed summary of the project's and its environments' usage. It also allows you to add new environments (please [refer to the documentation in the Environments section](#environments)) for your project.
Through this tab, you also have the possibility to:
- click the **Change** button to be redirected to the *Plans* tab, where you can change you subscription plan ([see related documentation](#plans)),
- click the **Edit** button in order to set a new payment method (see [related documentation](/cloud/account/account-billing)).
:::note
You can attach a dedicated card to your project by choosing the payment method directly from this page. In that way, you can manage your subscriptions with different cards.
:::
:::tip
In the Usage section of the *Billing & Usage* tab, you can see the current monthly usage of your project compared to the maximum usage allowed by your project's subscription. Use the arrows in the top right corner to see the project's usage for any chosen month.
Note also that if your usage indicates that another subscription plan would fit better for your project, a message will be displayed in the *Billing & Usage* tab to advise which plan you could switch to.
:::
### Plans
The *Plans* tab displays an overview of the available Strapi Cloud plans and allows you to upgrade or downgrade from your current plan to another.
:::info
Strapi recently launched [new Cloud plans](https://strapi.io/pricing-cloud). For now, you can [downgrade](#downgrading-to-another-plan) or [upgrade](#upgrading-to-another-plan) to another plan directly from the Cloud dashboard, under the **Settings** > **Plans** section.
If your project was created before the new plans were released, it may be on a *legacy* plan—deprecated but still supported. You can sidegrade to a new plan if desired (see [downgrade section](#downgrading-to-another-plan)).
:::
#### Upgrading to another plan
Strapi Cloud plan upgrades to another, higher plan are immediate and can be managed for each project via the project settings.
:::note
When using the Free plan, the buttons to upgrade to another plan are greyed out and unusable until you have filled in your billing information. Please refer to [Account billing details](/cloud/account/account-billing) for more information.
:::
To upgrade your current plan to a higher one:
1. In the *Plans* tab of your project's settings, click on the **Upgrade** button of the plan you want to upgrade to.
2. In the window that opens, check the payment details that indicate how much you will have to pay immediately after confirming the upgrade, and the available options.
a. (optional) Click the **Edit** button to select another payment method.
b. (optional) Click **I have a discount code**, enter your discount code in the field, and click on the **Apply** button.
3. Click on the **Upgrade to [plan name]** button to confirm the upgrade of your Strapi project to another plan.
#### Downgrading to another plan
Strapi Cloud plan downgrades can be managed for each project via the project settings. Downgrades are however not immediately effective: the higher plan will still remain active until the end of the current month (e.g. if you downgrade from the Scale plan to the Pro plan on June 18th, your project will remain on the Scale plan until the end of the month: on July 1st, the Pro plan will be effective for the project).
:::caution
Make sure to check the usage of your Strapi Cloud project before downgrading: if your current usage exceeds the limits of the lower plan, you are taking the risk of getting charged for the overages. You may also lose access to some features: for example, downgrading to the Essential plan which doesn't include the Backups feature, would make you lose all your project's backups. Please refer to [Information on billing & usage](/cloud/getting-started/usage-billing) for more information.
Note also that you cannot downgrade if you have additional environments (i.e. extra environments that have been purchased, not the default or included environments). For instance, if you wish to downgrade from the Pro plan to the Essential plan, you first need to delete all additional environments that have been configured (see [Resetting & Deleting environment](#resetting--deleting-environment)), for the **Downgrade** button to be displayed and available again.
:::
To downgrade your current plan to a lower one:
1. In the *Plans* tab of your project's settings, click on the **Downgrade** button of the plan you want to downgrade to.
2. In the window that opens, check the information related to downgrading.
3. Click on the **Downgrade** button to confirm the downgrade of your Strapi project's plan.
:::tip
Downgrades are effective from the 1st of the following month. Before that date, you can click on the **Cancel downgrade** button to remain on the current plan.
:::
### Invoices
The *Invoices* tab displays the full list of invoices for your Strapi Cloud project as well as their status.
:::strapi Invoices are also available in your profile settings.
In the *Profile > Invoices* tab, you will find the complete list of invoices for all your projects. Feel free to check the [dedicated documentation](/cloud/account/account-billing#account-invoices).
:::
No invoice is issued for the Free plan.
## Environment-level settings
In the project's environments' settings, you first need to select the environment whose settings you would like to configure, using the dropdown. Depending on the chosen environment, there are 3 to 4 tabs available:
- [*Configuration*](#configuration),
- [*Backups*](#backups), which are only available for the production environment,
- [*Domains*](#domains),
- and [*Variables*](#variables).
### Configuration
The *Configuration* tab for the environment-level settings enables you to check and update the following options for the project:
- *Basic information*, to see:
- the name of your Strapi Cloud project's environment. The environment name is set when it is created and cannot be modified afterwards.
- the Node version of the environment: to change the Node version of the project (see [Modifying Node version](#modifying-node-version)).
- the app's internal name for the environment, which can be useful for debug & support purposes.
- *Connected branch*: to change the branch of the GitHub repository used for your environment (see [Editing Git branch](#editing-git-branch)). Also allows to enable/disable the "deploy on push" option.
- *Danger zone*: to reset or permanently delete your Strapi Cloud project's environment (see [Resetting & Deleting environment](#resetting--deleting-environment)).
#### Modifying Node version
The environment's Node version is based on the one chosen at the creation of the project (see [Creating a project](/cloud/getting-started/deployment)), through the advanced settings. It is possible to switch to another Node version afterwards, for any environment.
1. In the *Basic information* section of the *Configuration* tab, click on the *Node version*'s edit button.
2. Using the *Node version* drop-down in the dialog, click on the version of your choice.
3. Click on **Save**, or **Save & deploy** if you want the changes to take effect immediately.
:::tip
Ensure the Node version configured in your Strapi project matches the Node version shown in your project’s dashboard before deploying.
:::
#### Editing Git branch
2. In the *Edit branch* dialog, edit the available settings. Note that the branch can be edited for all environments at the same time via the project's settings, see [General](#general).
| Setting name | Instructions |
| --------------- | ------------------------------------------------------------------------ |
| Selected branch | (mandatory) Choose a branch from the drop-down list. |
| Base directory | Write the path of the base directory in the textbox. |
| Deploy the project on every commit pushed to this branch | Tick the box to automatically trigger a new deployment whenever a new commit is pushed to the selected branch. Untick it to disable the option. |
3. Click on the **Save & deploy** button for the changes to take effect.
#### Resetting & Deleting environment
You can reset or delete any additional environment of your Strapi Cloud project, but it will be permanent and irreversible. The default, production environment, can however not be neither reset nor deleted.
##### Resetting an environment
Resetting an environment deletes all environments data and resets the variables to their default. To do so:
1. In the *Danger zone* section of the *Configuration* tab, click on the **Reset environment** button.
2. In the dialog that opens, click on the **Continue** button to confirm the environment reset.
3. Fill in the available fields to reset the environment:
| Setting name | Instructions |
| --------------- | ------------------------------------------------------------------------ |
| Environment name | (mandatory) Write a name for your project's new environment. |
| Git branch | (mandatory) Choose a branch from the drop-down list. |
| Base directory | Write the path of the base directory in the textbox. |
| Import variables | Tick the box to import variable names from an existing environment. Values will not be imported, and all variables will remain blank. |
| Auto-deploy | Deploy the project on every commit pushed to this branch | Tick the box to automatically trigger a new deployment whenever a new commit is pushed to the selected branch. Untick it to disable the option. |
4. Click on the **Reset** button.
##### Deleting an environment
1. In the *Danger zone* section of the *Configuration* tab, click on the **Delete environment** button.
2. Write in the textbox your *Environment name*.
3. Click on the **Delete environment** button to confirm the deletion.
### Backups {#backups}
The *Backups* tab informs you of the status and date of the latest backup of your Strapi Cloud projects. The databases associated with all existing Strapi Cloud projects are indeed automatically backed up (weekly for Pro plans and daily for Scale plans). Backups are retained for a 28-day period. Additionally, you can create a single manual backup.
:::note Notes
- The backup feature is not available for Strapi Cloud projects on the Free or Essential plans. You will need to upgrade to the Pro or Scale plan to enable automatic backups and access the manual backup option.
- Backups include only the database of your default Production environment. Assets uploaded to your project and databases from any secondary environments are not included.
- The manual backup option becomes available shortly after the project’s first successful deployment.
:::
:::tip
For projects created before the release of the Backup feature in October 2023, the first backup will automatically be triggered with the next deployment of the project.
:::
#### Creating a manual backup
To create a manual backup, in the *Backups* section, click on the **Create backup** button.
The manual backup should start immediately, and restoration or creation of other backups will be disabled until the backup is complete.
:::caution
When creating a new manual backup, any existing manual backup will be deleted. You can only have one manual backup at a time.
:::
#### Restoring a backup
If you need to restore a backup of your project:
1. In the *Backups* section, click on the **Restore backup** button.
2. In the dialog, choose one of the available backups (automatic or manual) of your project in the *Choose backup* drop-down.
3. Click on the **Restore** button of the dialog. Once the restoration is finished, your project will be back to the state it was at the time of the chosen backup. You will be able to see the restoration timestamp and the backup restored in the *Backups* tab.
4. The timestamp of the last completed restoration will be displayed to help you track when the project was last restored.
#### Downloading a backup
If you need to download a backup of your project:
1. In the *Backups* section, click on the **Download backup** button.
2. In the dialog, choose one of the available backups (automatic or manual) of your project in the *Choose backup* drop-down.
3. Click on the **Download** button of the dialog to download the chosen backup's archive file in `.sql` format.
:::note
The backup file will include only the database of your default Production environment. It will not include assets or any other environment databases.
:::
### Domains
The *Domains* tab enables you to manage domains and connect new ones.
All existing domains for your Strapi Cloud project are listed in the *Domains* tab. For each domain, you can:
- see its current status:
- Active: the domain is currently confirmed and active
- Pending: the domain transfer is being processed, waiting for DNS changes to propagate
- Failed: the domain change request did not complete as an error occured
- click the edit button to access the settings of the domain
- click the delete button to delete the domain
#### Connecting a custom domain
Default domain names are made of 2 randomly generated words followed by a hash. They can be replaced by any custom domain of your choice.
:::note
Custom domains are not available on the Free plan. Downgrading to the Free plan will result in the application domain's being restored to the default one.
:::
1. Click the **Connect new domain** button.
2. In the window that opens, fill in the following fields:
| Setting name | Instructions |
| ------------------------- | ------------------------------------------------------------------------- |
| Domain name | Type the new domain name (e.g. *custom-domain-name.com*) |
| Hostname | Type the hostname (i.e. address end-users enter in web browser, or call through APIs). |
| Target | Type the target (i.e. actual address where users are redirected when entering hostname). |
| Set as default domain | Tick the box to make the new domain the default one. |
3. Click on **Save**, or **Save & deploy** if you want the changes to take effect immediately.
:::tip
To finish setting up your custom domain, in the settings of your domain registar or hosting platform, please add the Target value (e.g., `proud-unicorn-123456af.strapiapp.com`) as a CNAME alias to the DNS records of your domain.
:::
:::info Custom domains and assets
When using custom domains, these domains do not apply to the URLs of uploaded assets. Uploaded assets keep the Strapi Cloud project-based URL.
This means that, if your custom domain is hosted at `https://my-custom-domain.com` and your Strapi Cloud project name is `my-strapi-cloud-instance`, API calls will still return URLs such as `https://my-strapi-cloud-instance.media.strapiapp.com/example.png`.
Media library queries over REST or GraphQL always return the project media domain on Strapi Cloud. If you move from a self-hosted project, where media URLs can match your own domain or CDN, plan to keep using the absolute URLs from the API or adjust your frontend to allow the Strapi Cloud media domain (see [Cloud Fundamentals](/cloud/cloud-fundamentals) for more details).
:::
### Variables
Environment variables (more information in the [CMS Documentation](/cms/configurations/environment)) are used to configure the environment of your Strapi application, such as the database connection.
In the *Variables* tab are listed both the default and custom environment variables for your Strapi Cloud project. Each variable is composed of a *Name* and a *Value*.
#### Managing environment variables
Hovering on an environment variable, either default or custom, displays the following available options:
- **Show value** to replace the `*` characters with the actual value of a variable.
- **Copy to clipboard** to copy the value of a variable.
- **Actions** to access the Edit and Delete buttons.
- When editing a default variable, the *Name* cannot be modified and the *Value* can only be automatically generated using the Generate value button. Don't forget to **Save**, or **Save & deploy** if you want the changes to take effect immediately.
- When editing a custom variable, both the *Name* and *Value* can be modified by writing something new or by using the Generate value button. Don't forget to **Save**, or **Save & deploy** if you want the changes to take effect immediately.
- When deleting a variable, you will be asked to confirm by selecting **Save**, or **Save & deploy** if you want the changes to take effect immediately.
:::tip
Use the search bar to find more quickly an environment variable in the list!
:::
#### Creating custom environment variables
Custom environment variables can be created for the Strapi Cloud project. Make sure to redeploy your project after creating or editing an environment variable.
1. In the *Custom environment variables* section, click on the **Add variable** button.
2. Write the *Name* and *Value* of the new environment variable in the same-named fields. Alternatively, you can click on the icon to generate automatically the name and value.
3. (optional) Click on **Add another** to directly create one or more other custom environment variables.
4. Click on the **Save** button to confirm the creation of the custom environment variables. To apply your changes immediately, click on **Save & deploy**.
# 管理面板定制
Source: https://docs.strapi.io/cms/admin-panel-customization
# 管理面板定制 {#admin-panel-customization}
¥Admin panel customization
Strapi 的前端部分
¥The **front-end part of Strapi**
称为管理面板。管理面板提供了一个图形用户界面,可帮助你构建和管理可通过 Content API 访问的内容。要了解管理面板的概览,请参阅 [入门 > 管理面板](/cms/features/admin-panel) 页面。
¥is called the admin panel. The admin panel presents a graphical user interface to help you structure and manage the content that will be accessible through the Content API. To get an overview of the admin panel, please refer to the [Getting Started > Admin panel](/cms/features/admin-panel) page.
从开发者的角度来看,Strapi 的管理面板是一个基于 React 的单页应用,它封装了 Strapi 应用的所有功能和已安装的插件。
¥From a developer point of view, Strapi's admin panel is a React-based single-page application that encapsulates all the features and installed plugins of a Strapi application.
管理面板的自定义可以通过调整 `src/admin/app` 文件或 `src/admin` 文件夹中包含的其他文件的代码来完成(参见 [项目结构](/cms/project-structure))。通过这样做,你可以:
¥Admin panel customization is done by tweaking the code of the `src/admin/app` file or other files included in the `src/admin` folder (see [project structure](/cms/project-structure)). By doing so, you can:
* 自定义管理面板的某些部分,以更好地体现你的品牌标识(徽标、网站图标)或语言。
¥Customize some parts of the admin panel to better reflect your brand identity (logos, favicon) or your language,
* 替换管理面板的其他部分,例如富文本编辑器和打包器。
¥Replace some other parts of the admin panel, such as the Rich text editor and the bundler,
* 扩展主题或管理面板以添加新功能或自定义现有用户界面。
¥Extend the theme or the admin panel to add new features or customize the existing user interface.
## 一般注意事项 {#general-considerations}
¥General considerations
:::prerequisites
在更新代码以自定义管理面板之前:
¥Before updating code to customize the admin panel:
* 将现在无效的任何配置文件重命名为新名称,并更新代码以查找该路径。
¥Rename the default `app.example.tsx|js` file into `app.ts|js`.
* 在 `/src/admin/` 中创建一个新的 `extensions` 文件夹。
¥Create a new `extensions` folder in `/src/admin/`.
* 如果你想在开发过程中实时看到你的更改,请确保管理面板服务器正在运行(如果你没有更改管理面板的默认 [主机、端口和路径](/cms/configurations/admin-panel#admin-panel-server),通常使用 `yarn develop` 或 `npm run develop` 命令完成)。
¥If you want to see your changes applied live while developing, ensure the admin panel server is running (it's usually done with the `yarn develop` or `npm run develop` command if you have not changed the default [host, port, and path](/cms/configurations/admin-panel#admin-panel-server) of the admin panel).
:::
大多数基本的管理面板自定义将在 `/src/admin/app` 文件中完成,该文件包含一个 `config` 对象。
¥Most basic admin panel customizations will be done in the `/src/admin/app` file, which includes a `config` object.
`config` 对象使用的任何文件(例如自定义徽标)都应放置在 `/src/admin/extensions/` 文件夹中并导入 `/src/admin/app.js` 中。
¥Any file used by the `config` object (e.g., a custom logo) should be placed in a `/src/admin/extensions/` folder and imported inside `/src/admin/app.js`.
这将替换位于 `./build` 的文件夹内容。访问
## 基本示例 {#basic-example}
¥Basic example
以下是管理面板基本自定义的示例:
¥The following is an example of a basic customization of the admin panel:
:::strapi 代码库中的详细示例
* 你可以查看完整的翻译键,例如更改欢迎消息,[在 GitHub 上](https://github.com/strapi/strapi/blob/develop/packages/core/admin/admin/src/translations)。
¥You can see the full translation keys, for instance to change the welcome message, [on GitHub](https://github.com/strapi/strapi/blob/develop/packages/core/admin/admin/src/translations).
* [在 GitHub 上](https://github.com/strapi/design-system/tree/main/packages/design-system/src/themes) 中也包含浅色和深色。
¥Light and dark colors are also found [on GitHub](https://github.com/strapi/design-system/tree/main/packages/design-system/src/themes).
:::
# 管理面板打包器
Source: https://docs.strapi.io/cms/admin-panel-customization/bundlers
# 管理面板打包器 {#admin-panel-bundlers}
¥Admin panel bundlers
Strapi 的 [管理面板](/cms/admin-panel-customization) 是一款基于 React 的单页应用,它封装了 Strapi 应用的所有功能和已安装的插件。你的 Strapi 5 应用可以使用 2 个不同的打包器,[Vite](#vite)(默认)和 [webpack](#webpack)。两个打包器都可以根据你的需要进行配置。
¥Strapi's [admin panel](/cms/admin-panel-customization) is a React-based single-page application that encapsulates all the features and installed plugins of a Strapi application. 2 different bundlers can be used with your Strapi 5 application, [Vite](#vite) (the default one) and [webpack](#webpack). Both bundlers can be configured to suit your needs.
:::info 信息
为简单起见,以下文档提到了 `strapi develop` 命令,但实际上,你可能会根据你选择的包管理器运行 `yarn develop` 或 `npm run develop` 来使用它的别名。
¥For simplification, the following documentation mentions the `strapi develop` command, but in practice you will probably use its alias by running either `yarn develop` or `npm run develop` depending on your package manager of choice.
:::
## Vite {#vite}
在 Strapi 5 中,
## Webpack {#webpack}
在 Strapi 5 中,默认打包器是 Vite。要使用
# 管理面板扩展
Source: https://docs.strapi.io/cms/admin-panel-customization/extension
# 管理面板扩展 {#admin-panel-extension}
¥Admin panel extension
Strapi 的 [管理面板](/cms/admin-panel-customization) 是一款基于 React 的单页应用,它封装了 Strapi 应用的所有功能和已安装的插件。如果 Strapi 提供的 [自定义选项](/cms/admin-panel-customization#available-customizations) 不足以满足你的用例,你将需要扩展 Strapi 的管理面板。
¥Strapi's [admin panel](/cms/admin-panel-customization) is a React-based single-page application that encapsulates all the features and installed plugins of a Strapi application. If the [customization options](/cms/admin-panel-customization#available-customizations) provided by Strapi are not enough for your use case, you will need to extend Strapi's admin panel.
扩展 Strapi 的管理面板意味着利用其 React 基础根据项目的特定需求调整和增强界面和功能,这可能意味着创建新组件或添加新类型的字段。
¥Extending Strapi's admin panel means leveraging its React foundation to adapt and enhance the interface and features according to the specific needs of your project, which might imply creating new components or adding new types of fields.
在 2 个用例中,你可能需要扩展管理面板:
¥There are 2 use cases where you might want to extend the admin panel:
* 作为 Strapi 插件开发者,你希望开发一个 Strapi 插件,每次安装在任何 Strapi 应用中时,都会扩展管理面板。
¥As a Strapi plugin developer, you want to develop a Strapi plugin that extends the admin panel **everytime it's installed in any Strapi application**.
👉 这可以通过利用 [管理面板 API 插件](/cms/plugins-development/admin-panel-api) 来完成。
¥👉 This can be done by taking advantage of the [Admin Panel API for plugins](/cms/plugins-development/admin-panel-api).
* 作为 Strapi 开发者,你希望为只需要扩展 Strapi 应用特定实例的 Strapi 用户开发独特的解决方案。
¥As a Strapi developer, you want to develop a unique solution for a Strapi user who only needs to extend a specific instance of a Strapi application.
👉 这可以通过直接更新 `/src/admin/app` 文件来完成,该文件可以导入位于 `/src/admin/extensions` 中的任何文件。
¥👉 This can be done by directly updating the `/src/admin/app` file, which can import any file located in `/src/admin/extensions`.
:::strapi 其他资源
* 如果你正在寻找替换默认富文本编辑器的方法,请参阅 [相应页面](/cms/admin-panel-customization/wysiwyg-editor)。
¥If you're searching for ways of replacing the default Rich text editor, please refer to the [corresponding page](/cms/admin-panel-customization/wysiwyg-editor).
* 还提供了有关 Strapi 管理面板开发的大量附加信息。
¥The also provide extensive additional information on developing for Strapi's admin panel.
:::
# 网站图标
Source: https://docs.strapi.io/cms/admin-panel-customization/favicon
# 网站图标 {#favicon}
¥Favicon
Strapi 的 [管理面板](/cms/admin-panel-customization) 在多个位置显示其品牌标识,包括 [logo](/cms/admin-panel-customization/logos) 和网站图标。替换这些图片可以让你将界面和应用与你的身份相匹配。
¥Strapi's [admin panel](/cms/admin-panel-customization) displays its branding on various places, including the [logo](/cms/admin-panel-customization/logos) and the favicon. Replacing these images allows you to match the interface and application to your identity.
要替换图标:
¥To replace the favicon:
1. 如果 `/src/admin/extensions/` 文件夹尚不存在,请创建该文件夹。
¥Create a `/src/admin/extensions/` folder if the folder does not already exist.
2. 将你的网站图标上传到 `/src/admin/extensions/`。
¥Upload your favicon into `/src/admin/extensions/`.
3. 将 Strapi 应用根目录中现有的 favicon.png|ico 文件替换为自定义 `favicon.png|ico` 文件。
¥Replace the existing **favicon.png|ico** file at the Strapi application root with a custom `favicon.png|ico` file.
4. 使用以下内容更新 `/src/admin/app.[tsx|js]`:
¥Update `/src/admin/app.[tsx|js]` with the following:
```js title="./src/admin/app.js"
import favicon from "./extensions/favicon.png";
export default {
config: {
// replace favicon with a custom icon
head: {
favicon: favicon,
},
},
};
```
5. 通过在终端中运行 `yarn build && yarn develop` 来重建、启动并重新访问你的 Strapi 应用。
¥Rebuild, launch and revisit your Strapi app by running `yarn build && yarn develop` in the terminal.
:::tip 提示
可以使用相同的过程来替换登录徽标(即 `AuthLogo`)和菜单徽标(即 `MenuLogo`)(参见 [徽标定制文档](/cms/admin-panel-customization/logos))。
¥This same process may be used to replace the login logo (i.e. `AuthLogo`) and menu logo (i.e. `MenuLogo`) (see [logos customization documentation](/cms/admin-panel-customization/logos)).
:::
:::caution 提醒
确保清除缓存的图标。它可以缓存在你的 Web 浏览器中,也可以使用你的域管理工具(例如 Cloudflare 的 CDN)进行缓存。
¥Make sure that the cached favicon is cleared. It can be cached in your web browser and also with your domain management tool like Cloudflare's CDN.
:::
# 主页自定义
Source: https://docs.strapi.io/cms/admin-panel-customization/homepage
# 主页自定义 {#homepage-customization}
¥Homepage customization
:::note 此 API 需要 Strapi 5.13+ 版本。
`app.widgets.register` API 仅适用于 Strapi 5.13 及更高版本。尝试使用旧版本的 Strapi 调用 API 将导致管理面板崩溃。想要注册小部件的插件开发者应该:
¥The `app.widgets.register` API only works with Strapi 5.13 and above. Trying to call the API with older versions of Strapi will crash the admin panel.
Plugin developers who want to register widgets should either:
* 在其插件 `package.json` 中将 `^5.13.0` 设置为其 `@strapi/strapi` peerDependency。此对等依赖支持 Marketplace 的兼容性检查。
¥set `^5.13.0` as their `@strapi/strapi` peerDependency in their plugin `package.json`. This peer dependency powers the Marketplace's compatibility check.
* 或者,在调用 API 之前检查它是否存在:
¥or check if the API exists before calling it:
```js
if ('widgets' in app) {
// proceed with the registration
}
```
如果插件的主要目的是注册小部件,则建议使用 peerDependency 方法。如果插件想要添加小部件,但其大部分功能位于其他位置,则第二种方法更有意义。
¥The peerDependency approach is recommended if the whole purpose of the plugin is to register widgets. The second approach makes more sense if a plugin wants to add a widget but most of its functionality is elsewhere.
:::
#### 小部件 API 参考 {#widget-api-reference}
¥Widget API reference
`app.widgets.register()` 方法可以接受单个窗口小部件配置对象或配置对象数组。每个小部件配置对象都可以接受以下属性:
¥The `app.widgets.register()` method can take either a single widget configuration object or an array of configuration objects. Each widget configuration object can accept the following properties:
| 属性 | 类型 | 描述 | 必需的 |
| ------------- | ------------------------------------ | ---------------------- | --- |
| `icon` | `React.ComponentType` | 显示在小部件标题旁边的图标组件 | 是的 |
| `title` | `MessageDescriptor` | 支持翻译的小部件标题 | 是的 |
| `component` | `() => Promise
:::tip 提示
为简单起见,以下示例直接在 useEffect 钩子内部使用数据提取。虽然这仅用于演示目的,但它可能无法反映生产环境中的最佳实践。
¥For simplicity, the example below uses data fetching directly inside a useEffect hook. While this works for demonstration purposes, it may not reflect best practices in production.
为了获得更强大的解决方案,请考虑 [React 文档](https://react.nodejs.cn/learn/build-a-react-app-from-scratch#data-fetching) 中推荐的替代方法。如果你希望集成数据获取库,我们建议你使用 [TanStackQuery](https://tanstack.com/query/v3/)。
¥For more robust solutions, consider alternative approaches recommended in the [React documentation](https://react.nodejs.cn/learn/build-a-react-app-from-scratch#data-fetching). If you're looking to integrate a data fetching library, we recommend using [TanStackQuery](https://tanstack.com/query/v3/).
:::
数据管理:
¥**Data management**:

上方的绿色框表示用户的 React 组件(来自 [API](#widget-api-reference) 中的 `widget.component`)的渲染区域。你可以在此框中渲染任何你喜欢的内容。但是,该框之外的所有内容均由 Strapi 渲染。这确保了管理面板内整体设计的一致性。API 中提供的 `icon`、`title` 和 `link`(可选)属性用于显示窗口小部件。
¥The green box above represents the area where the user’s React component (from `widget.component` in the [API](#widget-api-reference)) is rendered. You can render whatever you like inside of this box. Everything outside that box is, however, rendered by Strapi. This ensures overall design consistency within the admin panel. The `icon`, `title`, and `link` (optional) properties provided in the API are used to display the widget.
#### 小部件辅助组件参考 {#widget-helper-components-reference}
¥Widget helper components reference
Strapi 提供了几个辅助组件,以便在各个小部件之间保持一致的用户体验:
¥Strapi provides several helper components to maintain a consistent user experience across widgets:
| 组件 | 描述 | 用法 |
| ---------------------- | ------------ | ----------- |
| `Widget.Loading` | 显示加载旋转图标和消息 | 正在获取数据时 |
| `Widget.Error` | 显示错误状态 | 发生错误时 |
| `Widget.NoData` | 当没有可用数据时显示 | 小部件没有数据可显示时 |
| `Widget.NoPermissions` | 当用户缺少所需权限时显示 | 用户无法访问小部件时 |
这些组件有助于在不同的小部件之间保持一致的外观和体验。你可以渲染这些组件而不使用子组件以获得默认的措辞:`
))}
);
};
```
以下文件定义了一个自定义控制器,用于统计所有内容类型:
¥The following file defines a custom controller that counts all content-types:
```js title="src/plugins/content-metrics/server/src/controllers/metrics.js"
'use strict';
module.exports = ({ strapi }) => ({
async getContentCounts(ctx) {
try {
// Get all content types
const contentTypes = Object.keys(strapi.contentTypes)
.filter(uid => uid.startsWith('api::'))
.reduce((acc, uid) => {
const contentType = strapi.contentTypes[uid];
acc[contentType.info.displayName || uid] = 0;
return acc;
}, {});
// Count entities for each content type
for (const [name, _] of Object.entries(contentTypes)) {
const uid = Object.keys(strapi.contentTypes)
.find(key =>
strapi.contentTypes[key].info.displayName === name || key === name
);
if (uid) {
// Using the count() method from the Document Service API
const count = await strapi.documents(uid).count();
contentTypes[name] = count;
}
}
ctx.body = contentTypes;
} catch (err) {
ctx.throw(500, err);
}
}
});
```
以下文件确保指标控制器可通过自定义 `/count` 路由访问:
¥The following file ensures that the metrics controller is reachable at a custom `/count` route:
```js title="src/plugins/content-metrics/server/src/routes/index.js"
'content-api': {
type: 'content-api',
routes: [
{
method: 'GET',
path: '/count',
handler: 'metrics.getContentCounts',
config: {
policies: [],
},
},
],
},
};
```
))}
);
};
```
以下文件定义了一个自定义控制器,用于统计所有内容类型:
¥The following file defines a custom controller that counts all content-types:
```js title="src/plugins/content-metrics/server/src/controllers/metrics.js"
'use strict';
module.exports = ({ strapi }) => ({
async getContentCounts(ctx) {
try {
// Get all content types
const contentTypes = Object.keys(strapi.contentTypes)
.filter(uid => uid.startsWith('api::'))
.reduce((acc, uid) => {
const contentType = strapi.contentTypes[uid];
acc[contentType.info.displayName || uid] = 0;
return acc;
}, {});
// Count entities for each content type using Document Service
for (const [name, _] of Object.entries(contentTypes)) {
const uid = Object.keys(strapi.contentTypes)
.find(key =>
strapi.contentTypes[key].info.displayName === name || key === name
);
if (uid) {
// Using the count() method from Document Service instead of strapi.db.query
const count = await strapi.documents(uid).count();
contentTypes[name] = count;
}
}
ctx.body = contentTypes;
} catch (err) {
ctx.throw(500, err);
}
}
});
```
以下文件确保指标控制器可通过自定义 `/count` 路由访问:
¥The following file ensures that the metrics controller is reachable at a custom `/count` route:
```js title="src/plugins/content-metrics/server/src/routes/index.js"
'content-api': {
type: 'content-api',
routes: [
{
method: 'GET',
path: '/count',
handler: 'metrics.getContentCounts',
config: {
policies: [],
},
},
],
},
};
```
# 语言环境和翻译
Source: https://docs.strapi.io/cms/admin-panel-customization/locales-translations
# 语言环境和翻译 {#locales--translations}
¥Locales & translations
Strapi [管理面板](/cms/admin-panel-customization) 自带英文的字符串,并支持添加其他语言环境,以便你的编辑团队可以使用他们喜欢的语言工作。语言环境决定界面中显示的语言,而翻译则提供语言环境中每个键对应的显示文本。
¥The Strapi [admin panel](/cms/admin-panel-customization) ships with English strings and supports adding other locales so your editorial team can work in their preferred language. Locales determine which languages appear in the interface, while translations provide the text displayed for each key in a locale.
本指南面向希望从应用代码库定制管理体验的项目维护人员。所有示例都会修改从 `/src/admin/app` 文件导出的配置,Strapi 会在构建管理面板时加载该文件。你将学习如何声明其他语言环境,以及如何在语言环境缺少字符串时扩展 Strapi 或插件翻译。
¥This guide targets project maintainers customizing the admin experience from the application codebase. All examples modify the configuration exported from `/src/admin/app` file, which Strapi loads when the admin panel builds. You'll learn how to declare additional locales and how to extend Strapi or plugin translations when a locale is missing strings.
## 定义语言环境 {#defining-locales}
¥Defining locales
要更新管理面板中可用语言环境列表,请在 `src/admin/app` 文件中设置 `config.locales` 数组:
¥To update the list of available locales in the admin panel, set the `config.locales` array in `src/admin/app` file:
:::note 注意
* `en` 语言环境无法从构建中删除,因为它既是后备语言环境(即,如果在语言环境中找不到翻译,则将使用 `en`)和默认语言环境(即,当用户第一次打开管理面板时使用) 时间)。
¥The `en` locale cannot be removed from the build as it is both the fallback (i.e. if a translation is not found in a locale, the `en` will be used) and the default locale (i.e. used when a user opens the administration panel for the first time).
* 可用语言环境的完整列表可在
插件的键/值对在 `/admin/src/translations/[language-name].json` 处的插件文件中独立声明。这些键/值对可以类似地在 `config.translations` 键中扩展,方法是在键前面加上插件名称(即 `[plugin name].[key]: 'value'`),如下例所示:
¥A plugin's key/value pairs are declared independently in the plugin's files at `/admin/src/translations/[language-name].json`. These key/value pairs can similarly be extended in the `config.translations` key by prefixing the key with the plugin's name (i.e. `[plugin name].[key]: 'value'`) as in the following example:
如果你需要发送额外的翻译 JSON 文件(例如,为了组织大型覆盖或支持未与 Strapi 打包在一起的语言环境),请将它们放在 `/src/admin/extensions/translations` 文件夹中,并确保语言环境代码在 `config.locales` 中列出。
¥If you need to ship additional translation JSON files—for example to organize large overrides or to support a locale not bundled with Strapi—place them in the `/src/admin/extensions/translations` folder and ensure the locale code is listed in `config.locales`.
:::tip 重建管理后台
翻译更改会在管理员重新构建时生效。如果更新没有显示,请重新运行开发服务器或重新构建管理后台以刷新打包的翻译。
¥Translation changes apply when the admin rebuilds. If updates don’t show, re-run your dev server or rebuild the admin to refresh bundled translations.
:::
# 标志
Source: https://docs.strapi.io/cms/admin-panel-customization/logos
# 标志 {#logos}
¥Logos
Strapi 的 [管理面板](/cms/admin-panel-customization) 在登录屏幕和主导航栏中均显示其品牌标识。替换这些图片可以让你将界面与你的身份相匹配。本页面展示如何通过管理面板配置覆盖这两个徽标文件。如果你希望直接在 UI 中上传,请参阅 [定制徽标](/cms/features/admin-panel#customizing-the-logo)。
¥Strapi's [admin panel](/cms/admin-panel-customization) displays its branding on both the login screen and in the main navigation. Replacing these images allows you to match the interface to your identity. The present page shows how to override the two logo files via the admin panel configuration. If you prefer uploading them directly in the UI, see [Customizing the logo](/cms/features/admin-panel#customizing-the-logo).
Strapi 管理面板在 2 个不同位置显示徽标,由管理面板配置中的 2 个不同键表示:
¥The Strapi admin panel displays a logo in 2 different locations, represented by 2 different keys in the admin panel configuration:
| 用户界面中的位置 | 要更新的配置密钥 |
| -------- | ------------------ |
| 在登录页面上 | `config.auth.logo` |
| 在主导航中 | `config.menu.logo` |
:::note 注意
通过管理面板上传的徽标将取代通过配置文件设置的任何徽标。
¥Logos uploaded via the admin panel supersede any logo set through the configuration files.
:::
### 管理面板中的徽标位置 {#logos-location-in-the-admin-panel}
¥Logos location in the admin panel
`config.auth.logo` 徽标处理的徽标仅显示在登录屏幕上:
¥The logo handled by `config.auth.logo` logo is only shown on the login screen:

`config.menu.logo` 徽标处理的徽标位于管理面板左上角的主导航中:
¥The logo handled by `config.menu.logo` logo is located in the main navigation at the top left corner of the admin panel:

### 更新徽标 {#updating-logos}
¥Updating logos
要更新徽标,请将图片文件放在 `/src/admin/extensions` 文件夹中,在 `src/admin/app` 中导入这些文件并更新相应的键,如下例所示:
¥To update the logos, put image files in the `/src/admin/extensions` folder, import these files in `src/admin/app` and update the corresponding keys as in the following example:
:::note 注意
通过配置文件设置的图片文件没有大小限制。
¥There is no size limit for image files set through the configuration files.
:::
# 主题扩展
Source: https://docs.strapi.io/cms/admin-panel-customization/theme-extension
# 主题扩展 {#theme-extension}
¥Theme extension
Strapi 的 [管理面板](/cms/admin-panel-customization) 可以以浅色或夜间模式显示(参见 [配置文件设置](/cms/getting-started/setting-up-admin-panel#setting-up-your-administrator-profile)),并且两种模式都可以通过自定义主题设置进行扩展。
¥Strapi's [admin panel](/cms/admin-panel-customization) can be displayed either in light or dark mode (see [profile setup](/cms/getting-started/setting-up-admin-panel#setting-up-your-administrator-profile)), and both can be extended through custom theme settings.
要扩展主题,请使用:
¥To extend the theme, use either:
* `config.theme.light` 键用于灯光模式
¥the `config.theme.light` key for the Light mode
* `config.theme.dark` 键用于夜间模式
¥the `config.theme.dark` key for the Dark mode
:::strapi Strapi 设计系统
默认的
# 自定义富文本编辑器
Source: https://docs.strapi.io/cms/admin-panel-customization/wysiwyg-editor
# 更改默认富文本编辑器 {#change-the-default-rich-text-editor}
¥Change the default rich text editor
Strapi 的 [管理面板](/cms/admin-panel-customization) 内置富文本编辑器。要更改默认编辑器,你可以使用以下几个选项:
¥Strapi's [admin panel](/cms/admin-panel-customization) comes with a built-in rich text editor. To change the default editor, several options are at your disposal:
* 你可以通过访问 安装第三方插件,例如 CKEditor 插件。
¥You can install a third-party plugin, such as one for CKEditor, by visiting .
* 你可以创建自己的插件来创建和注册完全自定义的所见即所得字段(参见 [自定义字段文档](/cms/features/custom-fields))。
¥You can create your own plugin to create and register a fully custom WYSIWYG field (see [custom fields documentation](/cms/features/custom-fields)).
:::tip 后续步骤
评估编辑器时,建议先从 Marketplace 下载插件进行快速试用,如果需要更深入的集成(例如架构、验证或自定义工具栏行为),则可以考虑使用自定义字段。
¥When evaluating editors, start with a plugin from the Marketplace for a quick trial, then consider a custom field if you need deeper integration (schema, validation, or custom toolbar behavior).
:::
# Strapi 客户端
Source: https://docs.strapi.io/cms/api/client
# Strapi 客户端 {#strapi-client}
¥Strapi Client
Strapi 客户端库简化了与 Strapi 后端的交互,提供了一种获取、创建、更新和删除内容的方法。本指南将引导你设置 Strapi 客户端、配置身份验证以及有效使用其主要功能。
¥The Strapi Client library simplifies interactions with your Strapi back end, providing a way to fetch, create, update, and delete content. This guide walks you through setting up the Strapi Client, configuring authentication, and using its key features effectively.
## 入门 {#getting-started}
¥Getting Started
:::prerequisites
* Strapi 项目已创建并正在运行。如果你尚未设置,请按照 [快速入门指南](/cms/quick-start) 创建一个。
¥A Strapi project has been created and is running. If you haven't set one up yet, follow the [Quick Start Guide](/cms/quick-start) to create one.
* 你知道 Strapi 实例的内容 API 的 URL(例如 `http://localhost:1337/api`)。
¥You know the URL of the Content API of your Strapi instance (e.g., `http://localhost:1337/api`).
:::
### 安装 {#installation}
¥Installation
要在你的项目中使用 Strapi 客户端,请使用你首选的包管理器将其作为依赖安装:
¥To use the Strapi Client in your project, install it as a dependency using your preferred package manager:
### 基本配置 {#basic-configuration}
¥Basic configuration
要开始与 Strapi 后端交互,请初始化 Strapi 客户端并设置基本 API URL:
¥To start interacting with your Strapi back end, initialize the Strapi Client and set the base API URL:
`baseURL` 必须包含协议(`http` 或 `https`)。无效的 URL 将引发错误 `StrapiInitializationError`。
¥The `baseURL` must include the protocol (`http` or `https`). An invalid URL will throw an error `StrapiInitializationError`.
### 验证 {#authentication}
¥Authentication
Strapi 客户端支持不同的身份验证策略来访问 Strapi 后端中受保护的资源。
¥The Strapi Client supports different authentication strategies to access protected resources in your Strapi back end.
如果你的 Strapi 实例使用 [API 令牌](/cms/features/api-tokens),请按如下方式配置 Strapi 客户端:
¥If your Strapi instance uses [API tokens](/cms/features/api-tokens), configure the Strapi Client as follows:
```js
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token-here',
});
```
这允许你的请求自动包含必要的身份验证凭据。如果令牌无效或缺失,客户端将在初始化 `StrapiValidationError` 时抛出错误。
¥This allows your requests to include the necessary authentication credentials automatically.
If the token is invalid or missing, the client will throw an error during initialization `StrapiValidationError`.
## API 参考 {#api-reference}
¥API Reference
Strapi 客户端提供以下关键属性和方法用于与你的 Strapi 后端交互:
¥The Strapi Client provides the following key properties and methods for interacting with your Strapi back end:
| 范围 | 描述 |
| -------------- | ---------------------------------- |
| `baseURL` | Strapi 后端的基本 API URL。 |
| `fetch()` | 一种用于发出类似于原生获取 API 的通用 API 请求的实用方法。 |
| `collection()` | 管理集合类型资源(例如,博客文章、产品)。 |
| `single()` | 管理单一类型资源(例如,主页设置、全局配置)。 |
| `files()` | 支持直接从 Strapi 媒体库上传、检索和管理文件。 |
### 通用获取 {#general-purpose-fetch}
¥General purpose fetch
Strapi 客户端提供对底层 JavaScript `fetch` 函数的访问,以发出直接 API 请求。请求始终与客户端初始化期间提供的基本 URL 相关:
¥The Strapi Client provides access to the underlying JavaScript `fetch` function to make direct API requests. The request is always relative to the base URL provided during client initialization:
```js
const result = await client.fetch('articles', { method: 'GET' });
```
### 使用集合类型 {#working-with-collection-types}
¥Working with collection types
Strapi 中的集合类型是具有多个条目的实体(例如,包含多篇帖子的博客)。Strapi 客户端提供了一种 `collection()` 方法来与这些资源交互,可用的方法如下:
¥Collection types in Strapi are entities with multiple entries (e.g., a blog with many posts). The Strapi Client provides a `collection()` method to interact with these resources, with the following methods available:
| 范围 | 描述 |
| ---------------------------------------- | -------------------- |
| `find(queryParams?)` | 获取具有可选过滤、排序或分页的多个文档。 |
| `findOne(documentID, queryParams?)` | 通过其唯一 ID 检索单个文档。 |
| `create(data, queryParams?)` | 在集合中创建一个新文档。 |
| `update(documentID, data, queryParams?)` | 更新现有文档。 |
| `delete(documentID, queryParams?)` | 更新现有文档。 |
**使用示例:**
¥**Usage examples:**
### 使用单一类型 {#working-with-single-types}
¥Working with single types
Strapi 中的单一类型代表仅存在一次的唯一内容条目(例如,主页设置或站点范围的配置)。Strapi 客户端提供了一种 `single()` 方法来与这些资源交互,可用的方法如下:
¥Single types in Strapi represent unique content entries that exist only once (e.g., the homepage settings or site-wide configurations). The Strapi Client provides a `single()` method to interact with these resources, with the following methods available:
| 范围 | 描述 |
| ---------------------------------------- | ----- |
| `find(queryParams?)` | 获取文档。 |
| `update(documentID, data, queryParams?)` | 更新文档。 |
| `delete(queryParams?)` | 删除文档。 |
**使用示例:**
¥**Usage examples:**
```js
const homepage = client.single('homepage');
// Fetch the default homepage content
const defaultHomepage = await homepage.find();
// Fetch the Spanish version of the homepage
const spanishHomepage = await homepage.find({ locale: 'es' });
// Update the homepage draft content
const updatedHomepage = await homepage.update(
{ title: 'Updated Homepage Title' },
{ status: 'draft' }
);
// Delete the homepage content
await homepage.delete();
```
### 使用文件 {#working-with-files}
¥Working with files
Strapi 客户端通过 `files` 属性提供对 [媒体库](/cms/features/media-library) 的访问。这允许你检索和管理文件元数据,而无需直接与 REST API 交互。
¥The Strapi Client provides access to the [Media Library](/cms/features/media-library) via the `files` property. This allows you to retrieve and manage file metadata without directly interacting with the REST API.
以下方法可用于处理文件。点击表格中的方法名称可跳转到相应的部分,其中包含更多详细信息和示例:
¥The following methods are available for working with files. Click on the method name in the table to jump to the corresponding section with more details and examples:
| 方法 | 描述 |
| ------------------------------------- | ----------------------------------------------- |
| [`find(params?)`](#find) | 根据可选查询参数检索文件元数据列表 |
| [`findOne(fileId)`](#findone) | 通过 ID 检索单个文件的元数据 |
| [`update(fileId, fileInfo)`](#update) | 更新现有文件的元数据 |
| [`upload(file, options)`](#upload) | 上传文件(Blob 或 Buffer),并附带一个可选的 `options` 对象作为元数据。 |
| [`delete(fileId)`](#delete) | 通过 ID 删除文件 |
#### `find` {#find}
`strapi.client.files.find()` 方法根据可选查询参数检索文件元数据列表。
¥The `strapi.client.files.find()` method retrieves a list of file metadata based on optional query parameters.
该方法的使用方式如下:
¥The method can be used as follows:
```js
// Initialize the client
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token',
});
// Find all file metadata
const allFiles = await client.files.find();
console.log(allFiles);
// Find file metadata with filtering and sorting
const imageFiles = await client.files.find({
filters: {
mime: { $contains: 'image' }, // Only get image files
name: { $contains: 'avatar' }, // Only get files with 'avatar' in the name
},
sort: ['name:asc'], // Sort by name in ascending order
});
```
#### `findOne` {#findone}
`strapi.client.files.findOne()` 方法通过单个文件的 ID 检索其元数据。
¥The `strapi.client.files.findOne()` method retrieves the metadata for a single file by its id.
该方法的使用方式如下:
¥The method can be used as follows:
```js
// Initialize the client
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token',
});
// Find file metadata by ID
const file = await client.files.findOne(1);
console.log(file.name);
console.log(file.url);
console.log(file.mime); // The file MIME type
```
#### `update` {#update}
`strapi.client.files.update()` 方法更新现有文件的元数据,接受两个参数:`fileId` 和一个包含媒体名称、替代文本和标题等选项的对象。
¥The `strapi.client.files.update()` method updates metadata for an existing file, accepting 2 parameters, the `fileId`, and an object containing options such as the name, alternative text, and caption for the media.
这些方法的使用方式如下:
¥The methods can be used as follows:
```js
// Initialize the client
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token',
});
// Update file metadata
const updatedFile = await client.files.update(1, {
name: 'New file name',
alternativeText: 'Descriptive alt text for accessibility',
caption: 'A caption for the file',
});
```
#### `upload`
##### 响应结构 {#response-structure}
¥Response Structure
`strapi.client.files.upload()` 方法返回一个文件对象数组,每个对象包含如下字段:
¥The `strapi.client.files.upload()` method returns an array of file objects, each with fields such as:
```json
{
"id": 1,
"name": "image.png",
"alternativeText": "Uploaded from Node.js Buffer",
"caption": "Example upload",
"mime": "image/png",
"url": "/uploads/image.png",
"size": 12345,
"createdAt": "2025-07-23T12:34:56.789Z",
"updatedAt": "2025-07-23T12:34:56.789Z"
}
```
:::note 其他响应字段
上传响应包含除上述字段之外的其他字段。有关所有可用字段,请参阅 中的完整 FileResponse 接口。
¥The upload response includes additional fields beyond those shown above. See the complete FileResponse interface in the for all available fields.
:::
#### `delete` {#delete}
`strapi.client.files.delete()` 方法通过文件 ID 删除文件。
¥The `strapi.client.files.delete()` method deletes a file by its ID.
该方法的使用方式如下:
¥The method can be used as follows:
```js
// Initialize the client
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token',
});
// Delete a file by ID
const deletedFile = await client.files.delete(1);
console.log('File deleted successfully');
console.log('Deleted file ID:', deletedFile.id);
console.log('Deleted file name:', deletedFile.name);
```
## 常见错误处理 {#handling-common-errors}
¥Handling Common Errors
通过 Strapi 客户端发送查询时可能会出现以下错误:
¥The following errors might occur when sending queries through the Strapi Client:
| 错误 | 描述 |
| ------- | ------------------------------------------------------------------------ |
| 权限错误 | 如果经过身份验证的用户没有上传或管理文件的权限,则会抛出 `FileForbiddenError` 错误。 |
| HTTP 错误 | 如果服务器无法访问、身份验证失败或出现网络问题,则会抛出 `HTTPError` 错误。 |
| 缺少参数 | 上传 `Buffer` 时,必须在选项对象中同时提供 `filename` 和 `mimetype` 属性。如果缺少其中任何一个,则会引发错误。 |
:::strapi 附加信息
有关 Strapi 客户端的更多详细信息,请参阅 。
¥More details about the Strapi Client may be found in the .
:::
# 内容 API
Source: https://docs.strapi.io/cms/api/content-api
# 用于访问你的内容的 Strapi API {#strapi-apis-to-access-your-content}
¥Strapi APIs to access your content
创建并配置 Strapi 项目、使用 [内容类型生成器](/cms/features/content-type-builder) 创建内容结构并开始通过 [内容管理者](/cms/features/content-manager) 添加数据后,你可能希望访问你的内容。
¥Once you've created and configured a Strapi project, created a content structure with the [Content-Type Builder](/cms/features/content-type-builder) and started adding data through the [Content Manager](/cms/features/content-manager), you likely would like to access your content.
从前端应用,你的内容可以通过 Strapi 的 Content API 访问,该 API 公开:
¥From a front-end application, your content can be accessed through Strapi's Content API, which is exposed:
* 默认通过 [REST API](/cms/api/rest)
¥by default through the [REST API](/cms/api/rest)
* 如果你安装了 Strapi 内置 [GraphQL 插件](/cms/plugins/graphql),也可以通过 [GraphQL API](/cms/api/graphql)。
¥and also through the [GraphQL API](/cms/api/graphql) if you installed the Strapi built-in [GraphQL plugin](/cms/plugins/graphql).
你还可以使用 [Strapi 客户端](/cms/api/client) 库与 REST API 交互。
¥You can also use the [Strapi Client](/cms/api/client) library to interact with the REST API.
REST 和 GraphQL API 代表暴露给外部应用的 Content API 的顶层。Strapi 还提供 2 个更底层的 API:
¥REST and GraphQL APIs represent the top-level layers of the Content API exposed to external applications. Strapi also provides 2 lower-level APIs:
* [文档服务 API](/cms/api/document-service) 可通过 `strapi.documents` 访问,它是推荐的 API,用于在 [后端服务器](/cms/customization) 或通过 [plugins](/cms/plugins-development/developing-plugins) 与应用的数据库进行交互。文档服务是处理文档
# 文档
Source: https://docs.strapi.io/cms/api/document
# 文档 {#documents}
¥Documents
Strapi 5 中的文档是仅限 API 的概念。文档代表内容类型给定条目的所有不同内容变体。
¥A **document** in Strapi 5 is an API-only concept. A document represents all the different variations of content for a given entry of a content-type.
单一类型包含一个唯一文档,而集合类型可以包含多个文档。
¥A single type contains a unique document, and a collection type can contain several documents.
当你使用管理面板时,文档的概念从未被提及,并且对于终端用户来说不是必需的。用户在 [内容管理者](/cms/features/content-manager) 中创建和编辑条目。例如,作为用户,你可以列出给定语言环境的条目,也可以编辑给定语言环境中特定条目的草稿版本。
¥When you use the admin panel, the concept of a document is never mentioned and not necessary for the end user. Users create and edit **entries** in the [Content Manager](/cms/features/content-manager). For instance, as a user, you either list the entries for a given locale, or edit the draft version of a specific entry in a given locale.
但是,在 API 级别,条目字段的值实际上可以具有:
¥However, at the API level, the value of the fields of an entry can actually have:
* 英语和法语语言环境的内容不同,
¥different content for the English and the French locale,
* 甚至在每个语言环境中为草稿和已发布版本设置不同的内容。
¥and even different content for the draft and published version in each locale.
包含所有语言环境的所有草稿和已发布版本内容的存储桶是一个文档。
¥The bucket that includes the content of all the draft and published versions for all the locales is a document.
使用 [文档服务 API](/cms/api/document-service) 操作文档将帮助你创建、检索、更新和删除文档或它们包含的特定数据子集。
¥Manipulating documents with the [Document Service API](/cms/api/document-service) will help you create, retrieve, update, and delete documents or a specific subset of the data they contain.
下图表示内容的所有可能变化,具体取决于为内容类型启用了哪些功能(例如 [国际化(i18n)](/cms/features/internationalization) 和 [起草并发布](/cms/features/draft-and-publish)):
¥The following diagrams represent all the possible variations of content depending on which features, such as [Internationalization (i18n)](/cms/features/internationalization) and [Draft & Publish](/cms/features/draft-and-publish), are enabled for a content-type:
* 如果在内容类型上启用了国际化(i18n)功能,则文档可以有多个文档语言环境。
¥If the Internationalization (i18n) feature is enabled on the content-type, a document can have multiple **document locales**.
* 如果在内容类型上启用了草稿和发布功能,则文档可以具有已发布版本和草稿版本。
¥If the Draft & Publish feature is enabled on the content-type, a document can have a **published** and a **draft** version.
:::strapi 用于查询文档数据的 API
要与文档或它们所代表的数据进行交互:
¥To interact with documents or the data they represent:
* 从后端服务器(例如,从控制器、服务和插件的后端部分)使用 [文档服务 API](/cms/api/document-service)。
¥From the back-end server (for instance, from controllers, services, and the back-end part of plugins), use the [Document Service API](/cms/api/document-service).
* 从应用的前端部分,使用 [REST API](/cms/api/rest) 或 [GraphQL API](/cms/api/graphql) 查询数据。
¥From the front-end part of your application, query your data using the [REST API](/cms/api/rest) or the [GraphQL API](/cms/api/graphql).
有关 API 的更多信息,请参阅 [内容 API 介绍](/cms/api/content-api)。
¥For additional information about the APIs, please refer to the [Content API introduction](/cms/api/content-api).
:::
:::info 返回结果中的默认版本
后端和前端 API 之间的一个重要区别是关于未传递参数时返回的默认版本:
¥An important difference between the back-end and front-end APIs is about the default version returned when no parameter is passed:
* 文档服务 API 默认返回草稿版本,
¥The Document Service API returns the draft version by default,
* 而 REST 和 GraphQL API 默认返回已发布的版本。
¥while REST and GraphQL APIs return the published version by default.
:::
# 文档服务 API
Source: https://docs.strapi.io/cms/api/document-service
# 文档服务 API {#document-service-api}
¥Document Service API
文档服务 API 建立在查询引擎 API 之上
¥The Document Service API is built on top of the **Query Engine API**
用于对文档
:::strapi 实体服务 API 在 Strapi 5 中已弃用
文档服务 API 取代了 Strapi v4 中使用的实体服务 API (
如果找到匹配的文档,`findOne()` 方法返回该文档,否则返回 `null`。
¥The `findOne()` method returns the matching document if found, otherwise returns `null`.
## `findFirst()` {#findfirst}
查找与参数匹配的第一个文档。
¥Find the first document matching the parameters.
语法:`findFirst(parameters: Params) => Document`
¥Syntax: `findFirst(parameters: Params) => Document`
### 参数 {#parameters-1}
¥Parameters
| 范围 | 描述 | 默认 | 类型 |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | ------------------------- |
| [`locale`](/cms/api/document-service/locale#find-first) | 要查找的文档的语言环境。 | 默认语言环境 | 字符串或 `undefined` |
| [`status`](/cms/api/document-service/status#find-first) | 如果为内容类型启用了 [起草并发布](/cms/features/draft-and-publish): 发布状态,可以是:
`'published'` 仅查找已发布的文档
`'draft'` 仅查找草稿文档
| `'draft'` | `'published'` 或 `'draft'` |
| [`filters`](/cms/api/document-service/filters) | 使用 [过滤器](/cms/api/document-service/filters) | `null` | 目的 |
| [`fields`](/cms/api/document-service/fields#findfirst) | [选择字段](/cms/api/document-service/fields#findfirst) 返回 | 所有字段 (默认情况下未填充的字段除外) | 目的 |
| [`populate`](/cms/api/document-service/populate) | [填充](/cms/api/document-service/populate) 结果带有附加字段。 | `null` | 目的 |
### 示例 {#examples}
¥Examples
#### 通用示例 {#generic-example}
¥Generic example
默认情况下,`findFirst()` 在默认语言环境中返回传递的唯一标识符(集合类型 ID 或单一类型 ID)的第一个文档的草稿版本:
¥By default, `findFirst()` returns the draft version, in the default locale, of the first document for the passed unique identifier (collection type id or single type id):
#### 查找与参数匹配的第一个文档 {#find-the-first-document-matching-parameters}
¥Find the first document matching parameters
将一些参数传递给 `findFirst()` 以返回与它们匹配的第一个文档。
¥Pass some parameters to `findFirst()` to return the first document matching them.
如果没有传递 `locale` 或 `status` 参数,则结果将返回默认区域设置的草稿版本:
¥If no `locale` or `status` parameters are passed, results return the draft version for the default locale:
## `findMany()` {#findmany}
查找与参数匹配的文档。
¥Find documents matching the parameters.
语法:`findMany(parameters: Params) => Document[]`
¥Syntax: `findMany(parameters: Params) => Document[]`
### 参数 {#parameters-2}
¥Parameters
| 范围 | 描述 | 默认 | 类型 |
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | ------------------------- |
| [`locale`](/cms/api/document-service/locale#find-many) | 要查找的文档的语言环境。 | 默认语言环境 | 字符串或 `undefined` |
| [`status`](/cms/api/document-service/status#find-many) | 如果为内容类型启用了 [起草并发布](/cms/features/draft-and-publish): 发布状态,可以是:
`'published'` 仅查找已发布的文档
`'draft'` 仅查找草稿文档
| `'draft'` | `'published'` 或 `'draft'` |
| [`filters`](/cms/api/document-service/filters) | 使用 [过滤器](/cms/api/document-service/filters) | `null` | 目的 |
| [`fields`](/cms/api/document-service/fields#findmany) | [选择字段](/cms/api/document-service/fields#findmany) 返回 | 所有字段 (默认情况下未填充的字段除外) | 目的 |
| [`populate`](/cms/api/document-service/populate) | [填充](/cms/api/document-service/populate) 结果带有附加字段。 | `null` | 目的 |
| [`pagination`](/cms/api/document-service/sort-pagination#pagination) | [分页](/cms/api/document-service/sort-pagination#pagination) 结果 | | |
| [`sort`](/cms/api/document-service/sort-pagination#sort) | [排序](/cms/api/document-service/sort-pagination#sort) 结果 | | |
### 示例 {#examples-1}
¥Examples
#### 通用示例 {#generic-example-1}
¥Generic example
未传递任何参数时,`findMany()` 会为每个文档返回默认语言环境中的草稿版本:
¥When no parameter is passed, `findMany()` returns the draft version in the default locale for each document:
#### 查找与参数匹配的文档 {#find-documents-matching-parameters}
¥Find documents matching parameters
可用的过滤器在文档服务 API 参考的 [filters](/cms/api/document-service/filters) 页面中有详细说明。
¥Available filters are detailed in the [filters](/cms/api/document-service/filters) page of the Document Service API reference.
如果没有传递 `locale` 或 `status` 参数,则结果将返回默认区域设置的草稿版本:
¥If no `locale` or `status` parameters are passed, results return the draft version for the default locale:
## `create()` {#create}
创建草稿文档并返回它。
¥Creates a drafted document and returns it.
传递要在 `data` 对象中创建的内容的字段。
¥Pass fields for the content to create in a `data` object.
语法:`create(parameters: Params) => Document`
¥Syntax: `create(parameters: Params) => Document`
### 参数 {#parameters-3}
¥Parameters
| 范围 | 描述 | 默认 | 类型 |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------ | ---------------- |
| [`locale`](/cms/api/document-service/locale#create) | 要创建的文档的语言环境。 | 默认语言环境 | 字符串或 `undefined` |
| [`fields`](/cms/api/document-service/fields#create) | [选择字段](/cms/api/document-service/fields#create) 返回 | 所有字段 (默认情况下未填充的字段除外) | 目的 |
| [`status`](/cms/api/document-service/status#create) | 如果为内容类型启用了 [起草并发布](/cms/features/draft-and-publish): 可以设置为 `'published'` 以在创建文档时自动发布文档的草稿版本 | * | `'published'` |
| [`populate`](/cms/api/document-service/populate) | [填充](/cms/api/document-service/populate) 结果带有附加字段。 | `null` | 目的 |
### 示例 {#example-1}
¥Example
如果没有传递 `locale` 参数,则 `create()` 将为默认区域设置创建文档的草稿版本:
¥If no `locale` parameter is passed, `create()` creates the draft version of the document for the default locale:
:::tip 提示
如果内容类型启用了 [起草并发布](/cms/features/draft-and-publish) 功能,你可以在创建文档时自动发布文档(参见 [`status` 文档](/cms/api/document-service/status#create))。
¥If the [Draft & Publish](/cms/features/draft-and-publish) feature is enabled on the content-type, you can automatically publish a document while creating it (see [`status` documentation](/cms/api/document-service/status#create)).
:::
## `update()` {#update}
更新文档版本并返回它们。
¥Updates document versions and returns them.
语法:`update(parameters: Params) => Promise
## `delete()` {#delete}
删除一个文档或其特定语言环境。
¥Deletes one document, or a specific locale of it.
语法:`delete(parameters: Params): Promise<{ documentId: ID, entries: Number }>`
¥Syntax: `delete(parameters: Params): Promise<{ documentId: ID, entries: Number }>`
### 参数 {#parameters-5}
¥Parameters
| 范围 | 描述 | 默认 | 类型 |
| --------------------------------------------------- | -------------------------------------------------- | ------------------------ | ------------------ |
| `documentId` | 文档 ID | | `ID` |
| [`locale`](/cms/api/document-service/locale#delete) | 要删除的文档的语言环境版本。 | `null` (仅删除默认语言环境) | 字符串、`'*'` 或 `null` |
| [`filters`](/cms/api/document-service/filters) | 使用 [过滤器](/cms/api/document-service/filters) | `null` | 目的 |
| [`fields`](/cms/api/document-service/fields#delete) | [选择字段](/cms/api/document-service/fields#delete) 返回 | 所有字段 (默认情况下未填充的字段除外) | 目的 |
| [`populate`](/cms/api/document-service/populate) | [填充](/cms/api/document-service/populate) 结果带有附加字段。 | `null` | 目的 |
### 示例 {#example-3}
¥Example
如果没有传递 `locale` 参数,则 `delete()` 仅删除文档的默认区域设置版本。这将删除草稿版本和已发布版本:
¥If no `locale` parameter is passed, `delete()` only deletes the default locale version of a document. This deletes both the draft and published versions:
## `publish()` {#publish}
已发布的版本是只读的,因此你无法从技术上更新文档的已发布版本。
¥Publishes one or multiple locales of a document.
仅当在内容类型上启用 [起草并发布](/cms/features/draft-and-publish) 时,此方法才可用。
¥This method is only available if [Draft & Publish](/cms/features/draft-and-publish) is enabled on the content-type.
语法:`publish(parameters: Params): Promise<{ documentId: ID, entries: Number }>`
¥Syntax: `publish(parameters: Params): Promise<{ documentId: ID, entries: Number }>`
### 参数 {#parameters-6}
¥Parameters
| 范围 | 描述 | 默认 | 类型 |
| ---------------------------------------------------- | --------------------------------------------------- | ------------------------ | ------------------ |
| `documentId` | 文档 ID | | `ID` |
| [`locale`](/cms/api/document-service/locale#publish) | 要发布的文档的语言环境。 | 仅默认语言环境 | 字符串、`'*'` 或 `null` |
| [`filters`](/cms/api/document-service/filters) | 使用 [过滤器](/cms/api/document-service/filters) | `null` | 目的 |
| [`fields`](/cms/api/document-service/fields#publish) | [选择字段](/cms/api/document-service/fields#publish) 返回 | 所有字段 (默认情况下未填充的字段除外) | 目的 |
| [`populate`](/cms/api/document-service/populate) | [填充](/cms/api/document-service/populate) 结果带有附加字段。 | `null` | 目的 |
### 示例 {#example-4}
¥Example
如果没有传递 `locale` 参数,`publish()` 仅发布文档的默认语言环境版本:
¥If no `locale` parameter is passed, `publish()` only publishes the default locale version of the document:
## `unpublish()` {#unpublish}
取消发布文档的一个或所有语言环境版本,并返回未发布的语言环境版本数。
¥Unpublishes one or all locale versions of a document, and returns how many locale versions were unpublished.
仅当在内容类型上启用 [起草并发布](/cms/features/draft-and-publish) 时,此方法才可用。
¥This method is only available if [Draft & Publish](/cms/features/draft-and-publish) is enabled on the content-type.
语法:`unpublish(parameters: Params): Promise<{ documentId: ID, entries: Number }>`
¥Syntax: `unpublish(parameters: Params): Promise<{ documentId: ID, entries: Number }>`
### 参数 {#parameters-7}
¥Parameters
| 范围 | 描述 | 默认 | 类型 |
| ------------------------------------------------------ | ----------------------------------------------------- | ------------------------ | ------------------ |
| `documentId` | 文档 ID | | `ID` |
| [`locale`](/cms/api/document-service/locale#unpublish) | 要取消发布的文档的语言环境。 | 仅默认语言环境 | 字符串、`'*'` 或 `null` |
| [`filters`](/cms/api/document-service/filters) | 使用 [过滤器](/cms/api/document-service/filters) | `null` | 目的 |
| [`fields`](/cms/api/document-service/fields#unpublish) | [选择字段](/cms/api/document-service/fields#unpublish) 返回 | 所有字段 (默认情况下未填充的字段除外) | 目的 |
| [`populate`](/cms/api/document-service/populate) | [填充](/cms/api/document-service/populate) 结果带有附加字段。 | `null` | 目的 |
### 示例 {#example-5}
¥Example
如果没有传递 `locale` 参数,`unpublish()` 仅取消发布文档的默认语言环境版本:
¥If no `locale` parameter is passed, `unpublish()` only unpublishes the default locale version of the document:
## `discardDraft()` {#discarddraft}
丢弃草稿数据并用已发布的版本覆盖它。
¥Discards draft data and overrides it with the published version.
仅当在内容类型上启用 [起草并发布](/cms/features/draft-and-publish) 时,此方法才可用。
¥This method is only available if [Draft & Publish](/cms/features/draft-and-publish) is enabled on the content-type.
语法:`discardDraft(parameters: Params): Promise<{ documentId: ID, entries: Number }>`
¥Syntax: `discardDraft(parameters: Params): Promise<{ documentId: ID, entries: Number }>`
### 参数 {#parameters-8}
¥Parameters
| 范围 | 描述 | 默认 | 类型 |
| ---------------------------------------------------------- | -------------------------------------------------------- | ------------------------ | ------------------ |
| `documentId` | 文档 ID | | `ID` |
| [`locale`](/cms/api/document-service/locale#discard-draft) | 要丢弃的文档的语言环境。 | 仅默认语言环境。 | 字符串、`'*'` 或 `null` |
| [`filters`](/cms/api/document-service/filters) | 使用 [过滤器](/cms/api/document-service/filters) | `null` | 目的 |
| [`fields`](/cms/api/document-service/fields#discarddraft) | [选择字段](/cms/api/document-service/fields#discarddraft) 返回 | 所有字段 (默认情况下未填充的字段除外) | 目的 |
| [`populate`](/cms/api/document-service/populate) | [填充](/cms/api/document-service/populate) 结果带有附加字段。 | `null` | 目的 |
### 示例 {#example-6}
¥Example
如果没有传递 `locale` 参数,则 `discardDraft()` 将丢弃草稿数据,并使用仅针对默认区域设置的已发布版本覆盖它:
¥If no `locale` parameter is passed, `discardDraft()` discards draft data and overrides it with the published version only for the default locale:
## `count()` {#count}
计算与提供的参数匹配的文档数量。
¥Count the number of documents that match the provided parameters.
语法:`count(parameters: Params) => number`
¥Syntax: `count(parameters: Params) => number`
### 参数 {#parameters-9}
¥Parameters
| 范围 | 描述 | 默认 | 类型 |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------------------------- |
| [`locale`](/cms/api/document-service/locale#count) | 要计数的文档的语言环境 | 默认语言环境 | 字符串或 `null` |
| [`status`](/cms/api/document-service/status#count) | 如果为内容类型启用了 [起草并发布](/cms/features/draft-and-publish): 发布状态,可以是:
`'published'` 仅查找已发布的文档
`'draft'` 仅查找草稿文档(将返回所有文档)
| `'draft'` | `'published'` 或 `'draft'` |
| [`filters`](/cms/api/document-service/filters) | 使用 [过滤器](/cms/api/document-service/filters) | `null` | 目的 |
:::note 注意
由于已发布的文档必然也有草稿副本,因此已发布的文档仍算作具有草稿版本。
¥Since published documents necessarily also have a draft counterpart, a published document is still counted as having a draft version.
这意味着使用 `status: 'draft'` 参数计数仍会返回与其他参数匹配的文档总数,即使某些文档已经发布并且不再在内容管理器中显示为 "draft" 或 "modified"。目前没有办法阻止已发布的文档被计算在内。
¥This means that counting with the `status: 'draft'` parameter still returns the total number of documents matching other parameters, even if some documents have already been published and are not displayed as "draft" or "modified" in the Content Manager anymore. There currently is no way to prevent already published documents from being counted.
:::
### 示例 {#examples-2}
¥Examples
#### 通用示例 {#generic-example-2}
¥Generic example
如果未传递任何参数,`count()` 方法将返回默认语言环境的文档总数:
¥If no parameter is passed, the `count()` method the total number of documents for the default locale:
#### 计数已发布的文档 {#count-published-documents}
¥Count published documents
若要仅统计已发布的文档,请将 `status: 'published'` 与其他参数一起传递给 `count()` 方法。
¥To count only published documents, pass `status: 'published'` along with other parameters to the `count()` method.
如果没有传递 `locale` 参数,则文档将按默认语言环境进行计数。
¥If no `locale` parameter is passed, documents are counted for the default locale.
#### 使用过滤器计数文档 {#count-documents-with-filters}
¥Count documents with filters
任何 [filters](/cms/api/document-service/filters) 都可以传递给 `count()` 方法。
¥Any [filters](/cms/api/document-service/filters) can be passed to the `count()` method.
如果没有传递 `locale` 和 `status` 参数,则草稿文档(即该区域可用文档的总数,因为即使已发布的文档也算作具有草稿版本)仅针对默认区域进行计数:
¥If no `locale` and no `status` parameter is passed, draft documents (which is the total of available documents for the locale since even published documents are counted as having a draft version) are counted only for the default locale:
```js
/**
* Count number of draft documents (default if status is omitted)
* in English (default locale)
* whose name starts with 'Pizzeria'
*/
strapi.documents('api::restaurant.restaurant').count({ filters: { name: { $startsWith: "Pizzeria" }}})`
```
# 使用文档服务 API 的字段
Source: https://docs.strapi.io/cms/api/document-service/fields
# 文档服务 API:选择字段 {#document-service-api-selecting-fields}
¥Document Service API: Selecting fields
默认情况下,[文档服务 API](/cms/api/document-service) 返回文档的所有字段,但不填充任何字段。本页介绍如何使用 `fields` 参数仅返回查询结果中的特定字段。
¥By default the [Document Service API](/cms/api/document-service) returns all the fields of a document but does not populate any fields. This page describes how to use the `fields` parameter to return only specific fields with the query results.
:::tip 提示
你还可以使用 `populate` 参数来填充关系、媒体字段、组件或动态区域(请参阅 [`populate` 参数](/cms/api/document-service/populate) 文档)。
¥You can also use the `populate` parameter to populate relations, media fields, components, or dynamic zones (see the [`populate` parameter](/cms/api/document-service/populate) documentation).
:::
## 选择带有 `findFirst()` 查询的字段 {#findfirst}
¥Select fields with `findFirst()` queries
要选择 [查找第一个文档](/cms/api/document-service#findfirst) 与文档服务 API 匹配参数时要返回的字段:
¥To select fields to return while [finding the first document](/cms/api/document-service#findfirst) matching the parameters with the Document Service API:
## 选择带有 `findMany()` 查询的字段 {#findmany}
¥Select fields with `findMany()` queries
要选择 [查找文档](/cms/api/document-service#findmany) 与文档服务 API 匹配时要返回的字段:
¥To select fields to return while [finding documents](/cms/api/document-service#findmany) with the Document Service API:
## 选择带有 `create()` 查询的字段 {#create}
¥Select fields with `create()` queries
要选择 [创建文档](/cms/api/document-service#create) 与文档服务 API 匹配时要返回的字段:
¥To select fields to return while [creating documents](/cms/api/document-service#create) with the Document Service API:
## 选择带有 `update()` 查询的字段 {#update}
¥Select fields with `update()` queries
要选择 [更新文档](/cms/api/document-service#update) 与文档服务 API 匹配时要返回的字段:
¥To select fields to return while [updating documents](/cms/api/document-service#update) with the Document Service API:
## 选择带有 `delete()` 查询的字段 {#delete}
¥Select fields with `delete()` queries
要选择 [删除文档](/cms/api/document-service#delete) 与文档服务 API 匹配时要返回的字段:
¥To select fields to return while [deleting documents](/cms/api/document-service#delete) with the Document Service API:
## 选择带有 `publish()` 查询的字段 {#publish}
¥Select fields with `publish()` queries
要选择 [发布文档](/cms/api/document-service#publish) 与文档服务 API 匹配时要返回的字段:
¥To select fields to return while [publishing documents](/cms/api/document-service#publish) with the Document Service API:
## 选择带有 `unpublish()` 查询的字段 {#unpublish}
¥Select fields with `unpublish()` queries
要选择 [取消发布文档](/cms/api/document-service#unpublish) 与文档服务 API 匹配时要返回的字段:
¥To select fields to return while [unpublishing documents](/cms/api/document-service#unpublish) with the Document Service API:
## 选择带有 `discardDraft()` 查询的字段 {#discarddraft}
¥Select fields with `discardDraft()` queries
要选择 [丢弃文档的草稿版本](/cms/api/document-service#discarddraft) 与文档服务 API 匹配时要返回的字段:
¥To select fields to return while [discarding draft versions of documents](/cms/api/document-service#discarddraft) with the Document Service API:
# 使用文档服务 API 过滤器
Source: https://docs.strapi.io/cms/api/document-service/filters
# 文档服务 API:过滤器 {#document-service-api-filters}
¥Document Service API: Filters
[文档服务 API](/cms/api/document-service) 提供了过滤结果的能力。
¥The [Document Service API](/cms/api/document-service) offers the ability to filter results.
可以使用以下运算符:
¥The following operators are available:
| 运算符 | 描述 |
| -------------------------------- | ----------------- |
| [`$eq`](#eq) | 平等的 |
| [`$eqi`](#eqi) | 等于(不区分大小写) |
| [`$ne`](#ne) | 不等于 |
| [`$nei`](#nei) | 不等于(不区分大小写) |
| [`$lt`](#lt) | 少于 |
| [`$lte`](#lte) | 小于或等于 |
| [`$gt`](#gt) | 比...更棒 |
| [`$gte`](#gte) | 大于或等于 |
| [`$in`](#in) | 包含在数组中 |
| [`$notIn`](#notin) | 不包含在数组中 |
| [`$contains`](#contains) | 包含 |
| [`$notContains`](#notcontains) | 不含 |
| [`$containsi`](#containsi) | 包含(不区分大小写) |
| [`$notContainsi`](#notcontainsi) | 不包含(不区分大小写) |
| [`$null`](#null) | 一片空白 |
| [`$notNull`](#notnull) | 不为空 |
| [`$between`](#between) | 在。。。之间 |
| [`$startsWith`](#startswith) | 以。。开始 |
| [`$startsWithi`](#startswithi) | 开头为(不区分大小写) |
| [`$endsWith`](#endswith) | 以。。结束 |
| [`$endsWithi`](#endswithi) | 结尾为(不区分大小写) |
| [`$or`](#or) | 连接 "or" 表达式中的过滤器 |
| [`$and`](#and) | 连接 "and" 表达式中的过滤器 |
| [`$not`](#not) | 连接 "not" 表达式中的过滤器 |
## 属性运算符 {#attribute-operators}
¥Attribute operators
### `$not` {#not}
否定嵌套条件。
¥Negates the nested condition(s).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$not: {
$contains: 'Hello World',
},
},
},
});
```
### `$eq` {#eq}
属性等于输入值。
¥Attribute equals input value.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$eq: 'Hello World',
},
},
});
```
`$eq` 可以省略:
¥`$eq` can be omitted:
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: 'Hello World',
},
});
```
### `$eqi` {#eqi}
属性等于输入值(不区分大小写)。
¥Attribute equals input value (case-insensitive).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$eqi: 'HELLO World',
},
},
});
```
### `$ne` {#ne}
属性不等于输入值。
¥Attribute does not equal input value.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$ne: 'ABCD',
},
},
});
```
### `$nei` {#nei}
属性不等于输入值(不区分大小写)。
¥Attribute does not equal input value (case-insensitive).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$nei: 'abcd',
},
},
});
```
### `$in` {#in}
属性包含在输入列表中。
¥Attribute is contained in the input list.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$in: ['Hello', 'Hola', 'Bonjour'],
},
},
});
```
传递值数组时可以省略 `$in`:
¥`$in` can be omitted when passing an array of values:
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: ['Hello', 'Hola', 'Bonjour'],
},
});
```
### `$notIn` {#notin}
输入列表中不包含属性。
¥Attribute is not contained in the input list.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$notIn: ['Hello', 'Hola', 'Bonjour'],
},
},
});
```
### `$lt` {#lt}
属性小于输入值。
¥Attribute is less than the input value.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
rating: {
$lt: 10,
},
},
});
```
### `$lte` {#lte}
属性小于或等于输入值。
¥Attribute is less than or equal to the input value.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
rating: {
$lte: 10,
},
},
});
```
### `$gt` {#gt}
属性大于输入值。
¥Attribute is greater than the input value.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
rating: {
$gt: 5,
},
},
});
```
### `$gte` {#gte}
属性大于或等于输入值。
¥Attribute is greater than or equal to the input value.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
rating: {
$gte: 5,
},
},
});
```
### `$between` {#between}
属性位于 2 个输入值之间,包括边界(例如,`$between[1, 3]` 还将返回 `1` 和 `3`)。
¥Attribute is between the 2 input values, boundaries included (e.g., `$between[1, 3]` will also return `1` and `3`).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
rating: {
$between: [1, 20],
},
},
});
```
### `$contains` {#contains}
属性包含输入值(区分大小写)。
¥Attribute contains the input value (case-sensitive).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$contains: 'Hello',
},
},
});
```
### `$notContains` {#notcontains}
属性不包含输入值(区分大小写)。
¥Attribute does not contain the input value (case-sensitive).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$notContains: 'Hello',
},
},
});
```
### `$containsi` {#containsi}
属性包含输入值。`$containsi` 不区分大小写,而 [$包含](#contains) 则区分大小写。
¥Attribute contains the input value. `$containsi` is not case-sensitive, while [$contains](#contains) is.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$containsi: 'hello',
},
},
});
```
### `$notContainsi` {#notcontainsi}
属性不包含输入值。`$notContainsi` 不区分大小写,而 [$不包含](#notcontains) 则区分大小写。
¥Attribute does not contain the input value. `$notContainsi` is not case-sensitive, while [$notContains](#notcontains) is.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$notContainsi: 'hello',
},
},
});
```
### `$startsWith` {#startswith}
属性以输入值开头(区分大小写)。
¥Attribute starts with input value (case-sensitive).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$startsWith: 'ABCD',
},
},
});
```
### `$startsWithi` {#startswithi}
属性以输入值开头(不区分大小写)。
¥Attribute starts with input value (case-insensitive).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$startsWithi: 'ABCD', // will return the same as filtering with 'abcd'
},
},
});
```
### `$endsWith` {#endswith}
属性以输入值结尾(区分大小写)。
¥Attribute ends with input value (case-sensitive).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$endsWith: 'ABCD',
},
},
});
```
### `$endsWithi` {#endswithi}
属性以输入值结尾(不区分大小写)。
¥Attribute ends with input value (case-insensitive).
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$endsWith: 'ABCD', // will return the same as filtering with 'abcd'
},
},
},
});
```
### `$null` {#null}
属性为 `null`。
¥Attribute is `null`.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$null: true,
},
},
});
```
### `$notNull` {#notnull}
属性不是 `null`。
¥Attribute is not `null`.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: {
$notNull: true,
},
},
});
```
## 逻辑运算符 {#logical-operators}
¥Logical operators
### `$and` {#and}
所有嵌套条件必须为 `true`。
¥All nested conditions must be `true`.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
$and: [
{
title: 'Hello World',
},
{
createdAt: { $gt: '2021-11-17T14:28:25.843Z' },
},
],
},
});
```
当传递具有嵌套条件的对象时,将隐式使用 `$and`:
¥`$and` will be used implicitly when passing an object with nested conditions:
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
title: 'Hello World',
createdAt: { $gt: '2021-11-17T14:28:25.843Z' },
},
});
```
### `$or` {#or}
一个或多个嵌套条件必须为 `true`。
¥One or many nested conditions must be `true`.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
$or: [
{
title: 'Hello World',
},
{
createdAt: { $gt: '2021-11-17T14:28:25.843Z' },
},
],
},
});
```
### `$not` {#not-1}
否定嵌套条件。
¥Negates the nested conditions.
**示例**
¥**Example**
```js
const entries = await strapi.documents('api::article.article').findMany({
filters: {
$not: {
title: 'Hello World',
},
},
});
```
:::note 注意
`$not` 可用作:
¥`$not` can be used as:
* 逻辑运算符(例如在 `filters: { $not: { // conditions… }}` 中)
¥a logical operator (e.g. in `filters: { $not: { // conditions… }}`)
* [属性运算符](#not)(例如在 `filters: { attribute-name: $not: { … } }` 中)。
¥[an attribute operator](#not) (e.g. in `filters: { attribute-name: $not: { … } }`).
:::
:::tip 提示
`$and`、`$or` 和 `$not` 运算符可嵌套在另一个 `$and`、`$or` 或 `$not` 运算符内。
¥`$and`, `$or` and `$not` operators are nestable inside of another `$and`, `$or` or `$not` operator.
:::
# 使用文档服务 API 语言环境参数
Source: https://docs.strapi.io/cms/api/document-service/locale
# 文档服务 API:使用 `locale` 参数 {#document-service-api-using-the-locale-parameter}
¥Document Service API: Using the `locale` parameter
默认情况下,[文档服务 API](/cms/api/document-service) 返回文档的默认语言环境版本(即 'en',即英语版本,除非为应用设置了其他默认语言环境,请参阅 [国际化 (i18n) 功能](/cms/features/internationalization))。本页介绍如何使用 `locale` 参数仅针对特定语言环境获取或操作数据。
¥By default the [Document Service API](/cms/api/document-service) returns the default locale version of documents (which is 'en', i.e. the English version, unless another default locale has been set for the application, see [Internationalization (i18n) feature](/cms/features/internationalization)). This page describes how to use the `locale` parameter to get or manipulate data only for specific locales.
## 获取使用 `findOne()` 的语言环境版本 {#find-one}
¥Get a locale version with `findOne()`
如果传递了 `locale`,则文档服务 API 的 [`findOne()` 方法](/cms/api/document-service#findone) 将返回此语言环境的文档版本:
¥If a `locale` is passed, the [`findOne()` method](/cms/api/document-service#findone) of the Document Service API returns the version of the document for this locale:
如果没有传递 `status` 参数,则默认返回 `draft` 版本。
¥If no `status` parameter is passed, the `draft` version is returned by default.
## 获取使用 `findFirst()` 的语言环境版本 {#find-first}
¥Get a locale version with `findFirst()`
要使用文档服务 API 返回特定语言环境,同时 [查找第一个文档](/cms/api/document-service#findfirst) 与参数匹配:
¥To return a specific locale while [finding the first document](/cms/api/document-service#findfirst) matching the parameters with the Document Service API:
如果没有传递 `status` 参数,则默认返回 `draft` 版本。
¥If no `status` parameter is passed, the `draft` version is returned by default.
## 获取使用 `findMany()` 的语言环境版本 {#find-many}
¥Get locale versions with `findMany()`
当将 `locale` 传递给文档服务 API 的 [`findMany()` 方法](/cms/api/document-service#findmany) 时,响应将返回所有具有此语言环境的文档。
¥When a `locale` is passed to the [`findMany()` method](/cms/api/document-service#findmany) of the Document Service API, the response will return all documents that have this locale available.
如果没有传递 `status` 参数,则默认返回 `draft` 版本。
¥If no `status` parameter is passed, the `draft` versions are returned by default.
Explanation:
给定以下 4 个具有不同语言环境的文档:
¥Given the following 4 documents that have various locales:
* 文档 A:
¥Document A:
* en
* `fr`
* it
* 文档 B:
¥Document B:
* en
* it
* 文档 C:
¥Document C:
* `fr`
* 文档 D:
¥Document D:
* `fr`
* it
`findMany({ locale: 'fr' })` 只会返回具有 `‘fr’` 语言环境版本的文档的草稿版本,即文档 A、C 和 D。
¥`findMany({ locale: 'fr' })` would only return the draft version of the documents that have a `‘fr’` locale version, that is documents A, C, and D.
## `create()` 语言环境的文档 {#create}
¥`create()` a document for a locale
若要为特定语言环境创建文档,请将 `locale` 作为参数传递给文档服务 API 的 [`create` 方法](/cms/api/document-service#create):
¥To create a document for specific locale, pass the `locale` as a parameter to the [`create` method](/cms/api/document-service#create) of the Document Service API:
## `update()` 语言环境版本 {#update}
¥`update()` a locale version
要仅更新文档的特定语言环境版本,请将 `locale` 参数传递给文档服务 API 的 [`update()` 方法](/cms/api/document-service#update):
¥To update only a specific locale version of a document, pass the `locale` parameter to the [`update()` method](/cms/api/document-service#update) of the Document Service API:
## `delete()` 语言环境版本 {#delete}
¥`delete()` locale versions
将 `locale` 参数与文档服务 API 的 [`delete()` 方法](/cms/api/document-service#delete) 一起使用以仅删除某些语言环境。除非传递了特定的 `status` 参数,否则这将删除草稿和已发布的版本。
¥Use the `locale` parameter with the [`delete()` method](/cms/api/document-service#delete) of the Document Service API to delete only some locales. Unless a specific `status` parameter is passed, this deletes both the draft and published versions.
### 删除语言环境版本 {#delete-a-locale-version}
¥Delete a locale version
要删除文档的特定语言环境版本:
¥To delete a specific locale version of a document:
### 删除所有语言环境版本 {#delete-all-locale-versions}
¥Delete all locale versions
`locale` 参数支持 `*` 通配符,可用于删除文档的所有语言环境版本:
¥The `*` wildcard is supported by the `locale` parameter and can be used to delete all locale versions of a document:
## `publish()` 语言环境版本 {#publish}
¥`publish()` locale versions
要使用文档服务 API 的 [`publish()` 方法](/cms/api/document-service#publish) 仅发布文档的特定语言环境版本,请将 `locale` 作为参数传递:
¥To publish only specific locale versions of a document with the [`publish()` method](/cms/api/document-service#publish) of the Document Service API, pass `locale` as a parameter:
### 发布语言环境版本 {#publish-a-locale-version}
¥Publish a locale version
要发布文档的特定语言环境版本:
¥To publish a specific locale version of a document:
### 发布所有语言环境版本 {#publish-all-locale-versions}
¥Publish all locale versions
`locale` 参数支持 `*` 通配符,用于发布文档的所有语言环境版本:
¥The `*` wildcard is supported by the `locale` parameter to publish all locale versions of a document:
## `unpublish()` 语言环境版本 {#unpublish}
¥`unpublish()` locale versions
要使用文档服务 API 的 [`unpublish()` 方法](/cms/api/document-service#unpublish) 仅发布文档的特定语言环境版本,请将 `locale` 作为参数传递:
¥To publish only specific locale versions of a document with the [`unpublish()` method](/cms/api/document-service#unpublish) of the Document Service API, pass `locale` as a parameter:
### 取消发布语言环境版本 {#unpublish-a-locale-version}
¥Unpublish a locale version
要取消发布文档的特定语言环境版本,请将 `locale` 作为参数传递给 `unpublish()`:
¥To unpublish a specific locale version of a document, pass the `locale` as a parameter to `unpublish()`:
### 取消发布所有语言环境版本 {#unpublish-all-locale-versions}
¥Unpublish all locale versions
`locale` 参数支持 `*` 通配符,用于取消发布文档的所有语言环境版本:
¥The `*` wildcard is supported by the `locale` parameter, to unpublish all locale versions of a document:
## `discardDraft()` 语言环境版本 {#discard-draft}
¥`discardDraft()` for locale versions
要使用文档服务 API 的 [`discardDraft()` 方法](/cms/api/document-service#discarddraft) 仅丢弃文档某些语言环境版本的草稿数据,请将 `locale` 作为参数传递:
¥To discard draft data only for some locales versions of a document with the [`discardDraft()` method](/cms/api/document-service#discarddraft) of the Document Service API, pass `locale` as a parameter:
### 放弃语言环境版本的草稿 {#discard-draft-for-a-locale-version}
¥Discard draft for a locale version
要丢弃文档特定语言环境版本的草稿数据并使用此语言环境的已发布版本的数据覆盖它,请将 `locale` 作为参数传递给 `discardDraft()`:
¥To discard draft data for a specific locale version of a document and override it with data from the published version for this locale, pass the `locale` as a parameter to `discardDraft()`:
### 放弃所有语言环境版本的草稿 {#discard-drafts-for-all-locale-versions}
¥Discard drafts for all locale versions
`locale` 参数支持 `*` 通配符,用于丢弃文档所有语言环境版本的草稿数据,并用已发布版本的数据替换它们:
¥The `*` wildcard is supported by the `locale` parameter, to discard draft data for all locale versions of a document and replace them with the data from the published versions:
## `count()` 语言环境的文档 {#count}
¥`count()` documents for a locale
要计算特定语言环境的文档,请将 `locale` 与其他参数一起传递给文档服务 API 的 [`count()` 方法](/cms/api/document-service#count)。
¥To count documents for a specific locale, pass the `locale` along with other parameters to the [`count()` method](/cms/api/document-service#count) of the Document Service API.
如果没有传递 `status` 参数,则计算草稿文档(这是该语言环境可用文档的总数,因为即使已发布的文档也算作具有草稿版本):
¥If no `status` parameter is passed, draft documents are counted (which is the total of available documents for the locale since even published documents are counted as having a draft version):
```js
// Count number of published documents in French
strapi.documents('api::restaurant.restaurant').count({ locale: 'fr' });
```
# 扩展文档服务行为
Source: https://docs.strapi.io/cms/api/document-service/middlewares
# 文档服务 API:中间件 {#document-service-api-middlewares}
¥Document Service API: Middlewares
[文档服务 API](/cms/api/document-service) 提供了通过中间件扩展其行为的能力。
¥The [Document Service API](/cms/api/document-service) offers the ability to extend its behavior thanks to middlewares.
文档服务中间件允许你在方法运行之前和/或之后执行操作。
¥Document Service middlewares allow you to perform actions before and/or after a method runs.
The diagram represents a simplified version of how a request travels through the Strapi back end, with the Document Service highlighted. The backend customization introduction page includes a complete, interactive diagram.
## 注册中间件 {#registering-a-middleware}
¥Registering a middleware
语法:`strapi.documents.use(middleware)`
¥Syntax: `strapi.documents.use(middleware)`
### 参数 {#parameters}
¥Parameters
中间件是一种接收上下文和下一个函数的函数。
¥A middleware is a function that receives a context and a next function.
语法:`(context, next) => ReturnType`
¥Syntax: `(context, next) => ReturnType`
| 范围 | 描述 | 类型 |
| --------- | ------------ | ---------- |
| `context` | 中间件上下文 | `Context` |
| `next` | 调用堆栈中的下一个中间件 | `function` |
#### `context` {#context}
| 范围 | 描述 | 类型 |
| ------------- | -------------------------------------------- | ------------- |
| `action` | 正在运行的方法([查看可用方法](/cms/api/document-service)) | `string` |
| `params` | 方法参数 ([查看可用方法](/cms/api/document-service)) | `Object` |
| `uid` | 内容类型唯一标识符 | `string` |
| `contentType` | 内容类型 | `ContentType` |
Examples:
以下示例显示了 `context` 可能包含的内容(具体取决于调用的方法):
¥The following examples show what `context` might include depending on the method called:
#### `next` {#next}
`next` 是一个没有参数的函数,它调用堆栈中的下一个中间件并返回其响应。
¥`next` is a function without parameters that calls the next middleware in the stack and return its response.
**示例**
¥**Example**
```js
strapi.documents.use((context, next) => {
return next();
});
```
### 在哪里注册 {#where-to-register}
¥Where to register
一般来说,你应该在 Strapi 注册阶段注册你的中间件。
¥Generaly speaking you should register your middlewares during the Strapi registration phase.
#### 用户 {#users}
¥Users
中间件必须在通用 `register()` 生命周期方法中注册:
¥The middleware must be registered in the general `register()` lifecycle method:
```js title="/src/index.js|ts"
module.exports = {
register({ strapi }) {
strapi.documents.use((context, next) => {
// your logic
return next();
});
},
// bootstrap({ strapi }) {},
// destroy({ strapi }) {},
};
```
#### 插件开发者 {#plugin-developers}
¥Plugin developers
中间件必须在插件的 `register()` 生命周期方法中注册:
¥The middleware must be registered in the plugin's `register()` lifecycle method:
```js title="/(plugin-root-folder)/strapi-server.js|ts"
module.exports = {
register({ strapi }) {
strapi.documents.use((context, next) => {
// your logic
return next();
});
},
// bootstrap({ strapi }) {},
// destroy({ strapi }) {},
};
```
## 实现中间件 {#implementing-a-middleware}
¥Implementing a middleware
实现中间件时,始终返回来自 `next()` 的响应。如果不这样做,Strapi 应用就会崩溃。
¥When implementing a middleware, always return the response from `next()`.
Failing to do this will break the Strapi application.
### 示例 {#examples}
¥Examples
```js
const applyTo = ['api::article.article'];
strapi.documents.use((context, next) => {
// Only run for certain content types
if (!applyTo.includes(context.uid)) {
return next();
}
// Only run for certain actions
if (['create', 'update'].includes(context.action)) {
context.params.data.fullName = `${context.params.data.firstName} ${context.params.data.lastName}`;
}
const result = await next();
// do something with the result before returning it
return result
});
```
:::strapi 生命周期钩子
文档服务 API 根据调用的方法触发各种数据库生命周期钩子。有关完整参考,请参阅 [文档服务 API:生命周期钩子](/cms/migration/v4-to-v5/breaking-changes/lifecycle-hooks-document-service#table)。
¥The Document Service API triggers various database lifecycle hooks based on which method is called. For a complete reference, see [Document Service API: Lifecycle hooks](/cms/migration/v4-to-v5/breaking-changes/lifecycle-hooks-document-service#table).
:::
# 使用文档服务 API 填充
Source: https://docs.strapi.io/cms/api/document-service/populate
# 文档服务 API:填充字段 {#document-service-api-populating-fields}
¥Document Service API: Populating fields
默认情况下,[文档服务 API](/cms/api/document-service) 不填充任何关系、媒体字段、组件或动态区域。此页面介绍如何使用 `populate` 参数填充特定字段。
¥By default the [Document Service API](/cms/api/document-service) does not populate any relations, media fields, components, or dynamic zones. This page describes how to use the `populate` parameter to populate specific fields.
:::tip 提示
你还可以使用 `select` 参数仅返回查询结果中的特定字段(请参阅 [`select` 参数](/cms/api/document-service/fields) 文档)。
¥You can also use the `select` parameter to return only specific fields with the query results (see the [`select` parameter](/cms/api/document-service/fields) documentation).
:::
:::caution 提醒
如果安装了用户和权限插件,则必须为正在填充的内容类型启用 `find` 权限。如果角色无权访问内容类型,则不会填充该内容类型。
¥If the Users & Permissions plugin is installed, the `find` permission must be enabled for the content-types that are being populated. If a role doesn't have access to a content-type it will not be populated.
:::
## 关系和媒体字段 {#relations-and-media-fields}
¥Relations and media fields
发布文档的一个或多个语言环境。
¥Queries can accept a `populate` parameter to explicitly define which fields to populate, with the following syntax option examples.
### 为所有关系填充 1 级 {#populate-1-level-for-all-relations}
¥Populate 1 level for all relations
要为所有关系填充一层深度,请将 `*` 通配符与 `populate` 参数结合使用:
¥To populate one-level deep for all relations, use the `*` wildcard in combination with the `populate` parameter:
### 为特定关系填充 1 级 {#populate-1-level-for-specific-relations}
¥Populate 1 level for specific relations
要为特定关系填充一层深度,请将关系名称传递到 `populate` 数组中:
¥To populate specific relations one-level deep, pass the relation names in a `populate` array:
### 为特定关系填充多个深度级别 {#populate-several-levels-deep-for-specific-relations}
¥Populate several levels deep for specific relations
要为特定关系填充多层深度,请将对象格式与 `populate` 结合使用:
¥To populate specific relations several levels deep, use the object format with `populate`:
## 组件和动态区域 {#components--dynamic-zones}
¥Components & Dynamic Zones
组件的填充方式与关系相同:
¥Components are populated the same way as relations:
动态区域本质上是高度动态的内容结构。要填充动态区域,必须使用 `on` 属性定义每个组件的填充查询。
¥Dynamic zones are highly dynamic content structures by essence. To populate a dynamic zone, you must define per-component populate queries using the `on` property.
## 使用 `create()` 填充 {#populating-with-create}
¥Populating with `create()`
要在创建文档时填充:
¥To populate while creating documents:
## 使用 `update()` 填充 {#populating-with-update}
¥Populating with `update()`
要在更新文档时填充:
¥To populate while updating documents:
## 使用 `publish()` 填充 {#populating-with-publish}
¥Populating with `publish()`
要在发布文档时填充(与 `unpublish()` 和 `discardDraft()` 的行为相同):
¥To populate while publishing documents (same behavior with `unpublish()` and `discardDraft()`):
# 使用文档服务 API 排序和分页
Source: https://docs.strapi.io/cms/api/document-service/sort-pagination
# 文档服务 API:对结果进行排序和分页 {#document-service-api-sorting-and-paginating-results}
¥Document Service API: Sorting and paginating results
[文档服务 API](/cms/api/document-service) 提供了对查询结果进行排序和分页的能力。
¥The [Document Service API](/cms/api/document-service) offers the ability to sort and paginate query results.
## 排序 {#sort}
¥Sort
要对文档服务 API 返回的结果进行排序,请在查询中包含 `sort` 参数。
¥To sort results returned by the Document Service API, include the `sort` parameter with queries.
### 按单个字段排序 {#sort-on-a-single-field}
¥Sort on a single field
要根据单个字段对结果进行排序:
¥To sort results based on a single field:
### 按多个字段排序 {#sort-on-multiple-fields}
¥Sort on multiple fields
要对多个字段进行排序,请将它们全部传递到一个数组中:
¥To sort on multiple fields, pass them all in an array:
## 分页 {#pagination}
¥Pagination
要对结果进行分页,请传递 `limit` 和 `start` 参数:
¥To paginate results, pass the `limit` and `start` parameters:
# 使用草稿和使用文档服务 API 发布
Source: https://docs.strapi.io/cms/api/document-service/status
# 文档服务 API:与草稿和发布一起使用 {#document-service-api-usage-with-draft--publish}
¥Document Service API: Usage with Draft & Publish
默认情况下,当启用 [起草并发布](/cms/features/draft-and-publish) 功能时,[文档服务 API](/cms/api/document-service) 会返回文档的草稿版本。本页介绍如何使用 `status` 参数来:
¥By default the [Document Service API](/cms/api/document-service) returns the draft version of a document when the [Draft & Publish](/cms/features/draft-and-publish) feature is enabled. This page describes how to use the `status` parameter to:
* 返回文档的已发布版本,
¥return the published version of a document,
* 根据文档的状态计数文档,
¥count documents depending on their status,
* 并在创建或更新文档时直接发布文档。
¥and directly publish a document while creating it or updating it.
:::note 注意
将 `{ status: 'draft' }` 传递给文档服务 API 查询返回的结果与不传递任何 `status` 参数相同。
¥Passing `{ status: 'draft' }` to a Document Service API query returns the same results as not passing any `status` parameter.
:::
## 获取使用 `findOne()` 的已发布版本 {#find-one}
¥Get the published version with `findOne()`
`findOne()` 查询默认返回文档的草稿版本。
¥`findOne()` queries return the draft version of a document by default.
要使用文档服务 API 返回已发布的版本,同时 [查找特定文档](/cms/api/document-service#findone) 与文档服务 API 匹配,请传递 `status: 'published'`:
¥To return the published version while [finding a specific document](/cms/api/document-service#findone) with the Document Service API, pass `status: 'published'`:
## 获取使用 `findFirst()` 的已发布版本 {#find-first}
¥Get the published version with `findFirst()`
`findFirst()` 查询默认返回文档的草稿版本。
¥`findFirst()` queries return the draft version of a document by default.
要使用文档服务 API 返回已发布的版本,同时 [查找第一个文档](/cms/api/document-service#findfirst) 与文档服务 API 匹配,请传递 `status: 'published'`:
¥To return the published version while [finding the first document](/cms/api/document-service#findfirst) with the Document Service API, pass `status: 'published'`:
## 获取使用 `findMany()` 的已发布版本 {#find-many}
¥Get the published version with `findMany()`
`findMany()` 查询默认返回文档的草稿版本。
¥`findMany()` queries return the draft version of documents by default.
要使用文档服务 API 返回已发布的版本,同时 [查找文档](/cms/api/document-service#findmany) 与文档服务 API 匹配,请传递 `status: 'published'`:
¥To return the published version while [finding documents](/cms/api/document-service#findmany) with the Document Service API, pass `status: 'published'`:
## `count()` 仅限草稿或已发布版本 {#count}
¥`count()` only draft or published versions
要使用文档服务 API 进行 [计数文档](/cms/api/document-service#count) 时仅考虑文档的草稿或已发布版本,请传递相应的 `status` 参数:
¥To take into account only draft or published versions of documents while [counting documents](/cms/api/document-service#count) with the Document Service API, pass the corresponding `status` parameter:
```js
// Count draft documents (also actually includes published documents)
const draftsCount = await strapi.documents("api::restaurant.restaurant").count({
status: 'draft'
});
```
```js
// Count only published documents
const publishedCount = await strapi.documents("api::restaurant.restaurant").count({
status: 'published'
});
```
:::note 注意
由于已发布的文档必然也有草稿副本,因此已发布的文档仍算作具有草稿版本。
¥Since published documents necessarily also have a draft counterpart, a published document is still counted as having a draft version.
这意味着使用 `status: 'draft'` 参数计数仍会返回与其他参数匹配的文档总数,即使某些文档已经发布并且不再在内容管理器中显示为 "draft" 或 "modified"。目前没有办法阻止已发布的文档被计算在内。
¥This means that counting with the `status: 'draft'` parameter still returns the total number of documents matching other parameters, even if some documents have already been published and are not displayed as "draft" or "modified" in the Content Manager anymore. There currently is no way to prevent already published documents from being counted.
:::
## 创建草稿并发布 {#create}
¥Create a draft and publish it
要在创建文档时自动发布文档,请将 `status: 'published'` 添加到传递给 `create()` 的参数中:
¥To automatically publish a document while creating it, add `status: 'published'` to parameters passed to `create()`:
## 更新草稿并发布 {#update}
¥Update a draft and publish it
要在更新文档时自动发布文档,请将 `status: 'published'` 添加到传递给 `update()` 的参数中:
¥To automatically publish a document while updating it, add `status: 'published'` to parameters passed to `update()`:
# GraphQL API
Source: https://docs.strapi.io/cms/api/graphql
# GraphQL API {#graphql-api}
GraphQL API 允许执行查询和突变,以通过 Strapi 的 [GraphQL 插件](/cms/plugins/graphql) 与 [content-types](/cms/backend-customization/models#content-types) 进行交互。结果可以是 [filtered](#filters)、[sorted](#sorting) 和 [paginated](#pagination)。
¥The GraphQL API allows performing queries and mutations to interact with the [content-types](/cms/backend-customization/models#content-types) through Strapi's [GraphQL plugin](/cms/plugins/graphql). Results can be [filtered](#filters), [sorted](#sorting) and [paginated](#pagination).
:::prerequisites
要使用 GraphQL API,请安装 [GraphQL](/cms/plugins/graphql) 插件:
¥To use the GraphQL API, install the [GraphQL](/cms/plugins/graphql) plugin:
:::
安装后,可通过 `/graphql` URL 访问 GraphQL 在线运行,并可用于以交互方式构建查询和修改,以及阅读针对你的内容类型量身定制的文档:
¥Once installed, the GraphQL playground is accessible at the `/graphql` URL and can be used to interactively build your queries and mutations and read documentation tailored to your content-types:
#### 获取关系 {#fetch-relations}
¥Fetch relations
你可以要求在扁平查询或
:::
### 获取媒体字段 {#fetch-media-fields}
¥Fetch media fields
媒体字段内容的获取方式与其他属性一样。
¥Media fields content is fetched just like other attributes.
以下示例从 "餐厅" 内容类型中获取附加到每个文档的每个 `cover` 媒体字段的 `url` 属性值:
¥The following example fetches the `url` attribute value for each `cover` media field attached to each document from the "Restaurants" content-type:
```graphql
{
restaurants {
images {
documentId
url
}
}
}
```
对于多个媒体字段,你可以使用扁平查询或
### 获取组件 {#fetch-components}
¥Fetch components
组件内容的获取方式与其他属性一样。
¥Components content is fetched just like other attributes.
以下示例从 "餐厅" 内容类型中获取添加到每个文档的每个 `closingPeriod` 组件的 `label`、`start_date` 和 `end_date` 属性值:
¥The following example fetches the `label`, `start_date`, and `end_date` attributes values for each `closingPeriod` component added to each document from the "Restaurants" content-type:
```graphql
{
restaurants {
closingPeriod {
label
start_date
end_date
}
}
}
```
### 获取动态区域数据 {#fetch-dynamic-zone-data}
¥Fetch dynamic zone data
动态区域是 GraphQL 中的联合类型,因此你需要使用
```graphql title="Simple examples for membership operators (in, notIn)"
# in - returns restaurants with category either "pizza" or "burger"
{
restaurants(filters: { category: { in: ["pizza", "burger"] } }) {
name
}
}
# notIn - returns restaurants whose category is neither "pizza" nor "burger"
{
restaurants(filters: { category: { notIn: ["pizza", "burger"] } }) {
name
}
}
```
```graphql title="Simple examples for null checks operators (null, notNull)"
# null - returns restaurants where description is null
{
restaurants(filters: { description: { null: true } }) {
name
}
}
# notNull - returns restaurants where description is not null
{
restaurants(filters: { description: { notNull: true } }) {
name
}
}
```
```graphql title="Simple examples for logical operators (and, or, not)"
# and - both category must be "pizza" AND averagePrice must be < 20
{
restaurants(filters: {
and: [
{ category: { eq: "pizza" } },
{ averagePrice: { lt: 20 } }
]
}) {
name
}
}
# or - category is "pizza" OR category is "burger"
{
restaurants(filters: {
or: [
{ category: { eq: "pizza" } },
{ category: { eq: "burger" } }
]
}) {
name
}
}
# not - category must NOT be "pizza"
{
restaurants(filters: {
not: { category: { eq: "pizza" } }
}) {
name
}
}
```
```graphql title="Example with nested logical operators: use and, or, and not to find pizzerias under 20 euros"
{
restaurants(
filters: {
and: [
{ not: { averagePrice: { gte: 20 } } }
{
or: [
{ name: { eq: "Pizzeria" } }
{ name: { startsWith: "Pizzeria" } }
]
}
]
}
) {
documentId
name
averagePrice
}
}
```
### 在特定语言环境中获取文档 {#locale-fetch}
¥Fetch a document in a specific locale
要获取特定语言环境的文档
### 创建新的本地化文档 {#locale-create}
¥Create a new localized document
可以传递 `locale` 字段来为特定语言环境创建本地化文档
# 开放 API 规范
Source: https://docs.strapi.io/cms/api/openapi
# OpenAPI 规范生成 {#openapi-specification-generation}
¥OpenAPI specification generation
Strapi 提供了一个命令行工具,用于为你的应用生成
你还可以使用可选的 `--output` 参数来指定路径和文件名,如下例所示:
¥You can also path an optional `--output` argument to specify the path and filename, as in the following example:
### 规范结构和内容 {#specification-structure-and-content}
¥Specification structure and content
生成的 OpenAPI 规范遵循
生成的 OpenAPI 规范包含 Strapi 应用中所有可用的 API 端点,以及有关这些端点的信息,例如:
¥The generated OpenAPI specification includes all available API endpoints in your Strapi application, and information about these endpoints, such as the following:
* 适用于所有内容类型的 CRUD 操作
¥CRUD operations for all content types
* 应用中定义的自定义 API 路由
¥Custom API routes defined in your application
* 用于用户管理的身份验证端点
¥Authentication endpoints for user management
* 用于媒体处理的文件上传端点
¥File upload endpoints for media handling
* 已安装插件的插件端点
¥Plugin endpoints from installed plugins
## 与 Swagger UI 集成 {#integrating-with-swagger-ui}
¥Integrating with Swagger UI
通过以下步骤,你可以快速生成与 [招摇的用户界面](https://swagger.io/) 兼容的页面:
¥With the following steps you can quickly generate a [Swagger UI](https://swagger.io/)-compatible page:
1. 生成规范:
¥Generate a specification:
2. 使用以下代码更新 [`/config/middlewares.js` 配置文件](/cms/configurations/middlewares):
¥Update [the `/config/middlewares.js` configuration file](/cms/configurations/middlewares) with the following code:
```
This will ensure the Swagger UI display from is not blocked by Strapi's CSP policy handled by the [security middleware](/cms/configurations/middlewares#security).
```
3.
````
```html
API Documentation
```
````
4.Swagger UI 应显示如下:
¥4. Restart the Strapi server with `yarn develop` or `npm run develop` and visit the `/openapi.html` page. The Swagger UI should be displayed:

# REST API 参考
Source: https://docs.strapi.io/cms/api/rest
# REST API 参考 {#rest-api-reference}
¥REST API reference
REST API 允许通过 API 端点访问 [content-types](/cms/backend-customization/models)。创建内容类型时,Strapi 会自动创建 [API 端点](#endpoints)。查询 API 端点时可以使用 [接口参数](/cms/api/rest/parameters) 来细化结果。
¥The REST API allows accessing the [content-types](/cms/backend-customization/models) through API endpoints. Strapi automatically creates [API endpoints](#endpoints) when a content-type is created. [API parameters](/cms/api/rest/parameters) can be used when querying API endpoints to refine the results.
本文档的此部分内容是关于内容类型的 REST API 参考。我们还为特定用例提供了 [guides](/cms/api/rest/guides/intro)。
¥This section of the documentation is for the REST API reference for content-types. We also have [guides](/cms/api/rest/guides/intro) available for specific use cases.
:::prerequisites
默认情况下,所有内容类型都是私有的,需要公开或需要使用适当的权限对查询进行身份验证。有关更多详细信息,请参阅 [快速入门指南](/cms/quick-start#step-4-set-roles--permissions)、[用户和权限功能](/cms/features/users-permissions#roles) 和 [API 令牌配置文档](/cms/features/api-tokens) 的用户指南。
¥All content types are private by default and need to be either made public or queries need to be authenticated with the proper permissions. See the [Quick Start Guide](/cms/quick-start#step-4-set-roles--permissions), the user guide for the [Users & Permissions feature](/cms/features/users-permissions#roles), and [API tokens configuration documentation](/cms/features/api-tokens) for more details.
:::
:::note 注意
默认情况下,REST API 响应仅包含顶层字段,不会填充任何关系、媒体字段、组件或动态区域。使用 [`populate` 参数](/cms/api/rest/populate-select) 填充特定字段。确保为你填充的关系的字段授予查找权限。
¥By default, the REST API responses only include top-level fields and does not populate any relations, media fields, components, or dynamic zones. Use the [`populate` parameter](/cms/api/rest/populate-select) to populate specific fields. Ensure that the find permission is given to the field(s) for the relation(s) you populate.
:::
:::strapi Strapi 客户端
[Strapi 客户端](/cms/api/client) 库简化了与你的 Strapi 后端的交互,提供了一种获取、创建、更新和删除内容的方法。
¥The [Strapi Client](/cms/api/client) library simplifies interactions with your Strapi back end, providing a way to fetch, create, update, and delete content.
:::
## 端点 {#endpoints}
¥Endpoints
对于每个 Content-Type,会自动生成以下端点:
¥For each Content-Type, the following endpoints are automatically generated:
Plural API ID vs. Singular API ID:
在下表中:
¥In the following tables:
* `:singularApiId` 指的是内容类型的 "API ID(单数)" 字段的值,
¥`:singularApiId` refers to the value of the "API ID (Singular)" field of the content-type,
* 而 `:pluralApiId` 指的是内容类型的 "API ID(复数)" 字段的值。
¥and `:pluralApiId` refers to the value of the "API ID (Plural)" field of the content-type.
这些值是在内容类型生成器中创建内容类型时定义的,可以在管理面板中编辑内容类型时找到(请参阅 [用户指南](/cms/features/content-type-builder#creating-content-types))。例如,默认情况下,对于 "文章" 内容类型:
¥These values are defined when creating a content-type in the Content-Type Builder, and can be found while editing a content-type in the admin panel (see [User Guide](/cms/features/content-type-builder#creating-content-types)). For instance, by default, for an "Article" content-type:
* `:singularApiId` 将为 `article`
¥`:singularApiId` will be `article`
* `:pluralApiId` 将为 `articles`
¥`:pluralApiId` will be `articles`
Real-world examples of endpoints:
以下端点示例取自
:::strapi 上传 API
Upload 包(为 [媒体库功能](/cms/features/media-library) 提供支持)具有可通过其 [`/api/upload` 端点](/cms/api/rest/upload) 访问的特定 API。
¥The Upload package (which powers the [Media Library feature](/cms/features/media-library)) has a specific API accessible through its [`/api/upload` endpoints](/cms/api/rest/upload).
:::
:::note 注意
[组件](/cms/backend-customization/models#components-json) 没有 API 端点。
¥[Components](/cms/backend-customization/models#components-json) don't have API endpoints.
:::
## 要求 {#requests}
¥Requests
:::strapi Strapi 5 与 Strapi v4
Strapi 5 的内容 API 与 Strapi v4 有 2 个主要区别:
¥Strapi 5's Content API includes 2 major differences with Strapi v4:
* 响应格式已扁平化,这意味着属性不再嵌套在 `data.attributes` 对象中,而是可以在 `data` 对象的第一级直接访问(例如,使用 `data.title` 访问内容类型的 "title" 属性)。
¥The response format has been flattened, which means attributes are no longer nested in a `data.attributes` object and are directly accessible at the first level of the `data` object (e.g., a content-type's "title" attribute is accessed with `data.title`).
* Strapi 5 现在使用文档
### 获取文档 {#get}
¥Get a document
返回 `documentId` 的文档。
¥Returns a document by `documentId`.
:::strapi Strapi 5 与 Strapi v4
在 Strapi 5 中,特定文档由其 `documentId` 到达。
¥In Strapi 5, a specific document is reached by its `documentId`.
:::
### 创建文档 {#create}
¥Create a document
创建一个文档并返回其值。
¥Creates a document and returns its value.
如果安装了 [国际化 (i18n) 插件](/cms/features/internationalization),则可以使用 POST 请求将 REST API 发送到 [创建本地化文档](/cms/api/rest/locale#rest-delete)。
¥If the [Internationalization (i18n) plugin](/cms/features/internationalization) is installed, it's possible to use POST requests to the REST API to [create localized documents](/cms/api/rest/locale#rest-delete).
:::note 注意
在创建文档时,你可以定义其关系及其顺序(有关更多详细信息,请参阅 [通过 REST API 管理关系](/cms/api/rest/relations.md))。
¥While creating a document, you can define its relations and their order (see [Managing relations through the REST API](/cms/api/rest/relations.md) for more details).
:::
### 更新文档 {#update}
¥Update a document
通过 `id` 部分更新文档并返回其值。
¥Partially updates a document by `id` and returns its value.
发送 `null` 值以清除字段。
¥Send a `null` value to clear fields.
:::note NOTES
* 即使安装了 [国际化 (i18n) 插件](/cms/features/internationalization),目前也不可能安装 [更新语言环境一份文件](/cms/api/rest/locale#rest-update)。
¥Even with the [Internationalization (i18n) plugin](/cms/features/internationalization) installed, it's currently not possible to [update the locale of a document](/cms/api/rest/locale#rest-update).
* 在更新文档时,你可以定义其关系及其顺序(有关更多详细信息,请参阅 [通过 REST API 管理关系](/cms/api/rest/relations))。
¥While updating a document, you can define its relations and their order (see [Managing relations through the REST API](/cms/api/rest/relations) for more details).
:::
### 删除文档 {#delete}
¥Delete a document
删除文档。
¥Deletes a document.
`DELETE` 请求仅在成功时发送 204 HTTP 状态代码,并且不会在响应正文中返回任何数据。
¥`DELETE` requests only send a 204 HTTP status code on success and do not return any data in the response body.
# 过滤器
Source: https://docs.strapi.io/cms/api/rest/filters
# REST API:过滤器 {#rest-api-filters}
¥REST API: Filters
[REST API](/cms/api/rest) 能够过滤通过 ["获取条目"](/cms/api/rest#get-all) 方法找到的结果。 使用可选的 Strapi 功能可以提供更多过滤器:
¥The [REST API](/cms/api/rest) offers the ability to filter results found with its ["Get entries"](/cms/api/rest#get-all) method.
Using optional Strapi features can provide some more filters:
* 如果在内容类型上启用了 [国际化 (i18n) 插件](/cms/features/internationalization),则可以按区域设置进行过滤。
¥If the [Internationalization (i18n) plugin](/cms/features/internationalization) is enabled on a content-type, it's possible to filter by locale.
* 如果启用了 [起草并发布](/cms/features/draft-and-publish),则可以根据 `published`(默认)或 `draft` 状态进行过滤。
¥If the [Draft & Publish](/cms/features/draft-and-publish) is enabled, it's possible to filter based on a `published` (default) or `draft` status.
:::tip 提示
JavaScript query (built with the qs library):
## 示例:查找多个 id 为 3, 6,8 的餐厅 {#example-find-multiple-restaurants-with-ids-3-68}
¥Example: Find multiple restaurants with ids 3, 6,8
你可以将 `$in` 过滤运算符与值数组结合使用来查找多个精确值。
¥You can use the `$in` filter operator with an array of values to find multiple exact values.
JavaScript query (built with the qs library):
## 复杂过滤 {#complex-filtering}
¥Complex filtering
复杂过滤是使用高级方法组合多个过滤器,例如组合 `$and` 和 `$or`。这允许更灵活地请求准确所需的数据。
¥Complex filtering is combining multiple filters using advanced methods such as combining `$and` & `$or`. This allows for more flexibility to request exactly the data needed.
JavaScript query (built with the qs library):
## 深度过滤 {#deep-filtering}
¥Deep filtering
深度过滤是对关系的字段进行过滤。
¥Deep filtering is filtering on a relation's fields.
:::note 注意
* 默认情况下不填充关系、媒体字段、组件和动态区域。使用 `populate` 参数填充这些内容结构(参见 [`populate` 文档](/cms/api/rest/populate-select#population))
¥Relations, media fields, components, and dynamic zones are not populated by default. Use the `populate` parameter to populate these content structures (see [`populate` documentation](/cms/api/rest/populate-select#population))
* 你可以过滤填充的内容,也可以过滤嵌套关系,但不能对多态内容结构(例如媒体字段和动态区域)使用过滤器。
¥You can filter what you populate, you can also filter nested relations, but you can't use filters for polymorphic content structures (such as media fields and dynamic zones).
:::
:::caution 提醒
使用深层过滤器查询 API 可能会导致性能问题。如果你的深度过滤查询之一太慢,我们建议使用查询的优化版本构建自定义路由。
¥Querying your API with deep filters may cause performance issues. If one of your deep filtering queries is too slow, we recommend building a custom route with an optimized version of the query.
:::
JavaScript query (built with the qs library):
# REST API 指南
Source: https://docs.strapi.io/cms/api/rest/guides/intro
# REST API 指南 {#rest-api-guides}
¥REST API Guides
[REST API 参考](/cms/api/rest) 文档旨在提供所有可用端点和参数的快速参考。
¥The [REST API reference](/cms/api/rest) documentation is meant to provide a quick reference for all the endpoints and parameters available.
## 指南 {#guides}
¥Guides
以下指南由 Strapi 文档团队官方维护,涵盖专门主题并为某些用例提供详细说明(用 🧠 表示的指南)或分步说明(用 🛠️ 表示的指南):
¥The following guides, officially maintained by the Strapi Documentation team, cover dedicated topics and provide detailed explanations (guides indicated with 🧠) or step-by-step instructions (guides indicated with 🛠️) for some use cases:
## 其他资源 {#additional-resources}
¥Additional resources
:::strapi 想帮助其他用户吗?
本节列出的一些额外资源是为 Strapi v4 创建的,可能无法完全与 Strapi 5 一起使用。如果你想为 Strapi 5 更新以下文章之一,请随时 参加“为社区写作”计划。
¥Some of the additional resources listed in this section have been created for Strapi v4 and might not fully work with Strapi 5. If you want to update one of the following articles for Strapi 5, feel free to for the Write for the Community program.
:::
其他教程和指南可以在以下博客文章中找到:
¥Additional tutorials and guides can be found in the following blog posts:
# 交互式查询构建器
Source: https://docs.strapi.io/cms/api/rest/interactive-query-builder
# 使用 Strapi 的交互式工具构建你的查询 URL {#build-your-query-url-with-strapis-interactive-tool}
¥Build your query URL with Strapi's interactive tool
可以使用并组合多种参数来通过 [REST API](/cms/api/rest) 查询你的内容,这可能会导致查询 URL 又长又复杂。
¥A wide range of parameters can be used and combined to query your content with the [REST API](/cms/api/rest), which can result in long and complex query URLs.
Strapi 的代码库使用 来解析和字符串化嵌套的 JavaScript 对象。建议直接使用 `qs` 生成复杂的查询 URL,而不是手动创建。
¥Strapi's codebase uses to parse and stringify nested JavaScript objects. It's recommended to use `qs` directly to generate complex query URLs instead of creating them manually.
你可以使用以下交互式查询构建器工具自动生成查询 URL:
¥You can use the following interactive query builder tool to generate query URLs automatically:
1. 将端点和端点查询参数字段中的值替换为适合你需要的内容。
¥Replace the values in the *Endpoint* and *Endpoint Query Parameters* fields with content that fits your needs.
2. 单击“复制到剪贴板”按钮可复制自动生成的查询字符串 URL,该 URL 会在你键入时更新。
¥Click the **Copy to clipboard** button to copy the automatically generated *Query String URL* which is updated as you type.
:::info 参数使用
请参考 [REST API 参数表](/cms/api/rest/parameters) 并阅读相应的参数文档页面以更好地了解参数用法。
¥Please refer to the [REST API parameters table](/cms/api/rest/parameters) and read the corresponding parameters documentation pages to better understand parameters usage.
:::
¥
:::note 注意
默认端点路径以 `/api/` 为前缀,应保持原样,除非你使用 [`rest.prefix` API 配置选项](/cms/configurations/api) 配置了不同的 API 前缀。 例如,要使用默认 API 前缀查询 `books` 集合类型,请在端点字段中键入 `/api/books` 。
¥The default endpoint path is prefixed with `/api/` and should be kept as-is unless you configured a different API prefix using [the `rest.prefix` API configuration option](/cms/configurations/api). For instance, to query the `books` collection type using the default API prefix, type `/api/books` in the *Endpoint* field.
:::
:::caution 免责声明
本页提供的 `qs` 库和交互式查询构建器:
¥The `qs` library and the interactive query builder provided on this page:
* 可能无法检测到所有语法错误,
¥might not detect all syntax errors,
* 不知道 Strapi 项目中可用的参数和值,
¥are not aware of the parameters and values available in a Strapi project,
* 并且不提供自动补齐功能。
¥and do not provide autocomplete features.
目前,这些工具仅用于转换内联查询字符串 URL 中的 JavaScript 对象。使用生成的查询 URL 并不能保证你的 API 会返回正确的结果。
¥Currently, these tools are only provided to transform the JavaScript object in an inline query string URL. Using the generated query URL does not guarantee that proper results will get returned with your API.
:::
# 语言环境
Source: https://docs.strapi.io/cms/api/rest/locale
# REST API:`locale` {#rest-api-locale}
[国际化 (i18n) 功能](/cms/features/internationalization) 为 [REST API](/cms/api/rest) 添加了新功能。
¥The [Internationalization (i18n) feature](/cms/features/internationalization) adds new abilities to the [REST API](/cms/api/rest).
:::prerequisites
要使用针对某个语言环境的 API 内容,请确保该语言环境已经是 [添加到管理面板中的 Strapi](/cms/features/internationalization#settings)。
¥To work with API content for a locale, please ensure the locale has been already [added to Strapi in the admin panel](/cms/features/internationalization#settings).
:::
`locale` [接口参数](/cms/api/rest/parameters) 可用于处理仅针对指定语言环境的文档。`locale` 将语言环境代码作为值(参见
### `GET` 获取特定语言环境中的所有文档 {#rest-get-all}
¥`GET` Get all documents in a specific locale
### `GET` 获取特定语言环境中的文档 {#rest-get}
¥`GET` Get a document in a specific locale
要获取给定语言环境中的特定文档,请在查询的 `locale` 参数之后添加:
¥To get a specific document in a given locale, add the `locale` parameter to the query:
| 使用案例 | 语法格式和更多信息的链接 |
| ------ | ---------------------------------------------------------------------------------------------- |
| 在集合类型中 | [`GET /api/content-type-plural-name/document-id?locale=locale-code`](#get-one-collection-type) |
| 在单一类型中 | [`GET /api/content-type-singular-name?locale=locale-code`](#get-one-single-type) |
#### 集合类型 {#get-one-collection-type}
¥Collection types
要获取给定语言环境中集合类型中的特定文档,请在查询的 `documentId` 之后添加 `locale` 参数:
¥To get a specific document in a collection type in a given locale, add the `locale` parameter to the query, after the `documentId`:
#### 单一类型 {#get-one-single-type}
¥Single types
要获取给定语言环境中的特定单一类型文档,请在查询的 `locale` 参数之后添加单一类型名称:
¥To get a specific single type document in a given locale, add the `locale` parameter to the query, after the single type name:
### `POST` 为集合类型创建新的本地化文档 {#rest-create}
¥`POST` Create a new localized document for a collection type
若要从头开始创建本地化文档,请向内容 API 发送 POST 请求。根据你是要为默认语言环境还是其他语言环境创建它,你可能需要在请求的正文中传递 `locale` 参数
¥To create a localized document from scratch, send a POST request to the Content API. Depending on whether you want to create it for the default locale or for another locale, you might need to pass the `locale` parameter in the request's body
| 使用案例 | 语法格式和更多信息的链接 |
| --------- | --------------------------------------------------------------------------------------- |
| 为默认语言环境创建 | [`POST /api/content-type-plural-name`](#rest-create-default-locale) |
| 为特定语言环境创建 | [`POST /api/content-type-plural-name`](#rest-create-specific-locale) + 在请求正文中传递语言环境 |
#### 针对默认语言环境 {#rest-create-default-locale}
¥For the default locale
如果请求主体中未传递任何语言环境,则使用应用的默认语言环境创建文档:
¥If no locale has been passed in the request body, the document is created using the default locale for the application:
#### 针对特定语言环境 {#rest-create-specific-locale}
¥For a specific locale
要为不同于默认区域设置的区域设置创建本地化条目,请将 `locale` 属性添加到 POST 请求的正文中:
¥To create a localized entry for a locale different from the default one, add the `locale` attribute to the body of the POST request:
### `PUT` 为现有文档创建新的或更新现有的语言环境版本 {#rest-update}
¥`PUT` Create a new, or update an existing, locale version for an existing document
将 `PUT` 请求发送到现有文档后,你可以:
¥With `PUT` requests sent to an existing document, you can:
* 创建文档的另一个语言环境版本,
¥create another locale version of the document,
* 或更新文档的现有语言环境版本。
¥or update an existing locale version of the document.
将 `PUT` 请求发送到相应的 URL,将 `locale=your-locale-code` 参数添加到查询 URL 并在请求正文中的 `data` 对象中传递属性:
¥Send the `PUT` request to the appropriate URL, adding the `locale=your-locale-code` parameter to the query URL and passing attributes in a `data` object in the request's body:
| 使用案例 | 语法格式和更多信息的链接 |
| ------ | ----------------------------------------------------------------------------------------------- |
| 在集合类型中 | [`PUT /api/content-type-plural-name/document-id?locale=locale-code`](#rest-put-collection-type) |
| 在单一类型中 | [`PUT /api/content-type-singular-name?locale=locale-code`](#rest-put-single-type) |
:::caution 提醒
为现有本地化条目创建本地化时,请求正文只能接受本地化字段。
¥When creating a localization for existing localized entries, the body of the request can only accept localized fields.
:::
:::tip 提示
Content-Type 应该启用 [`createLocalization` 权限](/cms/features/rbac#collection-and-single-types),否则请求将返回 `403: Forbidden` 状态。
¥The Content-Type should have the [`createLocalization` permission](/cms/features/rbac#collection-and-single-types) enabled, otherwise the request will return a `403: Forbidden` status.
:::
:::note 注意
无法更改现有本地化条目的区域设置。更新本地化条目时,如果你在请求正文中设置 `locale` 属性,它将被忽略。
¥It is not possible to change the locale of an existing localized entry. When updating a localized entry, if you set a `locale` attribute in the request body it will be ignored.
:::
#### 在集合类型中 {#rest-put-collection-type}
¥In a collection type
要为集合类型中的现有文档创建新语言环境,请在查询中添加 `locale` 参数(位于 `documentId` 之后),并将数据传递到请求的正文:
¥To create a new locale for an existing document in a collection type, add the `locale` parameter to the query, after the `documentId`, and pass data to the request's body:
#### 在单一类型中 {#rest-put-single-type}
¥In a single type
要为现有单一类型文档创建新语言环境,请在查询中添加 `locale` 参数(位于单一类型名称之后),并将数据传递到请求的正文:
¥To create a new locale for an existing single type document, add the `locale` parameter to the query, after the single type name, and pass data to the request's body:
### `DELETE` 删除文档的语言环境版本 {#rest-delete}
¥`DELETE` Delete a locale version of a document
要删除文档的语言环境版本,请发送带有适当 `locale` 参数的 `DELETE` 请求。
¥To delete a locale version of a document, send a `DELETE` request with the appropriate `locale` parameter.
`DELETE` 请求仅在成功时发送 204 HTTP 状态代码,并且不会在响应正文中返回任何数据。
¥`DELETE` requests only send a 204 HTTP status code on success and do not return any data in the response body.
#### 在集合类型中 {#rest-delete-collection-type}
¥In a collection type
要仅删除集合类型中文档的特定语言环境版本,请在 `documentId` 后的查询中添加 `locale` 参数:
¥To delete only a specific locale version of a document in a collection type, add the `locale` parameter to the query after the `documentId`:
#### 在单一类型中 {#rest-delete-single-type}
¥In a single type
要仅删除单一类型文档的特定语言环境版本,请在单一类型名称后的查询中添加 `locale` 参数:
¥To delete only a specific locale version of a single type document, add the `locale` parameter to the query after the single type name:
# 参数
Source: https://docs.strapi.io/cms/api/rest/parameters
# REST API 参数 {#rest-api-parameters}
¥REST API parameters
API 参数可与 [REST API](/cms/api/rest) 一起使用来对结果进行筛选、排序和分页,以及选择要填充的字段和关系。此外,还可以使用与可选 Strapi 功能相关的特定参数,例如内容类型的发布状态和区域设置。
¥API parameters can be used with the [REST API](/cms/api/rest) to filter, sort, and paginate results and to select fields and relations to populate. Additionally, specific parameters related to optional Strapi features can be used, like the publication state and locale of a content-type.
以下 API 参数可用:
¥The following API parameters are available:
| 运算符 | 类型 | 描述 |
| ------------ | ------ | ------------------------------------------------------------ |
| `filters` | 目的 | [过滤响应](/cms/api/rest/filters) |
| `locale` | 字符串 | [选择语言环境](/cms/api/rest/locale) |
| `status` | 字符串 | [选择草稿和发布状态](/cms/api/rest/status) |
| `populate` | 字符串或对象 | [填充关系、组件或动态区域](/cms/api/rest/populate-select#population) |
| `fields` | 数组 | [仅选择要显示的特定字段](/cms/api/rest/populate-select#field-selection) |
| `sort` | 字符串或数组 | [对响应进行排序](/cms/api/rest/sort-pagination.md#sorting) |
| `pagination` | 目的 | [翻阅条目](/cms/api/rest/sort-pagination.md#pagination) |
查询参数使用 (即使用方括号 `[]` 进行编码)。
¥Query parameters use the (i.e. they are encoded using square brackets `[]`).
:::tip 提示
可以使用和组合各种 REST API 参数来查询你的内容,这可能会导致查询 URL 长而复杂。 👉 你可以使用 Strapi 的 [交互式查询构建器](/cms/api/rest/interactive-query-builder) 工具更方便地构建查询 URL。🤗
¥A wide range of REST API parameters can be used and combined to query your content, which can result in long and complex query URLs. 👉 You can use Strapi's [interactive query builder](/cms/api/rest/interactive-query-builder) tool to build query URLs more conveniently. 🤗
:::
# 填充并选择
Source: https://docs.strapi.io/cms/api/rest/populate-select
# REST API:人口和字段选择 {#rest-api-population--field-selection}
¥REST API: Population & Field Selection
默认情况下,[REST API](/cms/api/rest) 不填充任何关系、媒体字段、组件或动态区域。使用 [`populate` 参数](#population) 填充特定字段,使用 [`select` 参数](#field-selection) 仅返回特定字段和查询结果。
¥The [REST API](/cms/api/rest) by default does not populate any relations, media fields, components, or dynamic zones. Use the [`populate` parameter](#population) to populate specific fields and the [`select` parameter](#field-selection) to return only specific fields with the query results.
:::tip 提示
## 人口 {#population}
¥Population
默认情况下,REST API 不会填充任何类型的字段,因此它不会填充关系、媒体字段、组件或动态区域,除非你传递 `populate` 参数来填充各种字段类型。
¥The REST API by default does not populate any type of fields, so it will not populate relations, media fields, components, or dynamic zones unless you pass a `populate` parameter to populate various field types.
`populate` 参数可以单独使用,也可以使用 [与多个操作符结合](#combining-population-with-other-operators) 对总体进行更多控制。
¥The `populate` parameter can be used alone or [in combination with with multiple operators](#combining-population-with-other-operators) to have much more control over the population.
:::caution 提醒
必须为正在填充的内容类型启用 `find` 权限。如果角色无权访问内容类型,则不会填充该角色(有关如何为内容类型启用 `find` 权限的其他信息,请参阅 [用户指南](/cms/features/users-permissions#editing-a-role))。
¥The `find` permission must be enabled for the content-types that are being populated. If a role doesn't have access to a content-type it will not be populated (see [User Guide](/cms/features/users-permissions#editing-a-role) for additional information on how to enable `find` permissions for content-types).
:::
:::note 注意
目前无法仅通过请求返回 id 数组。
¥It's currently not possible to return just an array of ids with a request.
:::
:::strapi 填充指南
[REST API 指南](/cms/api/rest/guides/intro) 部分包含有关填充参数的各种可能用例的更详细信息:
¥The [REST API guides](/cms/api/rest/guides/intro) section includes more detailed information about various possible use cases for the populate parameter:
* [了解填充](/cms/api/rest/guides/understanding-populate) 指南通过图表、比较和实际示例详细解释了填充的工作原理。
¥The [Understanding populate](/cms/api/rest/guides/understanding-populate) guide explains in details how populate works, with diagrams, comparisons, and real-world examples.
* [如何填充创建者字段](/cms/api/rest/guides/populate-creator-fields) 指南提供了有关如何将 `createdBy` 和 `updatedBy` 字段添加到查询响应中的分步说明。
¥The [How to populate creator fields](/cms/api/rest/guides/populate-creator-fields) guide provides step-by-step instructions on how to add `createdBy` and `updatedBy` fields to your queries responses.
:::
下表总结了可能的填充用例及其关联的参数语法,并链接到了解填充指南的各部分,其中包括更详细的说明:
¥The following table sums up possible populate use cases and their associated parameter syntaxes, and links to sections of the Understanding populate guide which includes more detailed explanations:
| 使用案例 | 参数语法示例 | 详细解释请阅读 |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| 填充所有内容,深度为 1 层,包括媒体字段、关系、组件和动态区域 | `populate=*` | [填充所有关系和字段,深 1 层](/cms/api/rest/guides/understanding-populate#populate-all-relations-and-fields-1-level-deep) |
| 填充一个关系, 1 层深 | `populate=a-relation-name` | [为特定关系填充 1 层深度](/cms/api/rest/guides/understanding-populate#populate-1-level-deep-for-specific-relations) |
| 填充多个关系, 深 1 层 | `populate[0]=relation-name&populate[1]=another-relation-name&populate[2]=yet-another-relation-name` | [为特定关系填充 1 层深度](/cms/api/rest/guides/understanding-populate#populate-1-level-deep-for-specific-relations) |
| 填充一些深层次的关系 | `populate[root-relation-name][populate][0]=nested-relation-name` | [为特定关系填充多个深度级别](/cms/api/rest/guides/understanding-populate#populate-several-levels-deep-for-specific-relations) |
| 填充组件 | `populate[0]=component-name` | [填充组件](/cms/api/rest/guides/understanding-populate#populate-components) |
| 填充组件及其嵌套组件之一 | `populate[0]=component-name&populate[1]=component-name.nested-component-name` | [填充组件](/cms/api/rest/guides/understanding-populate#populate-components) |
| 填充动态区域(仅填充其第一级元素) | `populate[0]=dynamic-zone-name` | [填充动态区域](/cms/api/rest/guides/understanding-populate#populate-dynamic-zones) |
| 使用精确定义、详细的填充策略填充动态区域及其嵌套元素和关系 | `populate[dynamic-zone-name][on][component-category.component-name][populate][relation-name][populate][0]=field-name` | [填充动态区域](/cms/api/rest/guides/understanding-populate#populate-dynamic-zones) |
:::tip 提示
构建具有多级填充的复杂查询的最简单方法是使用我们的 [交互式查询构建器](/cms/api/rest/interactive-query-builder) 工具。
¥The easiest way to build complex queries with multiple-level population is to use our [interactive query builder](/cms/api/rest/interactive-query-builder) tool.
:::
### 将 Population 与其他运算符结合起来 {#combining-population-with-other-operators}
¥Combining Population with other operators
通过利用 `populate` 运算符,可以在总体查询中组合其他运算符,例如 [字段选择](/cms/api/rest/populate-select#field-selection)、[filters](/cms/api/rest/filters) 和 [sort](/cms/api/rest/sort-pagination)。
¥By utilizing the `populate` operator it is possible to combine other operators such as [field selection](/cms/api/rest/populate-select#field-selection), [filters](/cms/api/rest/filters), and [sort](/cms/api/rest/sort-pagination) in the population queries.
:::caution 提醒
总体和分页运算符不能组合使用。
¥The population and pagination operators cannot be combined.
:::
#### 使用字段选择填充 {#populate-with-field-selection}
¥Populate with field selection
`fields` 和 `populate` 可以组合。
¥`fields` and `populate` can be combined.
#### 填充过滤 {#populate-with-filtering}
¥Populate with filtering
`filters` 和 `populate` 可以组合。
¥`filters` and `populate` can be combined.
# 关系
Source: https://docs.strapi.io/cms/api/rest/relations
# 管理与 API 请求的关系 {#managing-relations-with-api-requests}
¥Managing relations with API requests
定义内容类型(在数据库层中指定为实体)之间的关系是将实体相互连接起来。
¥Defining relations between content-types (that are designated as entities in the database layers) is connecting entities with each other.
从关闭 i18n 的 [管理面板](/cms/features/content-manager#relational-fields) 到打开 i18n 的 [REST API](/cms/api/rest) 的关系:
¥Relations between content-types can be managed through the [admin panel](/cms/features/content-manager#relational-fields) or through [REST API](/cms/api/rest) or [Document Service API](/cms/api/document-service) requests.
可以通过在请求正文中传递参数,使用内容 API 连接、断开或设置关系。这些有效负载适用于单条目关系和多条目关系(一对多、多对一、多对多和多路关系)。当关系字段允许多个链接时,API 会期望关系 ID 数组,并在响应中返回数组。
¥Relations can be connected, disconnected or set through the Content API by passing parameters in the body of the request. These payloads work for both single-entry relations and multi relations (one-to-many, many-to-one, many-to-many, and many-way). When a relational field allows multiple links, the API expects arrays of relation IDs and returns arrays in responses.
| 参数名称 | 描述 | 更新类型 |
| --------------------------- | --------------------------------------------------------------------------------------------------- | ---- |
| [`connect`](#connect) | 连接新实体。
不能与 `connect` 或 `disconnect` 结合使用。 | 满的 |
:::note 注意
多重关系可以通过 REST API 和 [GraphQL API](/cms/api/graphql#fetch-relations) 进行管理:`connect`、`disconnect` 和 `set` 操作在两个 API 中都可用。但是,[文档服务 API](/cms/api/document-service) 不处理关联关系。
¥Multi relations can be managed from the REST API and the [GraphQL API](/cms/api/graphql#fetch-relations): the `connect`, `disconnect`, and `set` operations are available across both APIs. However, the [Document Service API](/cms/api/document-service) does not handle relations.
:::
:::note 注意
当在内容类型上启用 [国际化(i18n)](/cms/features/internationalization) 时,你还可以传递语言环境来为特定语言环境设置关系,如以下文档服务 API 示例所示:
¥When [Internationalization (i18n)](/cms/features/internationalization) is enabled on the content-type, you can also pass a locale to set relations for a specific locale, as in this Document Service API example:
```js
await strapi.documents('api::restaurant.restaurant').update({
documentId: 'a1b2c3d4e5f6g7h8i9j0klm',
locale: 'fr',
data: {
category: {
connect: ['z0y2x4w6v8u1t3s5r7q9onm', 'j9k8l7m6n5o4p3q2r1s0tuv']
}
}
})
```
如果未传递任何语言环境,则将假定使用默认语言环境。
¥If no locale is passed, the default locale will be assumed.
:::
## `connect` {#connect}
在请求正文中使用 `connect` 执行部分更新,连接指定的关系。
¥Using `connect` in the body of a request performs a partial update, connecting the specified relations.
`connect` 接受简写或全写语法:
¥`connect` accepts either a shorthand or a longhand syntax:
| 语法类型 | 语法示例 |
| --------- | ------------------------------------------------------------------------------------------------- |
| shorthand | `connect: ['z0y2x4w6v8u1t3s5r7q9onm', 'j9k8l7m6n5o4p3q2r1s0tuv']` |
| longhand | `connect: [{ documentId: 'z0y2x4w6v8u1t3s5r7q9onm' }, { documentId: 'j9k8l7m6n5o4p3q2r1s0tuv' }]` |
你还可以使用 [重新排序关系](#relations-reordering) 的普通语法。
¥You can also use the longhand syntax to [reorder relations](#relations-reordering).
`connect` 可以与 [`disconnect`](#disconnect) 结合使用。
¥`connect` can be used in combination with [`disconnect`](#disconnect).
:::caution 提醒
`connect` 尚未正式支持媒体属性。高级用户理论上可以通过指定上传文件 ID 来连接媒体条目,但 Strapi 不推荐或支持此方法,并且此方法很容易出错(例如,当 Draft & Publish 使用不匹配的 ID 时)。谨慎操作。
¥`connect` is not officially supported for media attributes. Advanced users can technically connect media entries by targeting upload file IDs, but this workaround isn't recommended or supported by Strapi and can easily break (e.g. when Draft & Publish uses mismatched IDs). Proceed with caution.
:::
### 关系重新排序 {#relations-reordering}
¥Relations reordering
省略 `position` 参数(如 `documentId: 'srkvrr77k96o44d9v6ef1vu9'`)默认为 `position: { end: true }`。所有其他关系都相对于另一个现有的 `id`(使用 `after` 或 `before`)或相对于关系列表(使用 `start` 或 `end`)定位。操作按照 `connect` 数组中定义的顺序依次处理,因此生成的数据库记录将如下所示:
¥Omitting the `position` argument (as in `documentId: 'srkvrr77k96o44d9v6ef1vu9'`) defaults to `position: { end: true }`. All other relations are positioned relative to another existing `id` (using `after` or `before`) or relative to the list of relations (using `start` or `end`). Operations are treated sequentially in the order defined in the `connect` array, so the resulting database record will be the following:
```js
categories: [
{ id: 'nyk7047azdgbtjqhl7btuxw' },
{ id: 'j9k8l7m6n5o4p3q2r1s0tuv' },
{ id: '6u86wkc6x3parjd4emikhmx6' },
{ id: '3r1wkvyjwv0b9b36s7hzpxl7' },
{ id: 'a1b2c3d4e5f6g7h8i9j0klm' },
{ id: 'rkyqa499i84197l29sbmwzl' },
{ id: 'srkvrr77k96o44d9v6ef1vu9' }
]
```
### 边缘情况:草稿和发布或 i18n 已禁用 {#edge-cases-draft--publish-or-i18n-disabled}
¥Edge cases: Draft & Publish or i18n disabled
当 Strapi 5 的一些内置功能针对内容类型(例如 [起草并发布](/cms/features/draft-and-publish) 和 [国际化 (i18)](/cms/features/internationalization))禁用时,`connect` 参数的使用方式可能会有所不同:
¥When some built-in features of Strapi 5 are disabled for a content-type, such as [Draft & Publish](/cms/features/draft-and-publish) and [Internationalization (i18)](/cms/features/internationalization), the `connect` parameter might be used differently:
**从关闭草稿和发布的 `Category` 到打开草稿和发布的 `Article` 的关系:**
¥**Relation from a `Category` with i18n *off* to an `Article` with i18n *on*:**
在这种情况下,你可以选择要连接到哪个语言环境:
¥In this situation you can select which locale you are connecting to:
```js
data: {
categories: {
connect: [
{ documentId: 'z0y2x4w6v8u1t3s5r7q9onm', locale: 'en' },
// Connect to the same document id but with a different locale 👇
{ documentId: 'z0y2x4w6v8u1t3s5r7q9onm', locale: 'fr' },
]
}
}
```
**根据你的用例阅读一些高级 `Category`。**
¥**Relation from a `Category` with Draft & Publish *off* to an `Article` with Draft & Publish *on*:**
```js
data: {
categories: {
connect: [
{ documentId: 'z0y2x4w6v8u1t3s5r7q9onm', status: 'draft' },
// Connect to the same document id but with different publication states 👇
{ documentId: 'z0y2x4w6v8u1t3s5r7q9onm', status: 'published' },
]
}
}
```
## `disconnect` {#disconnect}
在请求正文中使用 `disconnect` 执行部分更新,断开指定的关系。
¥Using `disconnect` in the body of a request performs a partial update, disconnecting the specified relations.
`disconnect` 接受简写或全写语法:
¥`disconnect` accepts either a shorthand or a longhand syntax:
| 语法类型 | 语法示例 |
| --------- | ---------------------------------------------------------------------------------------------------- |
| shorthand | `disconnect: ['z0y2x4w6v8u1t3s5r7q9onm', 'j9k8l7m6n5o4p3q2r1s0tuv']` |
| longhand | `disconnect: [{ documentId: 'z0y2x4w6v8u1t3s5r7q9onm' }, { documentId: 'j9k8l7m6n5o4p3q2r1s0tuv' }]` |
`disconnect` 可以与 [`connect`](#connect) 结合使用。
¥`disconnect` can be used in combination with [`connect`](#connect).
## `set` {#set}
使用 `set` 执行完整更新,按照指定的顺序将所有现有关系替换为指定的关系。
¥Using `set` performs a full update, replacing all existing relations with the ones specified, in the order specified.
`set` 接受简写或全写语法:
¥`set` accepts a shorthand or a longhand syntax:
| 语法类型 | 语法示例 |
| --------- | --------------------------------------------------------------------------------------------- |
| shorthand | `set: ['z0y2x4w6v8u1t3s5r7q9onm', 'j9k8l7m6n5o4p3q2r1s0tuv']` |
| longhand | `set: [{ documentId: 'z0y2x4w6v8u1t3s5r7q9onm' }, { documentId: 'j9k8l7m6n5o4p3q2r1s0tuv' }]` |
由于 `set` 替换了所有现有关系,因此不应与其他参数结合使用。要执行部分更新,请使用 [`connect`](#connect) 和 [`disconnect`](#disconnect)。
¥As `set` replaces all existing relations, it should not be used in combination with other parameters. To perform a partial update, use [`connect`](#connect) and [`disconnect`](#disconnect).
:::note 省略集合
省略任何参数都相当于使用 `set`。 例如,以下 3 种语法都是等效的:
¥Omitting any parameter is equivalent to using `set`. For instance, the following 3 syntaxes are all equivalent:
* `data: { categories: set: [{ documentId: 'z0y2x4w6v8u1t3s5r7q9onm' }, { documentId: 'j9k8l7m6n5o4p3q2r1s0tuv' }] }}`
* `data: { categories: set: ['z0y2x4w6v8u1t3s5r7q9onm2', 'j9k8l7m6n5o4p3q2r1s0tuv'] }}`
* `data: { categories: ['z0y2x4w6v8u1t3s5r7q9onm2', 'j9k8l7m6n5o4p3q2r1s0tuv'] }`
:::
# 排序和分页
Source: https://docs.strapi.io/cms/api/rest/sort-pagination
# REST API:排序和分页 {#rest-api-sort--pagination}
¥REST API: Sort & Pagination
查询返回到 [REST API](/cms/api/rest) 的条目可以进行排序和分页。
¥Entries that are returned by queries to the [REST API](/cms/api/rest) can be sorted and paginated.
:::tip 提示
JavaScript query (built with the qs library):
### 示例:使用 2 个字段排序并设置顺序 {#example-sort-using-2-fields-and-set-the-order}
¥Example: Sort using 2 fields and set the order
使用 `sort` 参数并在排序字段上定义 `:asc` 或 `:desc`,你可以获得按特定顺序排序的结果。
¥Using the `sort` parameter and defining `:asc` or `:desc` on sorted fields, you can get results sorted in a particular order.
JavaScript query (built with the qs library):
## 分页 {#pagination}
¥Pagination
查询可以接受 `pagination` 个参数。结果可以分页:
¥Queries can accept `pagination` parameters. Results can be paginated:
* 通过 [page](#pagination-by-page)(即指定页码和每页的条目数)
¥either by [page](#pagination-by-page) (i.e., specifying a page number and the number of entries per page)
* 或按 [offset](#pagination-by-offset)(即指定要跳过和返回的条目数)
¥or by [offset](#pagination-by-offset) (i.e., specifying how many entries to skip and to return)
:::note 注意
分页方法不能混合。始终使用 `page` 与 `pageSize` 或 `start` 与 `limit`。
¥Pagination methods can not be mixed. Always use either `page` with `pageSize` **or** `start` with `limit`.
:::
### 按页分页 {#pagination-by-page}
¥Pagination by page
要按页对结果进行分页,请使用以下参数:
¥To paginate results by page, use the following parameters:
| 范围 | 类型 | 描述 | 默认 |
| ----------------------- | --- | -------------- | -- |
| `pagination[page]` | 整数 | 页码 | 1 |
| `pagination[pageSize]` | 整数 | 页面大小 | 25 |
| `pagination[withCount]` | 布尔值 | 将条目总数和页数添加到响应中 | 真的 |
JavaScript query (built with the qs library):
### 按偏移量分页 {#pagination-by-offset}
¥Pagination by offset
要按偏移量对结果进行分页,请使用以下参数:
¥To paginate results by offset, use the following parameters:
| 范围 | 类型 | 描述 | 默认 |
| ----------------------- | --- | -------------- | ------ |
| `pagination[start]` | 整数 | 起始值(即返回的第一个条目) | 0 |
| `pagination[limit]` | 整数 | 要返回的条目数 | 25 |
| `pagination[withCount]` | 布尔值 | 切换显示响应的条目总数 | `true` |
:::tip 提示
`pagination[limit]` 的默认值和最大值可以是带有 `api.rest.defaultLimit` 和 `api.rest.maxLimit` 键的 [在 `./config/api.js` 中配置](/cms/configurations/api) 文件。
¥The default and maximum values for `pagination[limit]` can be [configured in the `./config/api.js`](/cms/configurations/api) file with the `api.rest.defaultLimit` and `api.rest.maxLimit` keys.
:::
JavaScript query (built with the qs library):
# 状态
Source: https://docs.strapi.io/cms/api/rest/status
# REST API:`status` {#rest-api-status}
[REST API](/cms/api/rest) 提供了根据结果状态(草稿或已发布)过滤结果的功能。
¥The [REST API](/cms/api/rest) offers the ability to filter results based on their status, draft or published.
:::prerequisites
应启用 [起草并发布](/cms/features/draft-and-publish) 功能。
¥The [Draft & Publish](/cms/features/draft-and-publish) feature should be enabled.
:::
查询可以接受 `status` 参数来明确定义要填充哪些字段,语法选项示例如下。
¥Queries can accept a `status` parameter to fetch documents based on their status:
* `published`:仅返回文档的已发布版本(默认)
¥`published`: returns only the published version of documents (default)
* `draft`:仅返回文档的草稿版本
¥`draft`: returns only the draft version of documents
:::tip 提示
在响应数据中,`publishedAt` 字段对于草稿为 `null`。
¥In the response data, the `publishedAt` field is `null` for drafts.
:::
:::note 注意
由于默认返回已发布的版本,因此不传递状态参数相当于传递 `status=published`。
¥Since published versions are returned by default, passing no status parameter is equivalent to passing `status=published`.
:::
JavaScript query (built with the qs library):
# 上传文件
Source: https://docs.strapi.io/cms/api/rest/upload
# REST API:上传文件 {#rest-api-upload-files}
¥REST API: Upload files
[媒体库功能](/cms/features/media-library) 由 `upload` 包在 Strapi 的后端服务器中提供支持。要将文件上传到 Strapi,你可以直接从管理面板使用媒体库,也可以使用 [REST API](/cms/api/rest),具有以下可用端点:
¥The [Media Library feature](/cms/features/media-library) is powered in the back-end server of Strapi by the `upload` package. To upload files to Strapi, you can either use the Media Library directly from the admin panel, or use the [REST API](/cms/api/rest), with the following available endpoints :
| 方法 | 路径 | 描述 |
| :- | :---------------------- | :----- |
| 得到 | `/api/upload/files` | 获取文件列表 |
| 得到 | `/api/upload/files/:id` | 获取特定文件 |
| 邮政 | `/api/upload` | 上传文件 |
| 邮政 | `/api/upload?id=x` | 更新文件信息 |
| 删除 | `/api/upload/files/:id` | 删除文件 |
:::note 注意
* [文件夹](/cms/features/media-library#organizing-assets-with-folders) 是管理面板专用功能,不属于 Content API(REST 或 GraphQL)。通过 REST 上传的文件位于自动创建的 "API 上传" 文件夹中。
¥[Folders](/cms/features/media-library#organizing-assets-with-folders) are an admin panel-only feature and are not part of the Content API (REST or GraphQL). Files uploaded through REST are located in the automatically created "API Uploads" folder.
* GraphQL API 不支持上传媒体文件。要上传文件,请使用 REST API 或直接从管理面板中的 [媒体库](/cms/features/media-library) 添加文件。仍然可以进行一些 GraphQL 修改来更新或删除已上传的媒体文件(有关详细信息,请参阅 [GraphQL API 文档](/cms/api/graphql#mutations-on-media-files))。
¥The GraphQL API does not support uploading media files. To upload files, use the REST API or directly add files from the [Media Library](/cms/features/media-library) in the admin panel. Some GraphQL mutations to update or delete uploaded media files are still possible (see [GraphQL API documentation](/cms/api/graphql#mutations-on-media-files) for details).
:::
## 上传文件 {#upload-files}
¥Upload files
将一个或多个文件上传到你的应用。
¥Upload one or more files to your application.
`files` 是唯一可接受的参数,并描述要上传的文件。值可以是缓冲区或流:
¥`files` is the only accepted parameter, and describes the file(s) to upload. The value(s) can be a Buffer or Stream:
:::caution 提醒
你必须在请求正文中发送 FormData。
¥You have to send FormData in your request body.
:::
## 上传入口文件 {#upload-entry-files}
¥Upload entry files
上传一个或多个将链接到特定条目的文件。
¥Upload one or more files that will be linked to a specific entry.
接受以下参数:
¥The following parameters are accepted:
| 范围 | 描述 |
| ------------ | -------------------------------------------------- |
| `files` | 要上传的文件。该值可以是缓冲区或流。 |
| `path`(可选) | 文件将上传到的文件夹(仅在 Strapi-provider-upload-aws-s3 上受支持)。 |
| `refId` | 文件将链接到的条目的 ID。 |
| `ref` | 文件将链接到的模型的唯一 ID (uid)(请参阅下文)。 |
| `source`(可选) | 模型所在插件的名称。 |
| `field` | 文件将精确链接到的条目的字段。 |
例如,给定 `Restaurant` 模型属性:
¥For example, given the `Restaurant` model attributes:
```json title="/src/api/restaurant/content-types/restaurant/schema.json"
{
// ...
"attributes": {
"name": {
"type": "string"
},
"cover": {
"type": "media",
"multiple": false,
}
}
// ...
}
```
以下是相应前端的示例代码:
¥The following is an example of a corresponding front-end code:
```html
```
:::caution 提醒
你必须在请求正文中发送 FormData。
¥You have to send FormData in your request body.
:::
## 更新文件信息 {#update-fileinfo}
¥Update fileInfo
更新应用中的文件。
¥Update a file in your application.
`fileInfo` 是唯一可接受的参数,并描述要更新的文件信息:
¥`fileInfo` is the only accepted parameter, and describes the fileInfo to update:
```js
const fileId = 50;
const newFileData = {
alternativeText: 'My new alternative text for this image!',
};
const form = new FormData();
form.append('fileInfo', JSON.stringify(newFileData));
const response = await fetch(`http://localhost:1337/api/upload?id=${fileId}`, {
method: 'post',
body: form,
});
```
## 型号定义 {#models-definition}
¥Models definition
向 [model](/cms/backend-customization/models)(或另一个插件的模型)添加文件属性就像添加新关联一样。
¥Adding a file attribute to a [model](/cms/backend-customization/models) (or the model of another plugin) is like adding a new association.
以下示例允许你上传并将一个文件附加到 `avatar` 属性:
¥The following example lets you upload and attach one file to the `avatar` attribute:
```json title="/src/api/restaurant/content-types/restaurant/schema.json"
{
// ...
{
"attributes": {
"pseudo": {
"type": "string",
"required": true
},
"email": {
"type": "email",
"required": true,
"unique": true
},
"avatar": {
"type": "media",
"multiple": false,
}
}
}
// ...
}
```
以下示例允许你上传并将多张图片附加到 `restaurant` 内容类型:
¥The following example lets you upload and attach multiple pictures to the `restaurant` content-type:
```json title="/src/api/restaurant/content-types/restaurant/schema.json"
{
// ...
{
"attributes": {
"name": {
"type": "string",
"required": true
},
"covers": {
"type": "media",
"multiple": true,
}
}
}
// ...
}
```
# 后端定制
Source: https://docs.strapi.io/cms/backend-customization
# 后端定制 {#backend-customization}
¥Backend customization
:::strapi 消歧义:带子后端
作为无头 CMS,整个 Strapi 软件可以被视为你网站或应用的 "后端"。但 Strapi 软件本身包括 2 个不同的部分:
¥As a headless CMS, the Strapi software as a whole can be considered as the "back end" of your website or application.
But the Strapi software itself includes 2 different parts:
* Strapi 的后端部分是 Strapi 运行的 HTTP 服务器。与任何 HTTP 服务器一样,Strapi 后端接收请求并发送响应。你的内容存储在数据库中,Strapi 后端与数据库交互以创建、检索、更新和删除内容。
¥The **back-end** part of Strapi is an HTTP server that Strapi runs. Like any HTTP server, the Strapi back end receives requests and send responses. Your content is stored in a database, and the Strapi back end interacts with the database to create, retrieve, update, and delete content.
* Strapi 的前端部分称为管理面板。管理面板提供图形用户界面来帮助你构建和管理内容。
¥The **front-end** part of Strapi is called the admin panel. The admin panel presents a graphical user interface to help you structure and manage the content.
在本开发者文档中,'后端' 专指 Strapi 的后端部分。
¥Throughout this developer documentation, 'back end' refers *exclusively* to the back-end part of Strapi.
[获取已开始 > 管理面板页面](/cms/features/admin-panel) 提供了管理面板的概述,而 [管理面板自定义部分](/cms/admin-panel-customization) 详细介绍了管理面板可用的各种自定义选项。
¥The [Getting Started > Admin panel page](/cms/features/admin-panel) gives an admin panel overview and the [admin panel customization section](/cms/admin-panel-customization) details the various customization options available for the admin panel.
:::
Strapi 后端运行基于 (一个后端 JavaScript 框架)的 HTTP 服务器。
¥The Strapi back end runs an HTTP server based on , a back-end JavaScript framework.
与任何 HTTP 服务器一样,Strapi 后端接收请求并发送响应。你可以向 Strapi 后端发送请求,以通过 [REST](/cms/api/rest) 或 [GraphQL](/cms/api/graphql) API 创建、检索、更新或删除数据。
¥Like any HTTP server, the Strapi back end receives requests and send responses. You can send requests to the Strapi back end to create, retrieve, update, or delete data through the [REST](/cms/api/rest) or [GraphQL](/cms/api/graphql) APIs.
请求可以通过 Strapi 后端传输,如下所示:
¥A request can travel through the Strapi back end as follows:
1. Strapi 服务器收到 [request](/cms/backend-customization/requests-responses)。
¥The Strapi server receives a [request](/cms/backend-customization/requests-responses).
2. 请求命中按顺序运行的 [全局中间件](/cms/backend-customization/middlewares)。
¥The request hits [global middlewares](/cms/backend-customization/middlewares) that are run in a sequential order.
3. 请求命中 [route](/cms/backend-customization/routes)。 默认情况下,Strapi 会为你创建的所有内容类型生成路由文件(请参阅 [REST API 文档](/cms/api/rest)),并且可以添加和配置更多路由。
¥The request hits a [route](/cms/backend-customization/routes). By default, Strapi generates route files for all the content-types that you create (see [REST API documentation](/cms/api/rest)), and more routes can be added and configured.
4. [路由策略](/cms/backend-customization/policies) 充当只读验证步骤,可以阻止对路由的访问。[路由中间件](/cms/backend-customization/routes#middlewares) 可以控制请求流并在继续之前改变请求本身。
¥[Route policies](/cms/backend-customization/policies) act as a read-only validation step that can block access to a route. [Route middlewares](/cms/backend-customization/routes#middlewares) can control the request flow and mutate the request itself before moving forward.
5. [控制器](/cms/backend-customization/controllers) 在到达路由后执行代码。[服务](/cms/backend-customization/services) 是可选的附加代码,可用于构建可由控制器重用的自定义逻辑。
¥[Controllers](/cms/backend-customization/controllers) execute code once a route has been reached. [Services](/cms/backend-customization/services) are optional, additional code that can be used to build custom logic reusable by controllers.
6. 控制器和服务执行的代码与 [models](/cms/backend-customization/models) 交互,[models](/cms/backend-customization/models) 是存储在数据库中的内容结构的表示。 与模型所表示的数据交互由 [文档服务](/cms/api/document-service) 和 [查询引擎](/cms/api/query-engine) 处理。
¥The code executed by the controllers and services interacts with the [models](/cms/backend-customization/models) that are a representation of the content content structure stored in the database. Interacting with the data represented by the models is handled by the [Document Service](/cms/api/document-service) and [Query Engine](/cms/api/query-engine).
7. 你可以实现 [文档服务中间件](/cms/api/document-service/middlewares) 来控制数据,然后再将其发送到查询引擎。查询引擎也可以使用生命周期钩子,但我们建议你使用文档服务中间件,除非你绝对需要直接与数据库交互。
¥You can implement [Document Service middlewares](/cms/api/document-service/middlewares) to control the data before it's sent to the Query Engine. The Query Engine can also use lifecycle hooks though we recommend you use Document Service middlewares unless you absolutely need to directly interact with the database.
8. 服务器返回 [response](/cms/backend-customization/requests-responses)。响应可以在发送之前通过路由中间件和全局中间件返回。
¥The server returns a [response](/cms/backend-customization/requests-responses). The response can travel back through route middlewares and global middlewares before being sent.
全局中间件和路由中间件都包含异步回调函数 `await next()`。根据中间件返回的内容,请求将通过后端的较短或较长的路径:
¥Both global and route middlewares include an asynchronous callback function, `await next()`. Depending on what is returned by the middleware, the request will either go through a shorter or longer path through the back end:
* 如果中间件不返回任何内容,则请求将继续穿过后端的各个核心元素(即控制器、服务以及与数据库交互的其他层)。
¥If a middleware returns nothing, the request will continue travelling through the various core elements of the back end (i.e., controllers, services, and the other layers that interact with the database).
* 如果中间件在调用 `await next()` 之前返回,则会立即发送响应,跳过其余核心元素。然后它会沿着它出现的同一条链返回。
¥If a middleware returns before calling `await next()`, a response will be immediately sent, skipping the rest of the core elements. Then it will go back down the same chain it came up.
:::info 信息
请注意,本节页面中描述的所有自定义仅适用于 REST API。[GraphQL 自定义](/cms/plugins/graphql#customization) 在 GraphQL 插件文档中进行了描述。
¥Please note that all customizations described in the pages of this section are only for the REST API. [GraphQL customizations](/cms/plugins/graphql#customization) are described in the GraphQL plugin documentation.
:::
## 交互式图表 {#interactive-diagram}
¥Interactive diagram
下图表示请求如何通过 Strapi 后端。你可以单击任何形状以跳转到文档中的相关页面。
¥The following diagram represents how requests travel through the Strapi back end. You can click on any shape to jump to the relevant page in the documentation.
¥
# 控制器
Source: https://docs.strapi.io/cms/backend-customization/controllers
# 控制器 {#controllers}
¥Controllers
控制器是 JavaScript 文件,其中包含一组称为操作的方法,客户端根据请求的 [route](/cms/backend-customization/routes)。每当客户端请求路由时,该操作都会执行业务逻辑代码并发回 [response](/cms/backend-customization/requests-responses)。控制器代表模型-视图-控制器 (MVC) 模式中的 C。
¥Controllers are JavaScript files that contain a set of methods, called actions, reached by the client according to the requested [route](/cms/backend-customization/routes). Whenever a client requests the route, the action performs the business logic code and sends back the [response](/cms/backend-customization/requests-responses). Controllers represent the C in the model-view-controller (MVC) pattern.
在大多数情况下,控制器将包含项目的大部分业务逻辑。但随着控制器的逻辑变得越来越复杂,使用 [services](/cms/backend-customization/services) 将代码组织成可重用的部分是一个很好的做法。
¥In most cases, the controllers will contain the bulk of a project's business logic. But as a controller's logic becomes more and more complicated, it's a good practice to use [services](/cms/backend-customization/services) to organize the code into re-usable parts.
The diagram represents a simplified version of how a request travels through the Strapi back end, with controllers highlighted. The backend customization introduction page includes a complete, interactive diagram.
:::caution 清理输入和输出
覆盖核心操作时,务必验证并清理查询和响应,以避免泄露私有字段或绕过访问规则。在从自定义操作返回数据之前,使用 `validateQuery`(可选)、`sanitizeQuery`(推荐)和 `sanitizeOutput`。请参阅下面的示例,了解如何安全地覆盖 `find`。
¥When overriding core actions, always validate and sanitize queries and responses to avoid leaking private fields or bypassing access rules. Use `validateQuery` (optional), `sanitizeQuery` (recommended), and `sanitizeOutput` before returning data from custom actions. See the example below for a safe `find` override.
:::
## 执行 {#implementation}
¥Implementation
控制器可以是 [手动生成或添加](#adding-a-new-controller)。Strapi 提供了 `createCoreController` 工厂功能,可自动生成核心控制器并允许构建自定义控制器或 [扩展或替换生成的控制器](#extending-core-controllers)。
¥Controllers can be [generated or added manually](#adding-a-new-controller). Strapi provides a `createCoreController` factory function that automatically generates core controllers and allows building custom ones or [extend or replace the generated controllers](#extending-core-controllers).
### 添加新控制器 {#adding-a-new-controller}
¥Adding a new controller
可以实现一个新的控制器:
¥A new controller can be implemented:
* 与 [交互式 CLI 命令 `strapi generate`](/cms/cli)
¥with the [interactive CLI command `strapi generate`](/cms/cli)
* 或通过创建 JavaScript 文件手动:
¥or manually by creating a JavaScript file:
* 在 `./src/api/[api-name]/controllers/` 中用于 API 控制器(此位置很重要,因为 Strapi 从那里自动加载控制器)
¥in `./src/api/[api-name]/controllers/` for API controllers (this location matters as controllers are auto-loaded by Strapi from there)
* 或者在插件控制器的 `./src/plugins/[plugin-name]/server/controllers/` 这样的文件夹中,尽管只要插件接口在 `strapi-server.js` 文件中正确导出(请参阅 [插件服务器 API 文档](/cms/plugins-development/server-api)),它们就可以在其他地方创建
¥or in a folder like `./src/plugins/[plugin-name]/server/controllers/` for plugin controllers, though they can be created elsewhere as long as the plugin interface is properly exported in the `strapi-server.js` file (see [Server API for Plugins documentation](/cms/plugins-development/server-api))
每个控制器操作可以是 `async` 或 `sync` 功能。每个操作都会接收一个上下文对象 (`ctx`) 作为参数。`ctx` 包含 [请求上下文](/cms/backend-customization/requests-responses#ctxrequest) 和 [响应上下文](/cms/backend-customization/requests-responses#ctxresponse)。
¥Each controller action can be an `async` or `sync` function.
Every action receives a context object (`ctx`) as a parameter. `ctx` contains the [request context](/cms/backend-customization/requests-responses#ctxrequest) and the [response context](/cms/backend-customization/requests-responses#ctxresponse).
Example: GET /hello route calling a basic controller
定义了具体的 `GET /hello` [route](/cms/backend-customization/routes),路由文件的名称(即 `index`)用于调用控制器处理程序(即 `index`)。每次向服务器发送 `GET /hello` 请求时,Strapi 都会调用 `hello.js` 控制器中的 `index` 操作,该操作返回 `Hello World!`:
¥A specific `GET /hello` [route](/cms/backend-customization/routes) is defined, the name of the router file (i.e. `index`) is used to call the controller handler (i.e. `index`). Every time a `GET /hello` request is sent to the server, Strapi calls the `index` action in the `hello.js` controller, which returns `Hello World!`:
:::note 注意
当创建新的 [content-type](/cms/backend-customization/models#content-types) 时,Strapi 会使用占位符代码构建通用控制器,以供自定义。
¥When a new [content-type](/cms/backend-customization/models#content-types) is created, Strapi builds a generic controller with placeholder code, ready to be customized.
:::
:::tip 提示
要了解自定义控制器可能的高级用法,请阅读后端自定义示例说明书的 [服务和控制器](/cms/backend-customization/examples/services-and-controllers) 页。
¥To see a possible advanced usage for custom controllers, read the [services and controllers](/cms/backend-customization/examples/services-and-controllers) page of the backend customization examples cookbook.
:::
### 控制器和路由:路由如何到达控制器操作 {#controllers--routes-how-routes-reach-controller-actions}
¥Controllers & Routes: How routes reach controller actions
* 核心映射自动:生成内容类型时,Strapi 会创建匹配的控制器和一个路由文件,该文件已针对标准操作(`find`、`findOne`、`create`、`update` 和 `delete`)。在生成的控制器中覆盖任何这些操作都不需要修改路由 - 路由会保留相同的处理程序字符串并执行更新后的逻辑。
¥Core mapping is automatic: when you generate a content-type, Strapi creates the matching controller and a router file that already targets the standard actions (`find`, `findOne`, `create`, `update`, and `delete`). Overriding any of these actions inside the generated controller does not require touching the router — the route keeps the same handler string and executes your updated logic.
* 仅应为新操作或路径添加路由。如果你引入了一个全新的方法(例如 `exampleAction`),请创建或更新一个路由条目,使其 `handler` 指向该操作,以便 HTTP 请求可以访问它。使用完全限定的处理程序语法 `::..`(例如,API 控制器使用 `api::restaurant.restaurant.exampleAction`,插件控制器使用 `plugin::menus.menu.exampleAction`)。
¥Adding a route should only be done for new actions or paths. If you introduce a brand-new method such as `exampleAction`, create or update a route entry whose `handler` points to the action so HTTP requests can reach it. Use the fully-qualified handler syntax `::..` (e.g. `api::restaurant.restaurant.exampleAction` for an API controller or `plugin::menus.menu.exampleAction` for a plugin controller).
* 关于控制器和路由文件名:默认控制器名称来自 `./src/api/[api-name]/controllers/` 中的文件名。使用 `createCoreRouter` 创建的核心路由将采用相同的名称,因此生成的处理程序字符串会自动匹配。自定义路由可以遵循任何文件命名方案,只要 `handler` 字符串引用已导出的控制器操作即可。
¥Regarding controller and route filenames: the default controller name comes from the filename inside `./src/api/[api-name]/controllers/`. Core routers created with `createCoreRouter` adopt the same name, so the generated handler string matches automatically. Custom routers can follow any file naming scheme, as long as the `handler` string references an exported controller action.
以下示例添加了一个新的控制器操作,并通过自定义路由将其公开,而不会重复现有的 CRUD 路由定义:
¥The example below adds a new controller action and exposes it through a custom route without duplicating the existing CRUD route definitions:
```js title="./src/api/restaurant/controllers/restaurant.js"
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::restaurant.restaurant', ({ strapi }) => ({
async exampleAction(ctx) {
const specials = await strapi.service('api::restaurant.restaurant').find({ filters: { isSpecial: true } });
return this.transformResponse(specials.results);
},
}));
```
```js title="./src/api/restaurant/routes/01-custom-restaurant.js"
module.exports = {
routes: [
{
method: 'GET',
path: '/restaurants/specials',
handler: 'api::restaurant.restaurant.exampleAction',
},
],
};
```
### 控制器中的清理和验证 {#sanitization-and-validation-in-controllers}
¥Sanitization and Validation in controllers
:::warning 警告
强烈建议你使用新的 `sanitizeQuery` 和 `validateQuery` 函数清理(v4.8.0+)和/或验证(v4.13.0+)传入请求查询,以防止泄露私有数据。
¥It's strongly recommended you sanitize (v4.8.0+) and/or validate (v4.13.0+) your incoming request query utilizing the new `sanitizeQuery` and `validateQuery` functions to prevent the leaking of private data.
:::
清理意味着对象被“清理”并返回。
¥Sanitization means that the object is “cleaned” and returned.
验证意味着断言数据已经干净,如果发现不应该存在的内容,则会引发错误。
¥Validation means an assertion is made that the data is already clean and throws an error if something is found that shouldn't be there.
在 Strapi 5 中,查询参数和输入数据(即创建和更新主体数据)都经过验证。任何具有以下无效输入的创建和更新数据请求都将引发 `400 Bad Request` 错误:
¥In Strapi 5, both query parameters and input data (i.e., create and update body data) are validated. Any create and update data requests with the following invalid input will throw a `400 Bad Request` error:
* 用户无权创建的关系
¥relations the user do not have permission to create
* 模式中不存在的无法识别的值
¥unrecognized values that are not present on a schema
* 不可写字段和内部时间戳(如 `createdAt` 和 `createdBy` 字段)标识
¥non-writable fields and internal timestamps like `createdAt` and `createdBy` fields
* 设置或更新 `id` 字段(连接关系除外)
¥setting or updating an `id` field (except for connecting relations)
#### 使用控制器工厂时的消毒 {#sanitization-when-utilizing-controller-factories}
¥Sanitization when utilizing controller factories
在 Strapi 工厂中,公开了以下可用于清理和验证的函数:
¥Within the Strapi factories the following functions are exposed that can be used for sanitization and validation:
| 函数名称 | 参数 | 描述 |
| ---------------- | ------------------------- | ------------------------------ |
| `sanitizeQuery` | `ctx` | 清理请求查询 |
| `sanitizeOutput` | `entity`/`entities`、`ctx` | 清理输出数据,其中实体应该是对象或数据数组 |
| `sanitizeInput` | `data`、`ctx` | 清理输入数据 |
| `validateQuery` | `ctx` | 验证请求查询(无效参数引发错误) |
| `validateInput` | `data`、`ctx` | (EXPERIMENTAL)验证输入数据(无效数据引发错误) |
这些函数自动从模型继承清理设置,并根据内容类型架构和任何内容 API 身份验证策略(例如用户和权限插件或 API 令牌)相应地清理数据。
¥These functions automatically inherit the sanitization settings from the model and sanitize the data accordingly based on the content-type schema and any of the content API authentication strategies, such as the Users & Permissions plugin or API tokens.
:::warning 警告
由于这些方法使用与当前控制器关联的模型,因此如果你查询来自其他模型的数据(例如,在 "restaurant" 控制器方法中查找 "menus"),则必须改用 `strapi.contentAPI` 方法,例如 [清理自定义控制器](#sanitize-validate-custom-controllers) 中描述的 `strapi.contentAPI.sanitize.query`,否则你的查询结果将根据错误的模型进行过滤。
¥Because these methods use the model associated with the current controller, if you query data that is from another model (i.e., doing a find for "menus" within a "restaurant" controller method), you must instead use the `strapi.contentAPI` methods, such as `strapi.contentAPI.sanitize.query` described in [Sanitizing Custom Controllers](#sanitize-validate-custom-controllers), or else the result of your query will be sanitized against the wrong model.
:::
#### 构建自定义控制器时的清理和验证 {#sanitize-validate-custom-controllers}
¥Sanitization and validation when building custom controllers
在自定义控制器中,Strapi 通过 `strapi.contentAPI` 公开以下函数以进行清理和验证:
¥Within custom controllers, Strapi exposes the following functions via `strapi.contentAPI` for sanitization and validation:
| 函数名称 | 参数 | 描述 |
| ----------------------------------- | --------------------------- | --------------------------------------------------------- |
| `strapi.contentAPI.sanitize.input` | `data`、`schema`、`auth` | 清理请求输入,包括不可写字段、删除受限关系以及插件添加的其他嵌套 "visitors" |
| `strapi.contentAPI.sanitize.output` | `data`、`schema`、`auth` | 清理响应输出,包括受限关系、私有字段、密码和插件添加的其他嵌套 "visitors" |
| `strapi.contentAPI.sanitize.query` | `ctx.query`、`schema`、`auth` | 清理请求查询,包括过滤器、排序、字段和填充 |
| `strapi.contentAPI.validate.query` | `ctx.query`、`schema`、`auth` | 验证请求查询,包括过滤器、排序、字段(当前未填充) |
| `strapi.contentAPI.validate.input` | `data`、`schema`、`auth` | (EXPERIMENTAL)验证请求输入,包括不可写字段、删除受限关系以及插件添加的其他嵌套 "visitors" |
:::note 注意
根据自定义控制器的复杂性,你可能需要 Strapi 目前无法考虑的额外清理,尤其是在组合多个来源的数据时。
¥Depending on the complexity of your custom controllers, you may need additional sanitization that Strapi cannot currently account for, especially when combining the data from multiple sources.
:::
### 扩展核心控制器 {#extending-core-controllers}
¥Extending core controllers
为每个内容类型创建默认控制器和操作。这些默认控制器用于返回对 API 请求的响应(例如,当访问 `GET /api/articles/3` 时,将调用 "文章" 内容类型的默认控制器的 `findOne` 操作)。可以自定义默认控制器以实现你自己的逻辑。以下代码示例应该可以帮助你入门。
¥Default controllers and actions are created for each content-type. These default controllers are used to return responses to API requests (e.g. when `GET /api/articles/3` is accessed, the `findOne` action of the default controller for the "Article" content-type is called). Default controllers can be customized to implement your own logic. The following code examples should help you get started.
:::tip 提示
来自核心控制器的操作可以完全由 [创建自定义操作](#adding-a-new-controller) 替换,并将该操作命名为与原始操作相同的名称(例如 `find`、`findOne`、`create`、`update` 或 `delete`)。
¥An action from a core controller can be replaced entirely by [creating a custom action](#adding-a-new-controller) and naming the action the same as the original action (e.g. `find`, `findOne`, `create`, `update`, or `delete`).
:::
:::tip 提示
扩展核心控制器时,你不需要重新实现任何清理,因为它已经由你正在扩展的核心控制器处理。如果可能,强烈建议扩展核心控制器而不是创建自定义控制器。
¥When extending a core controller, you do not need to re-implement any sanitization as it will already be handled by the core controller you are extending. Where possible it's strongly recommended to extend the core controller instead of creating a custom controller.
:::
Collection type examples
:::tip 提示
[后端定制示例秘诀](/cms/backend-customization/examples) 展示了如何覆盖默认控制器操作,例如 [`create` 行动](/cms/backend-customization/examples/services-and-controllers#custom-controller)。
¥The [backend customization examples cookbook](/cms/backend-customization/examples) shows how you can overwrite a default controller action, for instance for the [`create` action](/cms/backend-customization/examples/services-and-controllers#custom-controller).
:::
Single type examples
## 用法 {#usage}
¥Usage
控制器被声明并附加到路由。调用路由时会自动调用控制器,因此通常不需要显式调用控制器。但是,[services](/cms/backend-customization/services) 可以调用控制器,在这种情况下,应使用以下语法:
¥Controllers are declared and attached to a route. Controllers are automatically called when the route is called, so controllers usually do not need to be called explicitly. However, [services](/cms/backend-customization/services) can call controllers, and in this case the following syntax should be used:
```js
// access an API controller
strapi.controller('api::api-name.controller-name');
// access a plugin controller
strapi.controller('plugin::plugin-name.controller-name');
```
:::tip 提示
要列出所有可用的控制器,请运行 `yarn strapi controllers:list`。
¥To list all the available controllers, run `yarn strapi controllers:list`.
:::
# 中间件
Source: https://docs.strapi.io/cms/backend-customization/middlewares
# 中间件定制 {#middlewares-customization}
¥Middlewares customization
全局范围的自定义中间件应添加到 [中间件配置文件](/cms/configurations/middlewares#loading-order) 中,否则 Strapi 将不会加载它们。
¥Globally scoped custom middlewares should be added to the [middlewares configuration file](/cms/configurations/middlewares#loading-order) or Strapi won't load them.
API 级别和插件中间件可以添加到与其相关的特定路由中,如下所示:
¥API level and plugin middlewares can be added into the specific router that they are relevant to like the following:
```js title="./src/api/[api-name]/routes/[collection-name].js or ./src/plugins/[plugin-name]/server/routes/index.js"
module.exports = {
routes: [
{
method: "GET",
path: "/[collection-name]",
handler: "[controller].find",
config: {
middlewares: ["[middleware-name]"],
// See the usage section below for middleware naming conventions
},
},
],
};
```
Example of a custom timer middleware
GraphQL 插件还允许使用不同语法的 [实现自定义中间件](/cms/plugins/graphql#middlewares)。
¥The GraphQL plugin also allows [implementing custom middlewares](/cms/plugins/graphql#middlewares), with a different syntax.
:::tip 发现已加载的中间件
运行 `yarn strapi middlewares:list` 列出所有已注册的中间件,并在将其配置到路由时仔细检查命名。
¥Run `yarn strapi middlewares:list` to list all registered middlewares and double‑check naming when wiring them in routers.
:::
## 用法 {#usage}
¥Usage
中间件根据其范围有不同的调用方式:
¥Middlewares are called different ways depending on their scope:
* 将 `global::middleware-name` 用于应用级中间件
¥use `global::middleware-name` for application-level middlewares
* 使用 `api::api-name.middleware-name` 作为 API 级中间件
¥use `api::api-name.middleware-name` for API-level middlewares
* 使用 `plugin::plugin-name.middleware-name` 作为插件中间件
¥use `plugin::plugin-name.middleware-name` for plugin middlewares
:::tip 提示
要列出所有已注册的中间件,请运行 `yarn strapi middlewares:list`。
¥To list all the registered middlewares, run `yarn strapi middlewares:list`.
:::
### 使用 "是所有者政策" 限制内容访问 {#restricting-content-access-with-an-is-owner-policy}
¥Restricting content access with an "is-owner policy"
通常要求条目的作者是唯一允许编辑或删除该条目的用户。在以前版本的 Strapi 中,这被称为 "是所有者政策"。对于 Strapi v4,实现此行为的推荐方法是使用中间件。
¥It is often required that the author of an entry is the only user allowed to edit or delete the entry. In previous versions of Strapi, this was known as an "is-owner policy". With Strapi v4, the recommended way to achieve this behavior is to use a middleware.
正确的实现很大程度上取决于你的项目的需求和自定义代码,但最基本的实现可以通过以下过程来实现:
¥Proper implementation largely depends on your project's needs and custom code, but the most basic implementation could be achieved with the following procedure:
1. 在项目文件夹中,通过在终端中运行 `yarn strapi generate`(或 `npm run strapi generate`)命令,使用 Strapi CLI 生成器创建中间件。
¥From your project's folder, create a middleware with the Strapi CLI generator, by running the `yarn strapi generate` (or `npm run strapi generate`) command in the terminal.
2. 使用键盘箭头从列表中选择 `middleware`,然后按 Enter。
¥Select `middleware` from the list, using keyboard arrows, and press Enter.
3. 为中间件命名,例如 `isOwner`。
¥Give the middleware a name, for instance `isOwner`.
4. 从列表中选择 `Add middleware to an existing API`。
¥Choose `Add middleware to an existing API` from the list.
5. 选择你希望中间件应用哪个 API。
¥Select which API you want the middleware to apply.
6. 将 `/src/api/[your-api-name]/middlewares/isOwner.js` 文件中的代码替换为以下内容,将第 22 行中的 `api::restaurant.restaurant` 替换为与你在步骤 5 中选择的 API 对应的标识符(例如,如果你的 API 名称是 `blog-post`,则为 `api::blog-post.blog-post`):
¥Replace the code in the `/src/api/[your-api-name]/middlewares/isOwner.js` file with the following, replacing `api::restaurant.restaurant` in line 22 with the identifier corresponding to the API you choose at step 5 (e.g., `api::blog-post.blog-post` if your API name is `blog-post`):
```js showLineNumbers title="src/api/blog-post/middlewares/isOwner.js"
"use strict";
/**
* `isOwner` middleware
*/
module.exports = (config, { strapi }) => {
// Add your own logic here.
return async (ctx, next) => {
const user = ctx.state.user;
const entryId = ctx.params.id ? ctx.params.id : undefined;
let entry = {};
/**
* Gets all information about a given entry,
* populating every relations to ensure
* the response includes author-related information
*/
if (entryId) {
entry = await strapi.documents('api::restaurant.restaurant').findOne(
entryId,
{ populate: "*" }
);
}
/**
* Compares user id and entry author id
* to decide whether the request can be fulfilled
* by going forward in the Strapi backend server
*/
if (user.id !== entry.author.id) {
return ctx.unauthorized("This action is unauthorized.");
} else {
return next();
}
};
};
```
7. 确保中间件配置为应用于某些路由。在 `src/api/[your-api–name]/routes/[your-content-type-name].js` 文件中的 `config` 对象中,定义你希望中间件应用的操作键(`find`、`findOne`、`create`、`update`、`delete` 等),并为这些路由声明 `isOwner` 中间件。
例如,如果你希望允许任何用户对 `restaurant` API 中的 `restaurant` 内容类型发起 GET 请求(映射到 `find` 和 `findOne` 操作)和 POST 请求(即 `create` 操作),但希望将 PUT 请求(即 `update` 操作)和 DELETE 请求限制为仅允许创建该条目的用户发起,则可以在 `src/api/restaurant/routes/restaurant.js` 文件中使用以下代码:
¥Ensure the middleware is configured to apply on some routes. In the `config` object found in the `src/api/[your-api–name]/routes/[your-content-type-name].js` file, define the action keys (`find`, `findOne`, `create`, `update`, `delete`, etc.) for which you would like the middleware to apply, and declare the `isOwner` middleware for these routes.
For instance, if you wish to allow GET requests (mapping to the `find` and `findOne` actions) and POST requests (i.e., the `create` action) to any user for the `restaurant` content-type in the `restaurant` API, but would like to restrict PUT (i.e., `update` action) and DELETE requests only to the user who created the entry, you could use the following code in the `src/api/restaurant/routes/restaurant.js` file:
```js title="src/api/restaurant/routes/restaurant.js"
/**
* restaurant router
*/
const { createCoreRouter } = require("@strapi/strapi").factories;
module.exports = createCoreRouter("api::restaurant.restaurant", {
config: {
update: {
middlewares: ["api::restaurant.is-owner"],
},
delete: {
middlewares: ["api::restaurant.is-owner"],
},
},
});
```
:::info 信息
你可以在 [路由文档](/cms/backend-customization/routes).h 中找到有关路由中间件的更多信息。
¥You can find more information about route middlewares in the [routes documentation](/cms/backend-customization/routes).
:::
# 模块
Source: https://docs.strapi.io/cms/backend-customization/models
# 模块 {#models}
¥Models
由于 Strapi 是一个无头内容管理系统 (CMS),因此为内容创建内容结构是使用该软件的最重要方面之一。模型定义内容结构的表示。
¥As Strapi is a headless Content Management System (CMS), creating a content structure for the content is one of the most important aspects of using the software. Models define a representation of the content structure.
Strapi 有 2 种不同类型的模型:
¥There are 2 different types of models in Strapi:
* 内容类型,可以是集合类型或单一类型,具体取决于它们管理的条目数量,
¥content-types, which can be collection types or single types, depending on how many entries they manage,
* 以及可在多种内容类型中重复使用的内容结构组件。
¥and components that are content structures re-usable in multiple content-types.
如果你刚刚开始,直接在管理面板中使用 [内容类型生成器](/cms/features/content-type-builder) 生成一些模型会很方便。用户界面接管了大量验证任务,并展示了创建内容结构的所有可用选项。然后可以使用此文档在代码级别查看生成的模型映射。
¥If you are just starting out, it is convenient to generate some models with the [Content-type Builder](/cms/features/content-type-builder) directly in the admin panel. The user interface takes over a lot of validation tasks and showcases all the options available to create the content's content structure. The generated model mappings can then be reviewed at the code level using this documentation.
## 模型创建 {#model-creation}
¥Model creation
内容类型和组件模型的创建和存储方式不同。
¥Content-types and components models are created and stored differently.
### 内容类型 {#content-types}
¥Content-types
可以在 Strapi 中创建内容类型:
¥Content-types in Strapi can be created:
* 与 [管理面板中的内容类型生成器](/cms/features/content-type-builder) 一起,
¥with the [Content-type Builder in the admin panel](/cms/features/content-type-builder),
* 或使用 [Strapi 的交互式 CLI `strapi generate`](/cms/cli#strapi-generate) 命令。
¥or with [Strapi's interactive CLI `strapi generate`](/cms/cli#strapi-generate) command.
内容类型使用以下文件:
¥The content-types use the following files:
* `schema.json` 表示模型的 [schema](#model-schema) 定义。(使用任一方法创建内容类型时自动生成)
¥`schema.json` for the model's [schema](#model-schema) definition. (generated automatically, when creating content-type with either method)
* `lifecycles.js` 为 [生命周期钩子](#lifecycle-hooks)。该文件必须手动创建。
¥`lifecycles.js` for [lifecycle hooks](#lifecycle-hooks). This file must be created manually.
这些模型文件存储在 `./src/api/[api-name]/content-types/[content-type-name]/` 中,在这些文件夹中找到的任何 JavaScript 或 JSON 文件都将作为内容类型的模型加载(请参阅 [项目结构](/cms/project-structure))。
¥These models files are stored in `./src/api/[api-name]/content-types/[content-type-name]/`, and any JavaScript or JSON file found in these folders will be loaded as a content-type's model (see [project structure](/cms/project-structure)).
:::note 注意
在启用 [TypeScript](/cms/typescript.md) 的项目中,可以使用 `ts:generate-types` 命令生成模式类型。
¥In [TypeScript](/cms/typescript.md)-enabled projects, schema typings can be generated using the `ts:generate-types` command.
:::
### 组件 {#components-creation}
¥Components
无法使用 CLI 工具创建组件模型。使用 [内容类型生成器](/cms/features/content-type-builder) 或手动创建它们。
¥Component models can't be created with CLI tools. Use the [Content-type Builder](/cms/features/content-type-builder) or create them manually.
组件模型存储在 `./src/components` 文件夹中。每个组件都必须位于一个子文件夹中,该子文件夹以该组件所属的类别命名(参见 [项目结构](/cms/project-structure))。
¥Components models are stored in the `./src/components` folder. Every component has to be inside a subfolder, named after the category the component belongs to (see [project structure](/cms/project-structure)).
## 模型架构 {#model-schema}
¥Model schema
模型的 `schema.json` 文件包含:
¥The `schema.json` file of a model consists of:
* [settings](#model-settings),例如模型表示的内容类型类型或应存储数据的表名称,
¥[settings](#model-settings), such as the kind of content-type the model represents or the table name in which the data should be stored,
* [information](#model-information),主要用于在管理面板中显示模型并通过 REST 和 GraphQL API 访问它,
¥[information](#model-information), mostly used to display the model in the admin panel and access it through the REST and GraphQL APIs,
* [attributes](#model-attributes),描述模型的内容结构,
¥[attributes](#model-attributes), which describe the content structure of the model,
* [options](#model-options) 用于定义模型上的特定行为。
¥and [options](#model-options) used to defined specific behaviors on the model.
### 模型设置 {#model-settings}
¥Model settings
模型的常规设置可以使用以下参数进行配置:
¥General settings for the model can be configured with the following parameters:
| 范围 | 类型 | 描述 |
| ---------------------------------- | --- | --------------------------------------------------------------------------------- |
| `collectionName` | 字符串 | 应存储数据的数据库表名称 |
| `kind`
可选, 仅适用于内容类型 | 字符串 | 定义内容类型是否为:
集合类型 (`collectionType`)
还是单一类型 (`singleType`)
|
```json
// ./src/api/[api-name]/content-types/restaurant/schema.json
{
"kind": "collectionType",
"collectionName": "Restaurants_v1",
}
```
### 型号信息 {#model-information}
¥Model information
模型架构中的 `info` 键描述了用于在管理面板中显示模型并通过 Content API 访问模型的信息。它包括以下参数:
¥The `info` key in the model's schema describes information used to display the model in the admin panel and access it through the Content API. It includes the following parameters:
| 范围 | 类型 | 描述 |
| -------------- | --- | ------------------------------------------------------------ |
| `displayName` | 字符串 | 在管理面板中使用的默认名称 |
| `singularName` | 字符串 | 内容类型名称的单数形式。 用于生成 API 路由和数据库/表集合。
应该是短横线大小写。 |
| `description` | 字符串 | 型号说明 |
```json title="./src/api/[api-name]/content-types/restaurant/schema.json"
"info": {
"displayName": "Restaurant",
"singularName": "restaurant",
"pluralName": "restaurants",
"description": ""
},
```
### 模型属性 {#model-attributes}
¥Model attributes
模型的内容结构由属性列表组成。每个属性都有一个 `type` 参数,该参数描述其性质并将属性定义为简单的数据片段或 Strapi 使用的更复杂的结构。
¥The content structure of a model consists of a list of attributes. Each attribute has a `type` parameter, which describes its nature and defines the attribute as a simple piece of data or a more complex structure used by Strapi.
有多种类型的属性可用:
¥Many types of attributes are available:
* 标量类型(例如字符串、日期、数字、布尔值等),
¥scalar types (e.g. strings, dates, numbers, booleans, etc.),
* Strapi 特定类型,例如:
¥Strapi-specific types, such as:
* `media` 表示通过 [媒体库](/cms/features/content-type-builder#media) 上传的文件
¥`media` for files uploaded through the [Media library](/cms/features/content-type-builder#media)
* `relation` 描述内容类型之间的 [relation](#relations)
¥`relation` to describe a [relation](#relations) between content-types
* `customField` 描述 [自定义字段](#custom-fields) 及其具体按键
¥`customField` to describe [custom fields](#custom-fields) and their specific keys
* `component` 定义 [component](#components-json)(即可在多种内容类型中使用的内容结构)
¥`component` to define a [component](#components-json) (i.e. a content structure usable in multiple content-types)
* `dynamiczone` 定义 [动态区](#dynamic-zones)(即基于组件列表的灵活空间)
¥`dynamiczone` to define a [dynamic zone](#dynamic-zones) (i.e. a flexible space based on a list of components)
* 以及 `locale` 和 `localizations` 类型,仅由 [国际化 (i18n) 插件](/cms/features/internationalization) 使用
¥and the `locale` and `localizations` types, only used by the [Internationalization (i18n) plugin](/cms/features/internationalization)
属性的 `type` 参数应为以下值之一:
¥The `type` parameter of an attribute should be one of the following values:
| 类型类别 | 可用类型 |
| ------------------------------------------------------------------------------------- | ---- |
| 字符串类型 | |
| 日期类型 | |
| 号码类型 | |
| 其他通用类型 | |
| Strapi 独有的特殊类型 | |
| 国际化 (i18n) 相关类型
💡这对于隐藏敏感数据很有用。 | `false` |
| `configurable` | 布尔值 | 如果是 `false`,则无法通过 Content-type Builder 插件配置该属性。 | `true` |
```json title="./src/api/[api-name]/content-types/restaurant/schema.json"
{
// ...
"attributes": {
"title": {
"type": "string",
"minLength": 3,
"maxLength": 99,
"unique": true
},
"description": {
"default": "My description",
"type": "text",
"required": true
},
"slug": {
"type": "uid",
"targetField": "title"
}
// ...
}
}
```
#### 数据库验证和设置 {#database-validations-and-settings}
¥Database validations and settings
:::caution 🚧 此 API 被认为是实验性的。
这些设置应保留给高级用途,因为它们可能会破坏某些功能。没有计划使这些设置稳定。
¥These settings should be reserved to an advanced usage, as they might break some features. There are no plans to make these settings stable.
:::
数据库验证和设置是在架构迁移期间直接传递到 `tableBuilder` Knex.js 函数的自定义选项。数据库验证允许对自定义列设置进行高级控制。以下选项在每个属性的 `column: {}` 对象中设置:
¥Database validations and settings are custom options passed directly onto the `tableBuilder` Knex.js function during schema migrations. Database validations allow for an advanced degree of control for setting custom column settings. The following options are set in a `column: {}` object per attribute:
| 范围 | 类型 | 描述 | 默认 |
| ------------- | ------ | --------------------------------------------------------- | ------- |
| `name` | string | 更改数据库中列的名称 | * |
| `defaultTo` | string | 设置数据库 `defaultTo`,通常与 `notNullable` 一起使用 | * |
| `notNullable` | 布尔值 | 设置数据库 `notNullable`,确保列不能为空 | `false` |
| `unsigned` | 布尔值 | 仅适用于数字列,消除了负数的能力,但最大长度加倍 | `false` |
| `unique` | 布尔值 | 对已发布的条目强制执行数据库级别的唯一性。启用“草稿和发布”功能后,草稿保存会跳过检查,因此重复项仅在发布时失败。 | `false` |
| `type` | string | 更改数据库类型,如果 `type` 有参数,则应将它们传递到 `args` | * |
| `args` | array | 传递到 Knex.js 函数的参数会更改 `type` 等内容 | `[]` |
:::caution `unique`草稿& 发布和
启用 [起草并发布](/cms/features/draft-and-publish) 后,Strapi 会在条目保存为草稿时故意跳过 `unique` 验证。因此,重复项在发布之前不会被检测到,此时数据库约束会触发错误,即使 UI 之前显示草稿为“已保存文档”。
¥When [Draft & Publish](/cms/features/draft-and-publish) is enabled, Strapi intentionally skips `unique` validations while an entry is saved as a draft. Duplicates therefore remain undetected until publication, at which point the database constraint triggers an error even though the UI previously displayed “Saved document” for the drafts.
为避免意外发布失败:
¥To avoid unexpected publication failures:
* 禁用必须保持全局唯一的内容类型的“草稿和发布”功能,
¥disable Draft & Publish on content-types that must stay globally unique,
* 或添加自定义验证(例如生命周期钩子或中间件),在保存前检查草稿是否重复,
¥or add custom validation (e.g. lifecycle hooks or middleware) that checks for draft duplicates before saving,
* 或依赖自动生成的唯一标识符,例如 `uid` 字段和文档编辑约定。
¥or rely on automatically generated unique identifiers such as a `uid` field and document editorial conventions.
:::
```json title="./src/api/[api-name]/content-types/restaurant/schema.json"
{
// ...
"attributes": {
"title": {
"type": "string",
"minLength": 3,
"maxLength": 99,
"unique": true,
"column": {
"unique": true // enforce database unique also
}
},
"description": {
"default": "My description",
"type": "text",
"required": true,
"column": {
"defaultTo": "My description", // set database level default
"notNullable": true // enforce required at database level, even for drafts
}
},
"rating": {
"type": "decimal",
"default": 0,
"column": {
"defaultTo": 0,
"type": "decimal", // using the native decimal type but allowing for custom precision
"args": [
6,1 // using custom precision and scale
]
}
}
// ...
}
}
```
#### `uid` 型 {#uid-type}
¥`uid` type
`uid` 类型用于根据 2 个可选参数,使用唯一标识符 (UID)(例如文章的别名)自动预填充管理面板中的字段值:
¥The `uid` type is used to automatically prefill the field value in the admin panel with a unique identifier (UID) (e.g. slugs for articles) based on 2 optional parameters:
* `targetField`(字符串):如果使用,定义为目标的字段值将用于自动生成 UID。
¥`targetField` (string): If used, the value of the field defined as a target is used to auto-generate the UID.
* `options`(字符串):如果使用,则 UID 是根据传递给
#### 自定义字段 {#custom-fields}
¥Custom fields
[自定义字段](/cms/features/custom-fields) 通过向内容类型添加新类型的字段来扩展 Strapi 的功能。自定义字段在带有 `type: customField` 的模型的 [attributes](#model-attributes) 中显式定义。
¥[Custom fields](/cms/features/custom-fields) extend Strapi’s capabilities by adding new types of fields to content-types. Custom fields are explicitly defined in the [attributes](#model-attributes) of a model with `type: customField`.
自定义字段的属性还显示以下特性:
¥Custom fields' attributes also show the following specificities:
* `customField` 属性,其值充当唯一标识符,指示应使用哪个已注册的自定义字段。其值如下:
¥a `customField` attribute whose value acts as a unique identifier to indicate which registered custom field should be used. Its value follows:
* 如果插件创建了自定义字段,则为 `plugin::plugin-name.field-name` 格式
¥either the `plugin::plugin-name.field-name` format if a plugin created the custom field
* 或特定于当前 Strapi 应用的自定义字段的 `global::field-name` 格式
¥or the `global::field-name` format for a custom field specific to the current Strapi application
* 以及其他参数,具体取决于注册自定义字段时定义的内容(参见 [自定义字段文档](/cms/features/custom-fields))。
¥and additional parameters depending on what has been defined when registering the custom field (see [custom fields documentation](/cms/features/custom-fields)).
```json title="./src/api/[apiName]/[content-type-name]/content-types/schema.json"
{
// …
"attributes": {
"attributeName": { // attributeName would be replaced by the actual attribute name
"type": "customField",
"customField": "plugin::color-picker.color",
"options": {
"format": "hex"
}
}
}
// …
}
```
#### 组件 {#components-json}
¥Components
组件字段创建内容类型和组件结构之间的关系。组件在具有 `type: 'component'` 的模型的 [attributes](#model-attributes) 中显式定义,并接受以下附加参数:
¥Component fields create a relation between a content-type and a component structure. Components are explicitly defined in the [attributes](#model-attributes) of a model with `type: 'component'` and accept the following additional parameters:
| 范围 | 类型 | 描述 |
| ------------ | --- | ---------------------------------------------- |
| `repeatable` | 布尔值 | 可能是 `true` 或 `false`,具体取决于组件是否可重复 |
| `component` | 字符串 | 定义相应的组件,格式如下: `.` |
```json title="./src/api/[apiName]/restaurant/content-types/schema.json"
{
"attributes": {
"openinghours": {
"type": "component",
"repeatable": true,
"component": "restaurant.openinghours"
}
}
}
```
#### 动态区域 {#dynamic-zones}
¥Dynamic zones
动态区域创建了一个灵活的空间,可以根据 [components](#components-json) 的混合列表在其中编写内容。
¥Dynamic zones create a flexible space in which to compose content, based on a mixed list of [components](#components-json).
动态区域在具有 `type: 'dynamiczone'` 的模型的 [attributes](#model-attributes) 中明确定义。它们还接受 `components` 数组,其中每个组件应按照以下格式命名:`.`。
¥Dynamic zones are explicitly defined in the [attributes](#model-attributes) of a model with `type: 'dynamiczone'`. They also accept a `components` array, where each component should be named following this format: `.`.
```json title="./src/api/[api-name]/content-types/article/schema.json"
{
"attributes": {
"body": {
"type": "dynamiczone",
"components": ["article.slider", "article.content"]
}
}
}
```
### 型号选择 {#model-options}
¥Model options
`options` 键用于定义特定行为并接受以下参数:
¥The `options` key is used to define specific behaviors and accepts the following parameter:
| 范围 | 类型 | 描述 |
| ----------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `privateAttributes` | 字符串数组 | 允许将一组属性视为私有属性,即使它们实际上并未在模型中定义为属性。它可用于从 API 响应时间戳中删除它们。
默认值:`true`(如果内容类型是从交互式 CLI 创建的,则为 `false`)。 |
| `populateCreatorFields` | 布尔值 | 利用插件中的 `createdBy` 和 `updatedBy` 钩子的插件开发者需要重构其代码。`false`。 |
```json title="./src/api/[api-name]/content-types/restaurant/schema.json"
{
"options": {
"privateAttributes": ["id", "createdAt"],
"draftAndPublish": true
}
}
```
### 插件选项 {#plugin-options}
¥Plugin options
`pluginOptions` 是一个可选对象,允许插件存储模型或特定属性的配置。
¥`pluginOptions` is an optional object allowing plugins to store configuration for a model or a specific attribute.
| 密钥 | 值 | 描述 |
| ---------------------- | ----------------- | ------------------ |
| `i18n` | `localized: true` | 启用本地化。 |
| `content-manager` | `visible: false` | 在管理面板中的内容管理器中隐藏。 |
| `content-type-builder` | `visible: false` | 在管理面板中的内容类型构建器中隐藏。 |
```json title="./src/api/[api-name]/content-types/[content-type-name]/schema.json"
{
"attributes": {
"name": {
"pluginOptions": {
"i18n": {
"localized": true
}
},
"type": "string",
"required": true
},
"slug": {
"pluginOptions": {
"i18n": {
"localized": true
}
},
"type": "uid",
"targetField": "name",
"required": true
}
// …additional attributes
}
}
```
## 生命周期钩子 {#lifecycle-hooks}
¥Lifecycle hooks
生命周期钩子是调用 Strapi 查询时触发的函数。当通过管理面板管理内容或使用 `queries`· 开发自定义代码时,它们会自动触发
¥Lifecycle hooks are functions that get triggered when Strapi queries are called. They are triggered automatically when managing content through the administration panel or when developing custom code using `queries`·
生命周期钩子可以通过声明或编程方式自定义。
¥Lifecycle hooks can be customized declaratively or programmatically.
:::caution 提醒
直接使用
使用数据库层 API,还可以注册订阅者并以编程方式监听事件:
¥Using the database layer API, it's also possible to register a subscriber and listen to events programmatically:
```js title="./src/index.js"
module.exports = {
async bootstrap({ strapi }) {
// registering a subscriber
strapi.db.lifecycles.subscribe({
models: [], // optional;
beforeCreate(event) {
const { data, where, select, populate } = event.params;
event.state = 'doStuffAfterWards';
},
afterCreate(event) {
if (event.state === 'doStuffAfterWards') {
}
const { result, params } = event;
// do something to the result
},
});
// generic subscribe for generic handling
strapi.db.lifecycles.subscribe((event) => {
if (event.action === 'beforeCreate') {
// do something
}
});
}
}
```
# 政策
Source: https://docs.strapi.io/cms/backend-customization/policies
# 政策 {#policies}
¥Policies
策略是在每个请求到达 [controller](/cms/backend-customization/controllers) 之前对每个请求执行特定逻辑的函数。它们主要用于保护业务逻辑。
¥Policies are functions that execute specific logic on each request before it reaches the [controller](/cms/backend-customization/controllers). They are mostly used for securing business logic.
Strapi 项目的每个 [route](/cms/backend-customization/routes) 都可以与一系列策略相关联。例如,名为 `is-admin` 的策略可以检查请求是否由管理员用户发送,并限制对关键路由的访问。
¥Each [route](/cms/backend-customization/routes) of a Strapi project can be associated to an array of policies. For example, a policy named `is-admin` could check that the request is sent by an admin user, and restrict access to critical routes.
策略可以是全局的,也可以是有范围的。[全局政策](#global-policies) 可以与项目中的任何路由关联。作用域策略仅适用于特定的 [API](#api-policies) 或 [plugin](#plugin-policies),并且应位于相应的 `./src/api//policies/` 或 `./src/plugins//policies/` 文件夹下。
¥Policies can be global or scoped. [Global policies](#global-policies) can be associated to any route in the project. Scoped policies only apply to a specific [API](#api-policies) or [plugin](#plugin-policies) and should live under the corresponding `./src/api//policies/` or `./src/plugins//policies/` folder.
The diagram represents a simplified version of how a request travels through the Strapi back end, with policies and routes highlighted. The backend customization introduction page includes a complete, interactive diagram.
## 执行 {#implementation}
¥Implementation
可以实现一项新政策:
¥A new policy can be implemented:
* 与 [交互式 CLI 命令 `strapi generate`](/cms/cli#strapi-generate)
¥with the [interactive CLI command `strapi generate`](/cms/cli#strapi-generate)
* 或通过在适当的文件夹中手动创建 JavaScript 文件(参见 [项目结构](/cms/project-structure)):
¥or manually by creating a JavaScript file in the appropriate folder (see [project structure](/cms/project-structure)):
* `./src/policies/` 全局政策
¥`./src/policies/` for global policies
* API 政策的 `./src/api/[api-name]/policies/`
¥`./src/api/[api-name]/policies/` for API policies
* `./src/plugins/[plugin-name]/policies/` 用于插件策略
¥`./src/plugins/[plugin-name]/policies/` for plugin policies
全局政策实现示例:
¥Global policy implementation example:
`policyContext` 是 [controller](/cms/backend-customization/controllers) 上下文的封装器。它添加了一些可用于实现 REST 和 GraphQL 策略的逻辑。
¥`policyContext` is a wrapper around the [controller](/cms/backend-customization/controllers) context. It adds some logic that can be useful to implement a policy for both REST and GraphQL.
可以使用 `config` 对象配置策略:
¥Policies can be configured using a `config` object:
## 用法 {#usage}
¥Usage
要将策略应用于路由,请将它们添加到其配置对象中(请参阅 [路由文档](/cms/backend-customization/routes#policies))。
¥To apply policies to a route, add them to its configuration object (see [routes documentation](/cms/backend-customization/routes#policies)).
策略根据其范围有不同的调用方式:
¥Policies are called different ways depending on their scope:
* 使用 `global::policy-name` 代替 [全局政策](#global-policies)
¥use `global::policy-name` for [global policies](#global-policies)
* 使用 `api::api-name.policy-name` 代替 [API 政策](#api-policies)
¥use `api::api-name.policy-name` for [API policies](#api-policies)
* 使用 `plugin::plugin-name.policy-name` 代替 [插件政策](#plugin-policies)
¥use `plugin::plugin-name.policy-name` for [plugin policies](#plugin-policies)
:::tip 提示
要列出所有可用策略,请运行 `yarn strapi policies:list`。
¥To list all the available policies, run `yarn strapi policies:list`.
:::
### 全局政策 {#global-policies}
¥Global policies
全局策略可以与项目中的任何路由关联。
¥Global policies can be associated to any route in a project.
### 插件政策 {#plugin-policies}
¥Plugin policies
插件可以向应用添加和公开策略。例如,[用户和权限功能](/cms/features/users-permissions) 附带策略来确保用户经过身份验证或有权执行操作:
¥Plugins can add and expose policies to an application. For example, the [Users & Permissions feature](/cms/features/users-permissions) comes with policies to ensure that the user is authenticated or has the rights to perform an action:
### API 政策 {#api-policies}
¥API policies
API 策略与声明它们的 API 中定义的路由相关联。
¥API policies are associated to the routes defined in the API where they have been declared.
要在另一个 API 中使用策略,请使用以下语法引用它:`api::[apiName].[policyName]`:
¥To use a policy in another API, reference it with the following syntax: `api::[apiName].[policyName]`:
# 请求和响应
Source: https://docs.strapi.io/cms/backend-customization/requests-responses
# 请求和响应 {#requests-and-responses}
¥Requests and Responses
Strapi 后端服务器基于 。当你通过 [REST API](/cms/api/rest) 发送请求时,上下文对象 (`ctx`) 会传递到 Strapi 后端的每个元素(例如 [policies](/cms/backend-customization/policies)、[controllers](/cms/backend-customization/controllers)、[services](/cms/backend-customization/services))。
¥The Strapi back end server is based on . When you send requests through the [REST API](/cms/api/rest), a context object (`ctx`) is passed to every element of the Strapi back end (e.g., [policies](/cms/backend-customization/policies), [controllers](/cms/backend-customization/controllers), [services](/cms/backend-customization/services)).
`ctx` 包括 3 个主要对象:
¥`ctx` includes 3 main objects:
* [`ctx.request`](#ctxrequest) 有关客户端发出 API 请求所发送的请求的信息,
¥[`ctx.request`](#ctxrequest) for information about the request sent by the client making an API request,
* [`ctx.state`](#ctxstate) 有关 Strapi 后端内请求状态的信息,
¥[`ctx.state`](#ctxstate) for information about the state of the request within the Strapi back end,
* 和 [`ctx.response`](#ctxresponse) 有关服务器将返回的响应的信息。
¥and [`ctx.response`](#ctxresponse) for information about the response that the server will return.
:::tip 提示
还可以使用 [`strapi.requestContext` function](#accessing-the-request-context-anywhere). 代码从代码中的任何位置访问请求的上下文。
¥The request's context can also be accessed from anywhere in the code with the [`strapi.requestContext` function](#accessing-the-request-context-anywhere).
:::
:::info 信息
除了以下文档中描述的概念和参数外,你还可以在 、 和 中找到其他信息。
¥In addition to the concepts and parameters described in the following documentation, you might find additional information in the , and .
:::
The diagram represents a simplified version of how a request travels through the Strapi back end, with requests and responses highlighted. The backend customization introduction page includes a complete, interactive diagram.
## `ctx.request` {#ctxrequest}
`ctx.request` 对象包含以下参数:
¥The `ctx.request` object contains the following parameters:
| 范围 | 描述 | 类型 |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `ctx.request.body` | 正文的解析版本。 | `Object` |
| `ctx.request.files` | 随请求发送的文件。 | `Array` |
| `ctx.request.headers` | 随请求一起发送的标头。 | `Object` |
| `ctx.request.host` | URL 的主机部分,包括端口。 | `String` |
| `ctx.request.hostname` | URL 的主机部分,不包括端口。 | `String` |
| `ctx.request.href` | 所请求资源的完整 URL,包括协议、域、端口(如果指定)、路径和查询参数。 | `String` |
| `ctx.request.ip` | 发送请求者的 IP。 | `String` |
| `ctx.request.ips` | 当 `X-Forwarded-For` 存在且 `app.proxy` 启用时,将返回 IP 数组,按从上游到下游的顺序排列。
`ctx.response.attachment([filename], [options])` | 将 标头设置为 "attachment",以向客户端发出信号提示下载。可选择指定下载的文件名和一些 。 | `Function` |
| `ctx.response.type` | 标头,没有 "charset" 等参数。 | `String` |
| `ctx.response.lastModified` | 标头作为日期(如果存在)。 | `DateTime` |
| `ctx.response.etag` | 设置响应的 ,包括封装的“s。 没有相应的 `response.etag` getter。 | `String` |
## 在任何地方访问请求上下文 {#accessing-the-request-context-anywhere}
¥Accessing the request context anywhere
Strapi 公开了一种从代码中的任何位置访问当前请求上下文的方法(例如生命周期函数)。
¥Strapi exposes a way to access the current request context from anywhere in the code (e.g. lifecycle functions).
你可以按如下方式访问该请求:
¥You can access the request as follows:
```js
const ctx = strapi.requestContext.get();
```
你应该只在 HTTP 请求上下文中调用的函数内部使用它。
¥You should only use this inside of functions that will be called in the context of an HTTP request.
```js
// correct
const service = {
myFunction() {
const ctx = strapi.requestContext.get();
console.log(ctx.state.user);
},
};
// incorrect
const ctx = strapi.requestContext.get();
const service = {
myFunction() {
console.log(ctx.state.user);
},
};
```
**示例:**
¥**Example:**
```js title="./api/test/content-types/article/lifecycles.js"
module.exports = {
beforeUpdate() {
const ctx = strapi.requestContext.get();
console.log('User info in service: ', ctx.state.user);
},
};
```
:::note 注意
Strapi 使用名为 的 Node.js 功能使上下文在任何地方都可用。
¥Strapi uses a Node.js feature called to make the context available anywhere.
:::
# 路由
Source: https://docs.strapi.io/cms/backend-customization/routes
# 路由 {#routes}
¥Routes
通过任何 URL 发送到 Strapi 的请求均由路由处理。默认情况下,Strapi 为所有内容类型生成路由(参见 [REST API 文档](/cms/api/rest))。路由可以是 [added](#implementation) 并配置:
¥Requests sent to Strapi on any URL are handled by routes. By default, Strapi generates routes for all the content-types (see [REST API documentation](/cms/api/rest)). Routes can be [added](#implementation) and configured:
* 使用 [policies](#policies),这是一种阻止访问路由的方法,
¥with [policies](#policies), which are a way to block access to a route,
* 以及 [middlewares](#middlewares),这是一种控制和更改请求流和请求本身的方法。
¥and with [middlewares](#middlewares), which are a way to control and change the request flow and the request itself.
一旦存在一条路由,到达该路由就会执行一些由控制器处理的代码(参见 [控制器文档](/cms/backend-customization/controllers))。要查看所有现有路线及其层次顺序,你可以运行 `yarn strapi routes:list`(参见 [CLI 参考](/cms/cli))。
¥Once a route exists, reaching it executes some code handled by a controller (see [controllers documentation](/cms/backend-customization/controllers)). To view all existing routes and their hierarchal order, you can run `yarn strapi routes:list` (see [CLI reference](/cms/cli)).
:::tip 提示
如果你仅自定义 Strapi 为内容类型生成的默认控制器操作(`find`、`findOne`、`create`、`update` 或 `delete`),则可以保持路由不变。这些核心路由已经指向相同的处理程序名称,并将运行你的新控制器逻辑。仅当你需要全新的 HTTP 路径/方法或想要公开自定义控制器操作时,才添加或编辑路由。
¥If you only customize the default controller actions (`find`, `findOne`, `create`, `update`, or `delete`) that Strapi generates for a content-type, you can leave the router as-is. Those core routes already target the same handler names and will run your new controller logic. Add or edit a route only when you need a brand-new HTTP path/method or want to expose a custom controller action.
:::
The diagram represents a simplified version of how a request travels through the Strapi back end, with routes highlighted. The backend customization introduction page includes a complete, interactive diagram.
## 执行 {#implementation}
¥Implementation
实现新路由包括在 `./src/api/[apiName]/routes` 文件夹内的路由文件中定义它(请参阅 [项目结构](/cms/project-structure))。
¥Implementing a new route consists in defining it in a router file within the `./src/api/[apiName]/routes` folder (see [project structure](/cms/project-structure)).
根据用例,有 2 种不同的路由文件结构:
¥There are 2 different router file structures, depending on the use case:
* 配置 [核心路由](#configuring-core-routers)
¥configuring [core routers](#configuring-core-routers)
* 或创建 [定制路由](#creating-custom-routers)。
¥or creating [custom routers](#creating-custom-routers).
### 配置核心路由 {#configuring-core-routers}
¥Configuring core routers
核心路由(即 `find`、`findOne`、`create`、`update` 和 `delete`)对应于创建新 [content-type](/cms/backend-customization/models#model-creation) 时由 Strapi 自动创建的 [默认路由](/cms/api/rest#endpoints)。
¥Core routers (i.e. `find`, `findOne`, `create`, `update`, and `delete`) correspond to [default routes](/cms/api/rest#endpoints) automatically created by Strapi when a new [content-type](/cms/backend-customization/models#model-creation) is created.
Strapi 提供了 `createCoreRouter` 工厂功能,可自动生成核心路由并允许:
¥Strapi provides a `createCoreRouter` factory function that automatically generates the core routers and allows:
* 将配置选项传递给每个路由
¥passing in configuration options to each router
* 并禁用一些核心路由到 [创建自定义的](#creating-custom-routers)。
¥and disabling some core routers to [create custom ones](#creating-custom-routers).
核心路由文件是一个 JavaScript 文件,使用以下参数导出对 `createCoreRouter` 的调用结果:
¥A core router file is a JavaScript file exporting the result of a call to `createCoreRouter` with the following parameters:
| 范围 | 描述 | 类型 | |
| -------- | ----------------------------------------------------------------------------------- | -------- | --- |
| `prefix` | 允许传入自定义前缀以添加到该型号的所有路由(例如 `/test`) | `String` | |
| `only` | 只会加载的核心路由
| `Object` |
可以使用参数和正则表达式创建动态路由。这些参数将在 `ctx.params` 对象中公开。有关更多详细信息,请参阅
## 配置 {#configuration}
¥Configuration
[核心路由](#configuring-core-routers) 和 [定制路由](#creating-custom-routers) 具有相同的配置选项。路由配置在 `config` 对象中定义,可用于处理 [policies](#policies) 和 [middlewares](#middlewares) 或 [公开路由](#public-routes)。
¥Both [core routers](#configuring-core-routers) and [custom routers](#creating-custom-routers) have the same configuration options. The routes configuration is defined in a `config` object that can be used to handle [policies](#policies) and [middlewares](#middlewares) or to [make the route public](#public-routes).
### 政策 {#policies}
¥Policies
[政策](/cms/backend-customization/policies) 可以添加到路由配置中:
¥[Policies](/cms/backend-customization/policies) can be added to a route configuration:
* 通过指向 `./src/policies` 中注册的策略,无论是否传递自定义配置
¥by pointing to a policy registered in `./src/policies`, with or without passing a custom configuration
* 或直接声明策略实现,将其作为以 `policyContext` 扩展
### 中间件 {#middlewares}
¥Middlewares
[中间件](/cms/backend-customization/middlewares) 可以添加到路由配置中:
¥[Middlewares](/cms/backend-customization/middlewares) can be added to a route configuration:
* 通过指向 `./src/middlewares` 中注册的中间件,无论是否传递自定义配置
¥by pointing to a middleware registered in `./src/middlewares`, with or without passing a custom configuration
* 或直接声明中间件实现,将其作为以
### 公共路由 {#public-routes}
¥Public routes
默认情况下,路由受到 Strapi 身份验证系统的保护,该系统基于 [API 令牌](/cms/features/api-tokens) 或使用 [用户和权限插件](/cms/features/users-permissions)。
¥By default, routes are protected by Strapi's authentication system, which is based on [API tokens](/cms/features/api-tokens) or on the use of the [Users & Permissions plugin](/cms/features/users-permissions).
在某些情况下,公开可用的路由并控制正常 Strapi 身份验证系统之外的访问可能会很有用。这可以通过将路由的 `auth` 配置参数设置为 `false` 来实现:
¥In some scenarios, it can be useful to have a route publicly available and control the access outside of the normal Strapi authentication system. This can be achieved by setting the `auth` configuration parameter of a route to `false`:
# 服务
Source: https://docs.strapi.io/cms/backend-customization/services
# 服务 {#services}
¥Services
服务是一组可重用的功能。它们对于尊重 "不要重复自己" (DRY) 编程概念和简化 [controllers](/cms/backend-customization/controllers.md) 逻辑特别有用。
¥Services are a set of reusable functions. They are particularly useful to respect the "don’t repeat yourself" (DRY) programming concept and to simplify [controllers](/cms/backend-customization/controllers.md) logic.
The diagram represents a simplified version of how a request travels through the Strapi back end, with services highlighted. The backend customization introduction page includes a complete, interactive diagram.
## 执行 {#implementation}
¥Implementation
服务可以 [手动生成或添加](#adding-a-new-service)。Strapi 提供了 `createCoreService` 工厂功能,可自动生成核心服务并允许构建自定义服务或 [扩展或替换生成的服务](#extending-core-services)。
¥Services can be [generated or added manually](#adding-a-new-service). Strapi provides a `createCoreService` factory function that automatically generates core services and allows building custom ones or [extend or replace the generated services](#extending-core-services).
### 添加新服务 {#adding-a-new-service}
¥Adding a new service
可以实现一个新的服务:
¥A new service can be implemented:
* 与 [交互式 CLI 命令 `strapi generate`](/cms/cli#strapi-generate)
¥with the [interactive CLI command `strapi generate`](/cms/cli#strapi-generate)
* 或通过在适当的文件夹中手动创建 JavaScript 文件(参见 [项目结构](/cms/project-structure.md)):
¥or manually by creating a JavaScript file in the appropriate folder (see [project structure](/cms/project-structure.md)):
* `./src/api/[api-name]/services/` 用于 API 服务
¥`./src/api/[api-name]/services/` for API services
* 或 `./src/plugins/[plugin-name]/services/` 对应 [插件服务](/cms/plugins-development/server-api#services)。
¥or `./src/plugins/[plugin-name]/services/` for [plugin services](/cms/plugins-development/server-api#services).
要手动创建服务,请导出返回服务实现的工厂函数(即具有方法的对象)。该工厂函数接收 `strapi` 实例:
¥To manually create a service, export a factory function that returns the service implementation (i.e. an object with methods). This factory function receives the `strapi` instance:
:::strapi 文档服务 API
要开始创建你自己的服务,请参阅 [文档服务 API](/cms/api/document-service) 文档中的 Strapi 内置函数。
¥To get started creating your own services, see Strapi's built-in functions in the [Document Service API](/cms/api/document-service) documentation.
:::
Example of a custom email service (using Nodemailer)
服务的目标是存储可重用的功能。`sendNewsletter` 服务可用于从我们的代码库中具有特定目的的不同功能发送电子邮件:
¥The goal of a service is to store reusable functions. A `sendNewsletter` service could be useful to send emails from different functions in our codebase that have a specific purpose:
现在可以通过 `strapi.service('api::restaurant.restaurant').sendNewsletter(...args)` 全局变量使用该服务。它可以在代码库的另一部分中使用,例如在以下控制器中:
¥The service is now available through the `strapi.service('api::restaurant.restaurant').sendNewsletter(...args)` global variable. It can be used in another part of the codebase, like in the following controller:
:::note 注意
当创建新的 [content-type](/cms/backend-customization/models.md#content-types) 时,Strapi 会使用占位符代码构建通用服务,准备进行自定义。
¥When a new [content-type](/cms/backend-customization/models.md#content-types) is created, Strapi builds a generic service with placeholder code, ready to be customized.
:::
### 拓展核心服务 {#extending-core-services}
¥Extending core services
核心服务是为每种内容类型创建的,[controllers](/cms/backend-customization/controllers.md) 可以使用核心服务通过 Strapi 项目执行可重用逻辑。可以定制核心服务来实现你自己的逻辑。以下代码示例应该可以帮助你入门。
¥Core services are created for each content-type and could be used by [controllers](/cms/backend-customization/controllers.md) to execute reusable logic through a Strapi project. Core services can be customized to implement your own logic. The following code examples should help you get started.
:::tip 提示
核心服务可以完全替换为 [创建定制服务](#adding-a-new-service),并将其命名为与核心服务相同的名称(例如 `find`、`findOne`、`create`、`update` 或 `delete`)。
¥A core service can be replaced entirely by [creating a custom service](#adding-a-new-service) and naming it the same as the core service (e.g. `find`, `findOne`, `create`, `update`, or `delete`).
:::
Collection type examplesSingle type examples
## 用法 {#usage}
¥Usage
创建服务后,可以从 [controllers](/cms/backend-customization/controllers.md) 或其他服务访问它:
¥Once a service is created, it's accessible from [controllers](/cms/backend-customization/controllers.md) or from other services:
```js
// access an API service
strapi.service('api::apiName.serviceName').FunctionName();
// access a plugin service
strapi.service('plugin::pluginName.serviceName').FunctionName();
```
在上面的语法示例中,`serviceName` 是 API 服务的服务文件的名称,或者用于将服务文件导出到 `services/index.js` 的插件服务的名称。
¥In the syntax examples above, `serviceName` is the name of the service file for API services or the name used to export the service file to `services/index.js` for plugin services.
:::tip 提示
要列出所有可用服务,请运行 `yarn strapi services:list`。
¥To list all the available services, run `yarn strapi services:list`.
:::
### 核心服务方法 {#core-service-methods}
¥Core service methods
使用 `createCoreService` 生成的服务继承了封装 [文档服务 API](/cms/api/document-service) 的方法。可用的方法取决于内容类型:
¥Services generated with `createCoreService` inherit methods that wrap the [Document Service API](/cms/api/document-service). The available methods depend on the content-type:
#### 集合类型 {#collection-types}
¥Collection types
| 方法 | 描述 |
| ---------------------------------- | --------------------------------------------------------------------------- |
| `find(params)` | [`findMany`](/cms/api/document-service#findmany) 的封装器;返回分页的文档列表。 |
| `findOne(documentId, params)` | [`findOne`](/cms/api/document-service#findone) 的封装器;根据 `documentId` 返回单个文档。 |
| `create(params)` | [`create`](/cms/api/document-service#create) 的封装器;创建新文档。 |
| `update(documentId, params)` | [`update`](/cms/api/document-service#update) 的封装器;更新现有文档。 |
| `delete(documentId, params)` | [`delete`](/cms/api/document-service#delete) 的封装器;删除文档。 |
| `count(params)` | [`count`](/cms/api/document-service#count) 的封装器;返回匹配文档的数量。 |
| `publish(documentId, params)` | [`publish`](/cms/api/document-service#publish) 的封装器;发布草稿文档。 |
| `unpublish(documentId, params)` | [`unpublish`](/cms/api/document-service#unpublish) 的封装器;取消发布文档。 |
| `discardDraft(documentId, params)` | [`discardDraft`](/cms/api/document-service#discarddraft) 的封装器;删除草稿副本。 |
#### 单一类型 {#single-types}
¥Single types
| 方法 | 描述 |
| ------------------------------------- | ---------------------------------------------------------------------- |
| `find(params)` | 返回单个文档(内部使用 [`findFirst`](/cms/api/document-service#findfirst))。 |
| `createOrUpdate({ data, ...params })` | 如果文档不存在,则创建文档;否则更新文档(使用 [`update`](/cms/api/document-service#update))。 |
| `delete(params)` | 删除文档(使用 [`delete`](/cms/api/document-service#delete))。 |
| `count(params)` | 计算符合过滤器的文档数量(使用 [`count`](/cms/api/document-service#count))。 |
| `publish(params)` | 发布草稿文档(使用 [`publish`](/cms/api/document-service#publish))。 |
| `unpublish(params)` | 取消发布文档(使用 [`unpublish`](/cms/api/document-service#unpublish))。 |
| `discardDraft(params)` | 删除草稿副本(使用 [`discardDraft`](/cms/api/document-service#discarddraft))。 |
#### 参数和默认行为 {#parameters-and-default-behavior}
¥Parameters and default behavior
核心服务方法接受与其底层 [文档服务 API](/cms/api/document-service) 调用相同的参数,例如 `fields`, `filters`、`sort`、`pagination`、`populate`、`locale` 和 `status`。当未提供 `status` 时,Strapi 会自动设置 `status: 'published'`,因此只返回已发布的内容。要查询草稿文档,请显式传递 `status: 'draft'` 或文档服务支持的其他值。
¥Core service methods accept the same parameters as their underlying [Document Service API](/cms/api/document-service) calls, such as `fields`, `filters`, `sort`, `pagination`, `populate`, `locale`, and `status`. When no `status` is provided, Strapi automatically sets `status: 'published'` so only published content is returned. To query draft documents, explicitly pass `status: 'draft'` or another value supported by the Document Service.
`createCoreService` 工厂还公开了一个 `getFetchParams(params)` 助手,用于将控制器的查询对象转换为这些方法所需的参数格式。在重写核心方法以将已清理的参数转发到 `strapi.documents()` 时,可以重复使用此辅助程序。
¥The `createCoreService` factory also exposes a `getFetchParams(params)` helper that converts a controller's query object into the parameter format expected by these methods. This helper can be reused when overriding core methods to forward sanitized parameters to `strapi.documents()`.
# 网络钩子
Source: https://docs.strapi.io/cms/backend-customization/webhooks
# 网络钩子 {#webhooks}
¥Webhooks
Webhook 是应用用来通知其他应用事件发生的构造。更准确地说,webhook 是用户定义的 HTTP 回调。使用 webhook 是告诉第三方提供商开始某些处理(CI、构建、部署...)的好方法。
¥Webhook is a construct used by an application to notify other applications that an event occurred. More precisely, webhook is a user-defined HTTP callback. Using a webhook is a good way to tell third-party providers to start some processing (CI, build, deployment ...).
Webhook 的工作方式是通过 HTTP 请求(通常是 POST 请求)向接收应用传递信息。
¥The way a webhook works is by delivering information to a receiving application through HTTP requests (typically POST requests).
## 用户内容类型 webhook {#user-content-type-webhooks}
¥User content-type webhooks
为了防止无意中将任何用户信息发送到其他应用,Webhooks 不适用于用户内容类型。如果需要通知其他应用有关 Users 集合中的更改,可以通过使用 `./src/index.js` 示例创建 [生命周期钩子](/cms/backend-customization/models#lifecycle-hooks) 来实现。
¥To prevent from unintentionally sending any user's information to other applications, Webhooks will not work for the User content-type.
If you need to notify other applications about changes in the Users collection, you can do so by creating [Lifecycle hooks](/cms/backend-customization/models#lifecycle-hooks) using the `./src/index.js` example.
## 可用配置 {#available-configurations}
¥Available configurations
你可以在文件 `./config/server`.conf 中设置 webhook 配置。
¥You can set webhook configurations inside the file `./config/server`.
* `webhooks`
* `defaultHeaders`:你可以设置用于 Webhook 请求的默认标头。此选项将被 webhook 本身中设置的标头覆盖。
¥`defaultHeaders`: You can set default headers to use for your webhook requests. This option is overwritten by the headers set in the webhook itself.
**配置示例**
¥**Example configuration**
## Webhooks 安全性 {#webhooks-security}
¥Webhooks security
大多数时候,Webhook 会向公共 URL 发出请求,因此有人可能会找到该 URL 并向其发送错误信息。
¥Most of the time, webhooks make requests to public URLs, therefore it is possible that someone may find that URL and send it wrong information.
为了防止这种情况发生,你可以发送带有身份验证令牌的标头。使用管理面板,你必须为每个 Webhook 执行此操作。
¥To prevent this from happening you can send a header with an authentication token. Using the Admin panel you would have to do it for every webhook.
另一种方法是定义 `defaultHeaders` 以添加到每个 webhook 请求中。
¥Another way is to define `defaultHeaders` to add to every webhook request.
你可以通过更新 `./config/server` 处的文件来配置这些全局标头:
¥You can configure these global headers by updating the file at `./config/server`:
如果你自己开发 Webhook 处理程序,你现在可以通过读取标头来验证令牌。
¥If you are developing the webhook handler yourself you can now verify the token by reading the headers.
### 验证签名 {#verifying-signatures}
¥Verifying signatures
除了身份验证标头之外,建议对 webhook 有效负载进行签名并在服务器端验证签名,以防止篡改和重放攻击。为此,你可以遵循以下指南:
¥In addition to auth headers, it's recommended to sign webhook payloads and verify signatures server‑side to prevent tampering and replay attacks. To do so, you can use the following guidelines:
* 生成共享密钥并将其存储在环境变量中。
¥Generate a shared secret and store it in environment variables
* 让发送方对原始请求正文加上时间戳计算 HMAC(例如,SHA-256)。
¥Have the sender compute an HMAC (e.g., SHA‑256) over the raw request body plus a timestamp
* 在标头中发送签名(和时间戳)(例如,`X‑Webhook‑Signature`、`X‑Webhook‑Timestamp`)
¥Send the signature (and timestamp) in headers (e.g., `X‑Webhook‑Signature`, `X‑Webhook‑Timestamp`)
* 收到请求后,重新计算 HMAC 并使用恒定时间检查进行比较。
¥On receipt, recompute the HMAC and compare using a constant‑time check
* 如果签名无效或时间戳过旧,无法避免重放攻击,则拒绝请求。
¥Reject if the signature is invalid or the timestamp is too old to mitigate replay
Example: Verify HMAC signatures (Node.js)
以下是一个最小化的 Node.js 中间件示例(伪代码),展示了 `
以下是一些额外的外部示例:
¥Here a few additional external examples:
*
*
## 可用的事件 {#available-events}
¥Available events
默认情况下,Strapi webhook 可以由以下事件触发:
¥By default Strapi webhooks can be triggered by the following events:
| 名称 | 描述 |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| [`entry.create`](#entrycreate) | 创建内容类型条目时触发。 |
| [`entry.update`](#entryupdate) | 更新内容类型条目时触发。 |
| [`entry.delete`](#entrydelete) | 删除内容类型条目时触发。 |
| [`entry.publish`](#entrypublish) | 发布内容类型条目时触发。\* |
| [`entry.unpublish`](#entryunpublish) | 当内容类型条目取消发布时触发。\* |
| [`media.create`](#mediacreate) | 创建媒体时触发。 |
| [`media.update`](#mediaupdate) | 当媒体更新时触发。 |
| [`media.delete`](#mediadelete) | 删除媒体时触发。 |
| [`review-workflows.updateEntryStage`](#review-workflowsupdateentrystage) | 当内容在审阅阶段之间移动时触发(请参阅 [审查工作流程](/cms/features/review-workflows#configuration))。 此事件仅适用于 版本的 Strapi。 |
| [`releases.publish`](#releases-publish) | 发布版本时触发(参见 [发布](/cms/features/releases))。 此事件仅适用于 Strapi CMS 的 或 计划。 |
*仅当在此内容类型上启用 `draftAndPublish` 时。
¥*only when `draftAndPublish` is enabled on this Content Type.
## 有效载荷 {#payloads}
¥Payloads
:::tip 注意
打印当前安装的 Strapi 版本。
¥Private fields and s are not sent in the payload.
:::
### 标头 {#headers}
¥Headers
当有效负载传递到你的 webhook 的 URL 时,它将包含特定标头:
¥When a payload is delivered to your webhook's URL, it will contain specific headers:
| 标头 | 描述 |
| ---------------- | ----------- |
| `X-Strapi-Event` | 触发的事件类型的名称。 |
### `entry.create` {#entrycreate}
创建新条目时会触发此事件。
¥This event is triggered when a new entry is created.
**有效负载示例**
¥**Example payload**
```json
{
"event": "entry.create",
"createdAt": "2020-01-10T08:47:36.649Z",
"model": "address",
"entry": {
"id": 1,
"geolocation": {},
"city": "Paris",
"postal_code": null,
"category": null,
"full_name": "Paris",
"createdAt": "2020-01-10T08:47:36.264Z",
"updatedAt": "2020-01-10T08:47:36.264Z",
"cover": null,
"images": []
}
}
```
### `entry.update` {#entryupdate}
当条目更新时会触发此事件。
¥This event is triggered when an entry is updated.
**有效负载示例**
¥**Example payload**
```json
{
"event": "entry.update",
"createdAt": "2020-01-10T08:58:26.563Z",
"model": "address",
"entry": {
"id": 1,
"geolocation": {},
"city": "Paris",
"postal_code": null,
"category": null,
"full_name": "Paris",
"createdAt": "2020-01-10T08:47:36.264Z",
"updatedAt": "2020-01-10T08:58:26.210Z",
"cover": null,
"images": []
}
}
```
### `entry.delete` {#entrydelete}
当删除条目时会触发此事件。
¥This event is triggered when an entry is deleted.
**有效负载示例**
¥**Example payload**
```json
{
"event": "entry.delete",
"createdAt": "2020-01-10T08:59:35.796Z",
"model": "address",
"entry": {
"id": 1,
"geolocation": {},
"city": "Paris",
"postal_code": null,
"category": null,
"full_name": "Paris",
"createdAt": "2020-01-10T08:47:36.264Z",
"updatedAt": "2020-01-10T08:58:26.210Z",
"cover": null,
"images": []
}
}
```
### `entry.publish` {#entrypublish}
发布条目时会触发此事件。
¥This event is triggered when an entry is published.
**有效负载示例**
¥**Example payload**
```json
{
"event": "entry.publish",
"createdAt": "2020-01-10T08:59:35.796Z",
"model": "address",
"entry": {
"id": 1,
"geolocation": {},
"city": "Paris",
"postal_code": null,
"category": null,
"full_name": "Paris",
"createdAt": "2020-01-10T08:47:36.264Z",
"updatedAt": "2020-01-10T08:58:26.210Z",
"publishedAt": "2020-08-29T14:20:12.134Z",
"cover": null,
"images": []
}
}
```
### `entry.unpublish` {#entryunpublish}
当条目未发布时会触发此事件。
¥This event is triggered when an entry is unpublished.
**有效负载示例**
¥**Example payload**
```json
{
"event": "entry.unpublish",
"createdAt": "2020-01-10T08:59:35.796Z",
"model": "address",
"entry": {
"id": 1,
"geolocation": {},
"city": "Paris",
"postal_code": null,
"category": null,
"full_name": "Paris",
"createdAt": "2020-01-10T08:47:36.264Z",
"updatedAt": "2020-01-10T08:58:26.210Z",
"publishedAt": null,
"cover": null,
"images": []
}
}
```
### `media.create` {#mediacreate}
当你在条目创建时或通过媒体界面上传文件时,会触发此事件。
¥This event is triggered when you upload a file on entry creation or through the media interface.
**有效负载示例**
¥**Example payload**
```json
{
"event": "media.create",
"createdAt": "2020-01-10T10:58:41.115Z",
"media": {
"id": 1,
"name": "image.png",
"hash": "353fc98a19e44da9acf61d71b11895f9",
"sha256": "huGUaFJhmcZRHLcxeQNKblh53vtSUXYaB16WSOe0Bdc",
"ext": ".png",
"mime": "image/png",
"size": 228.19,
"url": "/uploads/353fc98a19e44da9acf61d71b11895f9.png",
"provider": "local",
"provider_metadata": null,
"createdAt": "2020-01-10T10:58:41.095Z",
"updatedAt": "2020-01-10T10:58:41.095Z",
"related": []
}
}
```
### `media.update` {#mediaupdate}
当你通过媒体接口更换媒体或更新媒体元数据时,会触发该事件。
¥This event is triggered when you replace a media or update the metadata of a media through the media interface.
**有效负载示例**
¥**Example payload**
```json
{
"event": "media.update",
"createdAt": "2020-01-10T10:58:41.115Z",
"media": {
"id": 1,
"name": "image.png",
"hash": "353fc98a19e44da9acf61d71b11895f9",
"sha256": "huGUaFJhmcZRHLcxeQNKblh53vtSUXYaB16WSOe0Bdc",
"ext": ".png",
"mime": "image/png",
"size": 228.19,
"url": "/uploads/353fc98a19e44da9acf61d71b11895f9.png",
"provider": "local",
"provider_metadata": null,
"createdAt": "2020-01-10T10:58:41.095Z",
"updatedAt": "2020-01-10T10:58:41.095Z",
"related": []
}
}
```
### `media.delete` {#mediadelete}
仅当你通过媒体接口删除媒体时才会触发该事件。
¥This event is triggered only when you delete a media through the media interface.
**有效负载示例**
¥**Example payload**
```json
{
"event": "media.delete",
"createdAt": "2020-01-10T11:02:46.232Z",
"media": {
"id": 11,
"name": "photo.png",
"hash": "43761478513a4c47a5fd4a03178cfccb",
"sha256": "HrpDOKLFoSocilA6B0_icA9XXTSPR9heekt2SsHTZZE",
"ext": ".png",
"mime": "image/png",
"size": 4947.76,
"url": "/uploads/43761478513a4c47a5fd4a03178cfccb.png",
"provider": "local",
"provider_metadata": null,
"createdAt": "2020-01-07T19:34:32.168Z",
"updatedAt": "2020-01-07T19:34:32.168Z",
"related": []
}
}
```
### `review-workflows.updateEntryStage` {#review-workflowsupdateentrystage}
此事件仅适用于 Strapi 的 计划。 当内容移至新的审核阶段(参见 [审查工作流程](/cms/features/review-workflows#configuration))时会触发此事件。
¥This event is only available with the plan of Strapi. The event is triggered when content is moved to a new review stage (see [Review Workflows](/cms/features/review-workflows#configuration)).
**有效负载示例**
¥**Example payload**
```json
{
"event": "review-workflows.updateEntryStage",
"createdAt": "2023-06-26T15:46:35.664Z",
"model": "model",
"uid": "uid",
"entity": {
"id": 2
},
"workflow": {
"id": 1,
"stages": {
"from": {
"id": 1,
"name": "Stage 1"
},
"to": {
"id": 2,
"name": "Stage 2"
}
}
}
}
```
### `releases.publish` {#releases-publish}
当发布 [release](/cms/features/releases) 时会触发该事件。
¥The event is triggered when a [release](/cms/features/releases) is published.
**有效负载示例**
¥**Example payload**
```json
{
"event": "releases.publish",
"createdAt": "2024-02-21T16:45:36.877Z",
"isPublished": true,
"release": {
"id": 2,
"name": "Fall Winter highlights",
"releasedAt": "2024-02-21T16:45:36.873Z",
"scheduledAt": null,
"timezone": null,
"createdAt": "2024-02-21T15:16:22.555Z",
"updatedAt": "2024-02-21T16:45:36.875Z",
"actions": {
"count": 1
}
}
}
```
## webhook 处理的最佳实践 {#best-practices-for-webhook-handling}
¥Best practices for webhook handling
* 通过检查标头和有效负载签名来验证传入请求。
¥Validate incoming requests by checking headers and payload signatures.
* 对失败的 webhook 请求实现重试以处理瞬态错误。
¥Implement retries for failed webhook requests to handle transient errors.
* 记录 webhook 事件以进行调试和监控。
¥Log webhook events for debugging and monitoring.
* 使用安全的 HTTPS 端点接收 webhook。
¥Use secure, HTTPS endpoints for receiving webhooks.
* 设置速率限制以避免被多个 webhook 请求淹没。
¥Set up rate limiting to avoid being overwhelmed by multiple webhook requests.
:::tip 提示
如果你想了解更多关于如何在 Next.js 中使用 webhook 的信息,请查看 [专用博客文章](https://strapi.io/blog/how-to-create-an-ssg-static-site-generation-application-with-strapi-webhooks-and-nextjs)。
¥If you want to learn more about how to use webhooks with Next.js, please have a look at the [dedicated blog article](https://strapi.io/blog/how-to-create-an-ssg-static-site-generation-application-with-strapi-webhooks-and-nextjs).
:::
# 命令行接口
Source: https://docs.strapi.io/cms/cli
# 命令行接口 (CLI) {#command-line-interface-cli}
¥Command Line Interface (CLI)
Strapi 配备了功能齐全的命令行接口 (CLI),可让你在几秒钟内构建和管理你的项目。CLI 可与 `yarn` 和 `npm` 包管理器配合使用。
¥Strapi comes with a full featured Command Line Interface (CLI) which lets you scaffold and manage your project in seconds. The CLI works with both the `yarn` and `npm` package managers.
:::caution 提醒
诸如 `strapi admin:create-user` 之类的交互式命令不会显示带有 `npm` 的提示。请考虑使用 `yarn` 包管理器。
¥Interactive commands such as `strapi admin:create-user` don't display prompts with `npm`. Please consider using the `yarn` package manager.
:::
:::note 注意
建议仅在本地安装 Strapi,这需要在以下所有 `strapi` 命令前添加用于项目设置的包管理器(例如 `npm run strapi help` 或 `yarn strapi help`)或专用节点包执行器(例如 `npx strapi help`)。
¥It is recommended to install Strapi locally only, which requires prefixing all of the following `strapi` commands with the package manager used for the project setup (e.g `npm run strapi help` or `yarn strapi help`) or a dedicated node package executor (e.g. `npx strapi help`).
要使用 `npm` 传递选项,请使用以下语法:`npm run strapi -- --