Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ displayed_sidebar: devDocsSidebar

The [Document Service API](/dev-docs/api/document-service) offers the ability to extend its behavior thanks to middlewares.

Middlewares allow you to perform actions before and/or after a method runs.
Document Service middlewares allow you to perform actions before and/or after a method runs.

<figure style={{width: '100%', margin: '0'}}>
<img src="/img/assets/backend-customization/diagram-controllers-services.png" alt="Simplified Strapi backend diagram with controllers highlighted" />
<em><figcaption style={{fontSize: '12px'}}>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, <a href="/dev-docs/backend-customization#interactive-diagram">interactive diagram</a>.</figcaption></em>
</figure>

## Registering a middleware

Expand Down Expand Up @@ -117,5 +122,5 @@ strapi.documents.use((context, next) => {
<br/>

:::strapi Lifecycle hooks
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](/dev-docs/api/document-service/lifecycle-hooks).
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](/dev-docs/migration/v4-to-v5/breaking-changes/lifecycle-hooks-document-service#table).
:::
2 changes: 0 additions & 2 deletions docusaurus/docs/dev-docs/api/graphql.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ tags:
---

import NotV5 from '/docs/snippets/_not-updated-to-v5.md'
const captionStyle = {fontSize: '12px'}
const imgStyle = {width: '100%', margin: '0' }

# GraphQL API

Expand Down
20 changes: 13 additions & 7 deletions docusaurus/docs/dev-docs/backend-customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ A request can travel through the Strapi back end as follows:
4. [Route policies](/dev-docs/backend-customization/policies) act as a read-only validation step that can block access to a route. [Route middlewares](/dev-docs/backend-customization/routes#middlewares) can control the request flow and mutate the request itself before moving forward.
5. [Controllers](/dev-docs/backend-customization/controllers) execute code once a route has been reached. [Services](/dev-docs/backend-customization/services) are optional, additional code that can be used to build custom logic reusable by controllers.
6. The code executed by the controllers and services interacts with the [models](/dev-docs/backend-customization/models) that are a representation of the content data structure stored in the database.<br />Interacting with the data represented by the models is handled by the [Document Service](/dev-docs/api/document-service) and [Query Engine](/dev-docs/api/query-engine).
7. You can implement [Document Service middlewares](/dev-docs/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.
7. The server returns a [response](/dev-docs/backend-customization/requests-responses). The response can travel back through route middlewares and global middlewares before being sent.

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:
Expand All @@ -55,9 +56,10 @@ Both global and route middlewares include an asynchronous callback function, `aw
Please note that all customizations described in the pages of this section are only for the REST API. [GraphQL customizations](/dev-docs/plugins/graphql#customization) are described in the GraphQL plugin documentation.
:::

:::tip Learn by example
<!-- TODO: uncomment this once we have updated the backend examples cookbook for v5 -->
<!-- :::tip Learn by example
If you prefer learning by reading examples and understanding how they can be used in real-world use cases, the [Examples cookbook](/dev-docs/backend-customization/examples) section is another way at looking how the Strapi back end customization works.
:::
::: -->

## Interactive diagram

Expand All @@ -76,12 +78,15 @@ graph TB
controllerA --"Don't call Service(s)" --> routeMiddlewareB
serviceA --"Call Document Service" --> documentService{{Document Service}}
serviceA --"Don't call Document Service" --> controllerB
documentService --"Call Query Engine"--> queryEngine{{Query Engine}}
documentService --"Don't call Query Engine" --> serviceB
queryEngine --> lifecyclesBefore[/Lifecycle<br> beforeX\]
documentService --"Call Document Service Middleware"--> dsMiddlewareBefore{{Document Service Middleware}}
dsMiddlewareBefore[/"Document Service Middleware"<br> before\]
dsMiddlewareBefore --> queryEngine
dsMiddlewareBefore --"Don't call Query Engine" --> dsMiddlewareAfter
queryEngine{{"Query Engine"}} --> lifecyclesBefore[/Lifecycle<br> beforeX\]
lifecyclesBefore[/Lifecycle<br> beforeX\] --> database[(Database)]
database --> lifecyclesAfter[\Lifecycle<br> afterX/]
lifecyclesAfter --> serviceB{{"Service<br/>after Document Service call"}}
lifecyclesAfter --> dsMiddlewareAfter[\"Document Service Middleware"<br> after/]
dsMiddlewareAfter --> serviceB{{"Service<br/>after Document Service call"}}
serviceB --> controllerB{{"Controller<br/>after service call"}}
controllerB --> routeMiddlewareB(("Route middleware<br/>after await next()"))
routeMiddlewareB --> globalMiddlewareB(("Global middleware<br/>after await next()"))
Expand All @@ -106,5 +111,6 @@ graph TB
click lifecyclesAfter "/dev-docs/backend-customization/models#lifecycle-hooks"
click response "/dev-docs/backend-customization/requests-responses"
click queryEngine "/dev-docs/api/query-engine"
click dsMiddlewareBefore "/dev-docs/api/document-service/middlewares"
click dsMiddlewareAfter "/dev-docs/api/document-service/middlewares"
```

Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ tags:
- strapi-utils
- validateQuery function
---

import FeedbackCallout from '/docs/snippets/backend-customization-feedback-cta.md'
import NotV5 from '/docs/snippets/_not-updated-to-v5.md'
const imgStyle = {width: '100%', margin: '0'}
const captionStyle = {fontSize: '12px'}

# Controllers

Expand All @@ -25,9 +24,9 @@ Controllers are JavaScript files that contain a set of methods, called actions,

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](/dev-docs/backend-customization/services) to organize the code into re-usable parts.

<figure style={imgStyle}>
<figure style={{width: '100%', margin: '0'}}>
<img src="/img/assets/backend-customization/diagram-controllers-services.png" alt="Simplified Strapi backend diagram with controllers highlighted" />
<em><figcaption style={captionStyle}>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, <a href="/dev-docs/backend-customization#interactive-diagram">interactive diagram</a>.</figcaption></em>
<em><figcaption style={{fontSize: '12px'}}>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, <a href="/dev-docs/backend-customization#interactive-diagram">interactive diagram</a>.</figcaption></em>
</figure>

## Implementation
Expand Down
2 changes: 1 addition & 1 deletion docusaurus/docs/dev-docs/backend-customization/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ Lifecycles hooks are not triggered when using directly the [knex](https://knexjs
:::

:::strapi Document Service API: lifecycles and middlewares
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](/dev-docs/api/document-service/lifecycle-hooks). Bulk actions lifecycles (`createMany`, `updateMany`, `deleteMany`) will never be triggered by a Document Service API method. [Document Service middlewares](/dev-docs/api/document-service/middlewares) can be implemented too.
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](/dev-docs/migration/v4-to-v5/breaking-changes/lifecycle-hooks-document-service#table). Bulk actions lifecycles (`createMany`, `updateMany`, `deleteMany`) will never be triggered by a Document Service API method. [Document Service middlewares](/dev-docs/api/document-service/middlewares) can be implemented too.
:::

### Available lifecycle events
Expand Down
4 changes: 1 addition & 3 deletions docusaurus/docs/dev-docs/configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ tags:

import ProjectStructureConfigFiles from '@site/src/components/ProjectStructureConfigFiles'
import NotV5 from '/docs/snippets/_not-updated-to-v5.md'
const imgStyle = {width: '100%', margin: '0'}
const captionStyle = {fontSize: '12px'}

# Configuration

Expand All @@ -24,7 +22,7 @@ The configuration of a Strapi project lives in the `/config` folder:

<ProjectStructureConfigFiles />

<em style={captionStyle}>The block above is an excerpt from the project structure. You can click on any file name in purple to read the corresponding documentation. Visit the <a href="/dev-docs/project-structure">project structure page</a> for the full version.</em>
<em style={{fontSize: '12px'}}>The block above is an excerpt from the project structure. You can click on any file name in purple to read the corresponding documentation. Visit the <a href="/dev-docs/project-structure">project structure page</a> for the full version.</em>

## Base configurations

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Lifecycle hooks are triggered differently with the Document Service API methods
description: In Strapi 5, database lifecycle hooks are triggered differently with the various Document Service API methods, mainly due to the new way the Draft & Publish feature works.
title: Database lifecycle hooks are triggered differently with the Document Service API methods
description: In Strapi 5, database lifecycle hooks are triggered differently with the various Document Service API methods.
sidebar_label: Lifecycle hooks
displayed_sidebar: devDocsMigrationV5Sidebar
tags:
Expand All @@ -15,10 +15,14 @@ import MigrationIntro from '/docs/snippets/breaking-change-page-migration-intro.
import YesPlugins from '/docs/snippets/breaking-change-affecting-plugins.md'
import NoCodemods from '/docs/snippets/breaking-change-not-handled-by-codemod.md'

# Lifecycle hooks are triggered differently with the Document Service API methods
# Database lifecycle hooks are triggered differently with the Document Service API methods

In Strapi 5, database lifecycle hooks are triggered differently with the various [Document Service API](/dev-docs/api/document-service) methods, mainly due to the new way the [Draft & Publish](/user-docs/content-manager/saving-and-publishing-content) feature works.

The majority of use cases should only use the Document Service. The Document Service API handles Draft & Publish, i18n, and any underlying strapi logic.

However, the Document Service API might not suit all your use cases; the database layer is therefore exposed allowing you to do anything on the database without any restriction. Users would then need to resort to the database lifecycle hooks as a system to extend the database behaviour.

<Intro />

<YesPlugins />
Expand Down Expand Up @@ -53,7 +57,27 @@ Lifecycle hooks work the same way as in Strapi v4 but are triggered differently,

### Notes

The [Document Service API: Lifecycle hooks](/dev-docs/api/document-service/lifecycle-hooks) documentation lists how database lifecycle hooks are triggered based on which Document Service API methods are called.
#### Database lifecycle hooks triggered by the Document Service API methods {#table}
Depending on the [Document Service API methods](/dev-docs/api/document-service) called, the following database lifecycle hooks are triggered:

| Document Service API method | Triggered database lifecycle hook(s) |
|-----------------------------------|--------------------------------------|
| `findOne()` | before(after) findOne |
| `findFirst()` | before(after) findOne |
| `findMany()` | before(after) findMany |
| `create()` | before(after) Create |
| `create({ status: 'published' })` | <ul><li>before(after) Create️<br/>Triggered twice as it creates both the draft and published versions</li><li>before(after) Delete<ul><li>Deletes previous draft versions of a document</li><li>Can be triggered multiple times if deleting multiple locales (one per each locale)</li></ul></li></ul> |
| `update()` | <ul><li>before(after) Create<br/>when creating a new locale on a document</li><li>before(after) Update<br/>when updating an existing version of a document</li></ul> |
| `update({ status: 'published' })` | <ul><li>before(after) Create<br/>Can be triggered multiple times if deleting multiple locales (one per each locale)</li><li>before(after) Update<br/>when updating an existing version of a document</li><li>before(after) Delete<ul><li>Deletes previous published versions of a document</li><li>Can be triggered multiple times if deleting multiple locales (one per each locale)</li></ul></li></ul> |
| `delete()` | before(after) Delete<br/>Can be triggered multiple times if deleting multiple locales (one per each locale) |
| `publish()` | <ul><li>before(after) Create<br/>Can be triggered multiple times if deleting multiple locales (one per each locale)</li><li>before(after) Delete<ul><li>Deletes previous published versions of a document</li><li>Can be triggered multiple times if deleting multiple locales (one per each locale)</li></ul></li></ul> |
| `unpublish()` | before(after) Delete<ul><li>Deletes all published versions of a document</li><li>Can be triggered multiple times if deleting multiple locales (one per each locale)</li></ul> |
| `discardDraft()` | <ul><li>before(after) Create<ul><li>Creates new draft versions</li><li>Can be triggered multiple times if deleting multiple locales (one per each locale)</li></ul></li><li>before(after) Delete<ul><li>Deletes previous draft versions of a document</li><li>Can be triggered multiple times if deleting multiple locales (one per each locale)</li></ul></li></ul> |
| `count()` | before(after) Count |

:::note
Bulk actions lifecycles (`createMany`, `updateMany`, `deleteMany`) will never be triggered by a Document Service API method.
:::

### Manual procedure

Expand Down
2 changes: 1 addition & 1 deletion docusaurus/docs/snippets/middleware-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ In Strapi, 3 middleware concepts coexist:

- **Route middlewares** have a more limited scope and are configured and used as middlewares at the route level. They are described in the [routes documentation](/dev-docs/backend-customization/routes#middlewares).

- **Document Service middlewares** apply to the Document Service API and have their own [implementation](/dev-docs/api/document-service/middlewares) and related [lifecycle hooks](/dev-docs/api/document-service/lifecycle-hooks).
- **Document Service middlewares** apply to the Document Service API and have their own [implementation](/dev-docs/api/document-service/middlewares) and related [lifecycle hooks](/dev-docs/migration/v4-to-v5/breaking-changes/lifecycle-hooks-document-service#table).

:::
5 changes: 0 additions & 5 deletions docusaurus/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,6 @@ const sidebars = {
label: 'Middlewares',
id: 'dev-docs/api/document-service/middlewares'
},
{
type: 'doc',
label: 'Lifecycle hooks',
id: 'dev-docs/api/document-service/lifecycle-hooks'
},
]
},
]
Expand Down
1 change: 1 addition & 0 deletions docusaurus/src/scss/__index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@
@import 'table-of-contents.scss';
@import 'typography.scss';
@import 'kapa.scss';
@import 'diagrams.scss';
@import 'custom-search-bar.scss';
6 changes: 6 additions & 0 deletions docusaurus/src/scss/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
}
}

@mixin xlarge-up {
@media (min-width: 1920px) {
@content;
}
}

/** Mixin: Dark mode */
@mixin dark {
html[data-theme='dark'] {
Expand Down
Loading