diff --git a/README.md b/README.md
index f32cb8d650a..c68614cb558 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-

+
# API Platform Documentation
diff --git a/admin/index.md b/admin/index.md
index 0349b705bcf..d31508fd6fb 100644
--- a/admin/index.md
+++ b/admin/index.md
@@ -17,7 +17,7 @@ library to expose a nice, responsive, management interface (Create-Retrieve-Upda
You can **customize everything** by using provided React Admin and [MUI](https://mui.com/) components, or by writing your custom [React](https://reactjs.org/) components.
-
Watch the React Admin screencast
+
Watch the React Admin screencast
## Features
diff --git a/core/content-negotiation.md b/core/content-negotiation.md
index 568ff186afa..c6d4dbcac9f 100644
--- a/core/content-negotiation.md
+++ b/core/content-negotiation.md
@@ -9,7 +9,7 @@ Using the raw JSON or raw XML formats is discouraged, prefer using JSON-LD inste
API Platform also supports [JSON Merge Patch (RFC 7396)](https://tools.ietf.org/html/rfc7396) the JSON:API [`PATCH`](https://jsonapi.org/format/#crud-updating) formats, as well as [Problem Details (RFC 7807)](https://tools.ietf.org/html/rfc7807), [Hydra](https://www.hydra-cg.com/spec/latest/core/#description-of-http-status-codes-and-errors) and [JSON:API](https://jsonapi.org/format/#errors) error formats.
-
Watch the Formats screencast
+
Watch the Formats screencast
API Platform will automatically detect the best resolving format depending on:
diff --git a/core/dto.md b/core/dto.md
index d9040ddfbf1..534a4bf2e5e 100644
--- a/core/dto.md
+++ b/core/dto.md
@@ -1,6 +1,6 @@
# Using Data Transfer Objects (DTOs)
-
Watch the Custom Resources screencast
+
Watch the Custom Resources screencast
As stated in [the general design considerations](design.md), in most cases [the DTO pattern](https://en.wikipedia.org/wiki/Data_transfer_object) should be implemented using an API Resource class representing the public data model exposed through the API and [a custom State Provider](state-providers.md). In such cases, the class marked with `#[ApiResource]` will act as a DTO.
diff --git a/core/extending-jsonld-context.md b/core/extending-jsonld-context.md
index 1c341c08ec8..b909f16d632 100644
--- a/core/extending-jsonld-context.md
+++ b/core/extending-jsonld-context.md
@@ -2,7 +2,7 @@
## JSON-LD
-
Watch the JSON-LD screencast
+
Watch the JSON-LD screencast
API Platform provides the possibility to extend the JSON-LD context of properties. This allows you to describe JSON-LD-typed
values, inverse properties using the `@reverse` keyword, and you can even overwrite the `@id` property this way.
@@ -64,7 +64,7 @@ Note that you do not have to provide the `@id` attribute. If you do not provide
## Hydra
-
Watch the Hydra screencast
+
Watch the Hydra screencast
It's also possible to replace the Hydra context used by the documentation generator:
diff --git a/core/extending.md b/core/extending.md
index 9a1332c1c4d..9588f2412aa 100644
--- a/core/extending.md
+++ b/core/extending.md
@@ -14,10 +14,10 @@ The following tables summarizes which extension point to use depending on what y
| [Laravel Policies](../laravel/security.md#policies) | custom authorization logic |
| [Validation constraints](validation.md) | custom validation logic |
| [State Processors](state-processors) | custom business logic and computations to trigger before or after persistence (ex: mail, call to an external API...) |
-| [Normalizers](serialization.md#decorating-a-serializer-and-adding-extra-data) | customize the resource sent to the client (add fields in JSON documents, encode codes, dates...) |
+| [Normalizers](serialization.md#changing-the-serialization-context-dynamically) | customize the resource sent to the client (add fields in JSON documents, encode codes, dates...) |
| [Filters](filters.md) | create filters for collections and automatically document them (OpenAPI, GraphQL, Hydra) |
| [Serializer Context Builders](serialization.md#changing-the-serialization-context-dynamically) | change the Serialization context (e.g. groups) dynamically |
-| [Messenger Handlers](../symfony/messenger.md) | create 100% custom, RPC, async, service-oriented endpoints (should be used in place of custom controllers because the messenger integration is compatible with both REST and GraphQL, while custom controllers only work with REST) |
+| [Messenger Handlers](../symfony/messenger.md) | create 100% custom, RPC, async, service-oriented endpoints (should be used in place of custom controllers because the messenger integration is compatible with both REST and GraphQL, while custom controllers only work with REST) |
| [DTOs](dto.md) | use a specific class to represent the input or output data structure related to an operation |
| [Kernel Events](events.md) | customize the HTTP request or response (REST only, other extension points must be preferred when possible) |
@@ -36,7 +36,7 @@ For instance, if you want to send a mail after a resource has been persisted, bu
To replace existing API Platform services with your decorators, [check out how to decorate services](https://symfony.com/doc/current/service_container/service_decoration.html).
-
Watch the Service Decoration screencast
+
Watch the Service Decoration screencast
## System Providers and Processors
diff --git a/core/filters.md b/core/filters.md
index 5c74d310236..dfcbcf58b5c 100644
--- a/core/filters.md
+++ b/core/filters.md
@@ -12,7 +12,7 @@ By default, all filters are disabled. They must be enabled explicitly.
When a filter is enabled, it automatically appears in the [OpenAPI](openapi.md) and [GraphQL](graphql.md) documentations.
It is also automatically documented as a `search` property for JSON-LD responses.
-
Watch the Filtering & Searching screencast
+
Watch the Filtering & Searching screencast
For the **specific filters documentation**, please refer to the following pages, depending on your needs:
- [Doctrine filters documentation](../core/doctrine-filters.md)
diff --git a/core/getting-started.md b/core/getting-started.md
index 7ea79cd42d5..b9d75dbac0f 100644
--- a/core/getting-started.md
+++ b/core/getting-started.md
@@ -53,7 +53,7 @@ and what [JSON-LD](https://json-ld.org/) and [Hydra](https://www.hydra-cg.com/)
### Symfony with Doctrine
-
Watch the Create an API Resource screencast
+
Watch the Create an API Resource screencast
API Platform can automatically expose entities mapped as "API resources" through a REST API supporting CRUD
operations.
diff --git a/core/index.md b/core/index.md
index 4930af7f370..113c774612b 100644
--- a/core/index.md
+++ b/core/index.md
@@ -44,6 +44,6 @@ This bundle is extensively tested (unit and functional). The [`Fixtures/` direct
## Symfony Screencasts
-
+
The easiest and funniest way to learn how to use API Platform for Symfony is to watch [the more than 60 screencasts available on SymfonyCasts](https://symfonycasts.com/tracks/rest?cid=apip#api-platform-3)!
diff --git a/core/openapi.md b/core/openapi.md
index 1f4d1833b6f..896a92ed807 100644
--- a/core/openapi.md
+++ b/core/openapi.md
@@ -4,7 +4,7 @@ API Platform natively supports the [OpenAPI](https://www.openapis.org/) API spec

-
Watch the OpenAPI screencast
+
Watch the OpenAPI screencast
The specification of the API is available at the `/docs.jsonopenapi` path.
By default, OpenAPI v3 is used.
diff --git a/core/operations.md b/core/operations.md
index 8e637c2d473..89fc1dc0ff7 100644
--- a/core/operations.md
+++ b/core/operations.md
@@ -3,7 +3,7 @@
API Platform relies on the concept of operations. Operations can be applied to a resource exposed by the API. From
an implementation point of view, an operation is a link between a resource, a route and its related controller.
-
Watch the Operations screencast
+
Watch the Operations screencast
API Platform automatically registers typical [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations
and describes them in the exposed documentation (Hydra and Swagger). It also creates and registers routes
diff --git a/core/pagination.md b/core/pagination.md
index 6c9018ed965..6366fdfb4fc 100644
--- a/core/pagination.md
+++ b/core/pagination.md
@@ -1,6 +1,6 @@
# Pagination
-
Watch the Pagination screencast
+
Watch the Pagination screencast
API Platform has native support for paged collections. Pagination is enabled by default for all collections. Each collection
contains 30 items per page.
diff --git a/core/serialization.md b/core/serialization.md
index 2701a43f936..726d226dd42 100644
--- a/core/serialization.md
+++ b/core/serialization.md
@@ -4,7 +4,7 @@
API Platform embraces and extends the Symfony Serializer Component to transform PHP entities in (hypermedia) API responses.
-
Watch the Serializer screencast
+
Watch the Serializer screencast
The main serialization process has two stages:
@@ -35,7 +35,7 @@ JSON-LD, or JavaScript Object Notation for Linked Data, is a method of encoding
## The Serialization Context, Groups and Relations
-
Watch the Serialization Groups screencast
+
Watch the Serialization Groups screencast
API Platform allows you to specify the `$context` variable used by the Symfony Serializer. This variable is an associative array that has a handy `groups` key allowing you to choose which attributes of the resource are exposed during the normalization (read) and denormalization (write) processes.
It relies on the [serialization (and deserialization) groups](https://symfony.com/doc/current/components/serializer.html#attributes-groups)
@@ -192,7 +192,7 @@ documentation generator.
## Using Serialization Groups per Operation
-
Watch the Relations screencast
+
Watch the Relations screencast
By default, the serializer provided with API Platform represents relations between objects using [dereferenceable IRIs](https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier).
They allow you to retrieve details for related objects by issuing extra HTTP requests. However, for performance reasons,
@@ -239,6 +239,7 @@ App\ApiResource\Book:
normalizationContext:
groups: ['get']
operations:
+ ApiPlatform\Metadata\Get: ~
ApiPlatform\Metadata\Get: ~
ApiPlatform\Metadata\Patch:
normalizationContext:
@@ -318,7 +319,7 @@ Refer to the [operations](operations.md) documentation to learn more.
## Embedding Relations
-
Watch the Relations screencast
+
Watch the Relations screencast
By default, the serializer provided with API Platform represents relations between objects using [dereferenceable IRIs](https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier).
They allow you to retrieve details for related objects by issuing extra HTTP requests. However, for performance reasons, it is sometimes preferable to avoid forcing the client to issue extra HTTP requests.
@@ -805,7 +806,7 @@ App\Entity\Greeting:
## Changing the Serialization Context Dynamically
-
Watch the Context Builder & Service Decoration screencast
+
Watch the Context Builder & Service Decoration screencast
Let's imagine a resource where most fields can be managed by any user, but some can be managed only by admin users:
diff --git a/deployment/index.md b/deployment/index.md
index e594468f5e9..3c0ab79967d 100644
--- a/deployment/index.md
+++ b/deployment/index.md
@@ -9,7 +9,7 @@ If you want to play with a local Kubernetes cluster, read [how to deploy an API
If you don't want to use Docker, keep in mind that the server application of API Platform is a standard Symfony project,
while the Progressive Web Application is a standard Next.js project:
-
Watch the Animated Deployment with Ansistrano screencast
+
Watch the Animated Deployment with Ansistrano screencast
- [Deploying the Symfony application](https://symfony.com/doc/current/deployment.html)
- [Deploying the Next.js application](https://nextjs.org/docs/deployment)
diff --git a/extra/contribution-guides.md b/extra/contribution-guides.md
index 3e3cd52aaa8..d410c59541d 100644
--- a/extra/contribution-guides.md
+++ b/extra/contribution-guides.md
@@ -7,4 +7,4 @@
**To report a security issue, please refer to [the dedicated document](security.md).**
-
Watch the Contributing back to Symfony screencast (free)
+
Watch the Contributing back to Symfony screencast (free)
diff --git a/outline.yaml b/outline.yaml
index d06d9052727..2ab6b4879ea 100644
--- a/outline.yaml
+++ b/outline.yaml
@@ -9,14 +9,14 @@ chapters:
- testing
- debugging
- caddy
- - migrate-from-fosrestbundle
- - fosuser-bundle
- - nelmio-api-doc
- - user
- jwt
+ - messenger
+ - user
- file-upload
- controllers
- - messenger
+ - nelmio-api-doc
+ - migrate-from-fosrestbundle
+ - fosuser-bundle
- title: "API Platform for Laravel"
path: laravel
items:
diff --git a/symfony/debugging.md b/symfony/debugging.md
index e128a4dfce5..9af77dd5204 100644
--- a/symfony/debugging.md
+++ b/symfony/debugging.md
@@ -1,6 +1,6 @@
# Debugging
-
Watch the Debugging API Platform screencast
+
Watch the Debugging API Platform screencast
## Xdebug
diff --git a/symfony/index.md b/symfony/index.md
index b2e379bcdcb..6dbfe98bcf7 100644
--- a/symfony/index.md
+++ b/symfony/index.md
@@ -19,8 +19,8 @@ API Platform is shipped with **[Docker](../deployment/docker-compose.md)** and *
The easiest and most powerful way to get started is [to download the API Platform distribution](https://github.com/api-platform/api-platform/releases). It contains:
- the API skeleton, including [the Core library](../core/index.md), [the Symfony framework](https://symfony.com/) ([optional](../core/bootstrap.md)) and [the Doctrine ORM](https://www.doctrine-project.org/projects/orm.html) ([optional](../core/extending.md))
-- [the client scaffolding tool](../create-client/) to generate [Next.js](../create-client/) web applications from the API documentation ([Nuxt](https://nuxt.com/), [Vue](https://vuejs.org/), [Create React App](https://reactjs.org), [React Native](https://reactnative.dev/), [Quasar](https://quasar.dev/) and [Vuetify](https://vuetifyjs.com/) are also supported)
-- [a beautiful admin interface](../admin/), built on top of React Admin, dynamically created by parsing the API documentation
+- [the client scaffolding tool](../create-client/index.md) to generate [Next.js](../create-client/index.md) web applications from the API documentation ([Nuxt](https://nuxt.com/), [Vue](https://vuejs.org/), [Create React App](https://reactjs.org), [React Native](https://reactnative.dev/), [Quasar](https://quasar.dev/) and [Vuetify](https://vuetifyjs.com/) are also supported)
+- [a beautiful admin interface](../admin/index.md), built on top of React Admin, dynamically created by parsing the API documentation
- all you need to [create real-time and async APIs using the Mercure protocol](../core/mercure.md)
- a [Docker](../deployment/docker-compose.md) definition to start a working development environment in a single command, providing containers for the API and the Next.js web application
- a [Helm](https://helm.sh/) chart to deploy the API in any [Kubernetes](../deployment/kubernetes.md) cluster
@@ -799,6 +799,6 @@ and [browse it online](https://demo.api-platform.com).
## Screencasts
-
+
The easiest and funniest way to learn how to use API Platform is to watch [the more than 60 screencasts available on SymfonyCasts](https://symfonycasts.com/tracks/rest?cid=apip#api-platform-3)!
diff --git a/symfony/jwt.md b/symfony/jwt.md
index 460da9b417a..f55c560d050 100644
--- a/symfony/jwt.md
+++ b/symfony/jwt.md
@@ -5,7 +5,7 @@
> **we recommend adopting open standards such as [OpenID Connect (OIDC)](https://openid.net/connect/)** for robust, scalable,
> and interoperable authentication.
-
Watch the LexikJWTAuthenticationBundle screencast
+
Watch the LexikJWTAuthenticationBundle screencast
## Installing LexikJWTAuthenticationBundle
diff --git a/symfony/security.md b/symfony/security.md
index a8848cdff9d..3f93f4bf86f 100644
--- a/symfony/security.md
+++ b/symfony/security.md
@@ -4,7 +4,7 @@ The API Platform security layer is built on top of the [Symfony Security compone
All its features, including [global access control directives](https://symfony.com/doc/current/security.html#securing-url-patterns-access-control) are supported.
API Platform also provides convenient [access control expressions](https://symfony.com/doc/current/expressions.html#security-complex-access-controls-with-expressions) which you can apply at resource and operation level.
-
Watch the Security screencast
+
Watch the Security screencast
@@ -110,8 +110,8 @@ Available variables are:
- `previous_object`: (`securityPostDenormalize` only) a clone of `object`, before modifications were made - this is `null` for create operations
- `request` (only at the resource level): the current request
-Access control checks in the `security` attribute are always executed before the [denormalization step](serialization.md).
-It means that for `PUT` or `PATCH` requests, `object` doesn't contain the value submitted by the user, but values currently stored in [the persistence layer](state-processors.md).
+Access control checks in the `security` attribute are always executed before the [denormalization step](../core/serialization.md).
+It means that for `PUT` or `PATCH` requests, `object` doesn't contain the value submitted by the user, but values currently stored in [the persistence layer](../core/state-processors.md).
## Executing Access Control Rules After Denormalization
@@ -337,17 +337,17 @@ resources:
## Filtering Collection According to the Current User Permissions
-Filtering collections according to the role or permissions of the current user must be done directly at [the state provider](state-providers.md) level. For instance, when using the built-in adapters for Doctrine ORM, MongoDB and ElasticSearch, removing entries from a collection should be done using [extensions](extensions.md).
+Filtering collections according to the role or permissions of the current user must be done directly at [the state provider](../core/state-providers.md) level. For instance, when using the built-in adapters for Doctrine ORM, MongoDB and ElasticSearch, removing entries from a collection should be done using [extensions](../core/extensions.md).
Extensions allow to customize the generated DQL/Mongo/Elastic/... query used to retrieve the collection (e.g. add `WHERE` clauses depending of the currently connected user) instead of using access control expressions.
As extensions are services, you can [inject the Symfony `Security` class](https://symfony.com/doc/current/security.html#b-fetching-the-user-from-a-service) into them to access to current user's roles and permissions.
-If you use [custom state providers](state-providers.md), you'll have to implement the filtering logic according to the persistence layer you rely on.
+If you use [custom state providers](../core/state-providers.md), you'll have to implement the filtering logic according to the persistence layer you rely on.
## Disabling Operations
-To completely disable some operations from your application, refer to the [disabling operations](operations.md#enabling-and-disabling-operations)
+To completely disable some operations from your application, refer to the [disabling operations](../core/operations.md#enabling-and-disabling-operations)
section.
## Changing Serialization Groups Depending of the Current User
-See [how to dynamically change](serialization.md#changing-the-serialization-context-dynamically) the current Serializer context according to the current logged in user.
+See [how to dynamically change](../core/serialization.md#changing-the-serialization-context-dynamically) the current Serializer context according to the current logged-in user.
diff --git a/symfony/testing.md b/symfony/testing.md
index 4f9cb3b810b..0e04307a3bb 100644
--- a/symfony/testing.md
+++ b/symfony/testing.md
@@ -5,7 +5,7 @@ For an introduction to testing using API Platform, refer to the [Core Testing Do
Let's learn how to use tests with Symfony!
-
Watch the Tests & Assertions screencast
+
Watch the Tests & Assertions screencast
In this article you'll learn how to use:
@@ -377,14 +377,14 @@ If you would like to verify that your stack (including services such as the DBMS
works, you need [end-to-end testing](https://wiki.c2.com/?EndToEndPrinciple). To do so, we recommend using [Playwright](https://playwright.dev) if you use have PWA/JavaScript-heavy app, or [Symfony Panther](https://github.com/symfony/panther) if you mostly use Twig.
Usually, end-to-end testing should be done with a production-like setup. For your convenience, you may [run our Docker Compose setup
-for production locally](../deployment/docker-compose.md#running-the-docker-compose-setup-for-production-locally).
+for production locally](../deployment/docker-compose.md#deploying-with-docker-compose).
## Testing Utilities for Symfony
API Platform provides a set of useful utilities dedicated to API testing.
For an overview of how to test an API Platform app, be sure to read [the testing part first](#testing-the-api-with-symfony).
-
Watch the API Tests & Assertions screencast
+
Watch the API Tests & Assertions screencast
### The Test HttpClient
diff --git a/symfony/validation.md b/symfony/validation.md
index ec7eaa6dfd7..cdfc5f28f56 100644
--- a/symfony/validation.md
+++ b/symfony/validation.md
@@ -4,7 +4,7 @@ API Platform takes care of validating the data sent to the API by the client (us
By default, the framework relies on [the powerful Symfony Validator Component](https://symfony.com/doc/current/validation.html)
for this task, but you can replace it with your preferred validation library such as [the PHP filter extension](https://www.php.net/manual/en/intro.filter.php) if you want to.
-
Watch the Validation screencast
+
Watch the Validation screencast
## Validating Submitted Data
@@ -104,7 +104,7 @@ error will look like the following if the requested format is JSON-LD (the defau
}
```
-Take a look at the [Errors Handling guide](errors.md) to learn how API Platform converts PHP exceptions like validation
+Take a look at the [Errors Handling guide](../core/errors.md) to learn how API Platform converts PHP exceptions like validation
errors to HTTP errors.
## Using Validation Groups
@@ -136,7 +136,7 @@ class Book
With the previous configuration, the validation groups `a` and `b` will be used when validation is performed.
-Like for [serialization groups](serialization.md#using-different-serialization-groups-per-operation),
+Like for [serialization groups](../core/serialization.md#using-serialization-groups-per-operation),
you can specify validation groups globally or on a per-operation basis.
Of course, you can use XML or YAML configuration format instead of attributes if you prefer.
@@ -146,7 +146,7 @@ the array of group names.
## Using Validation Groups on Operations
-You can have different validation for each [operation](operations.md) related to your resource.
+You can have different validation for each [operation](../core/operations.md) related to your resource.
```php
getValues()`. Then, define your validation on the getter instead of the property.
For example: