```php
* With JSON-lD / Hydra, [an `owl:deprecated` annotation property](https://www.w3.org/TR/owl2-syntax/#Annotation_Properties) will be added to the appropriate data structure
* With Swagger / OpenAPI, [a `deprecated` property](https://swagger.io/docs/specification/2-0/paths-and-operations/) will be added
diff --git a/core/design.md b/core/design.md
index 79b318e6bfa..3f85d5f233a 100644
--- a/core/design.md
+++ b/core/design.md
@@ -8,7 +8,7 @@ To do so, you have to write a plain old PHP object (POPO) representing the input
that is [marked with the `#[ApiResource]` attribute](../distribution/index.md).
This class **doesn't have** to be mapped with Doctrine ORM, or any other persistence system. It must be simple (it's usually
just a data structure with no or minimal behaviors) and will be automatically converted to [Hydra](extending-jsonld-context.md),
-[OpenAPI](swagger.md) and [GraphQL](graphql.md) documentations or schemas by API Platform (there is a 1-1 mapping
+[OpenAPI](openapi.md) and [GraphQL](graphql.md) documentations or schemas by API Platform (there is a 1-1 mapping
between this class and those docs).
Then, it's up to the developer to feed API Platform with an hydrated instance of this API resource object by implementing
diff --git a/core/dto.md b/core/dto.md
index f27168f3449..a3171424d8e 100644
--- a/core/dto.md
+++ b/core/dto.md
@@ -124,7 +124,7 @@ final class BookRepresentationProvider implements ProviderInterface
For returning another representation of your data in a [State Processor](./state-processors.md), you should specify your processor class in the `processor` attribute and same for your `output`.
-[codeSelector]
+
```php
```
-[/codeSelector]
+
Here the `$data` attribute represents an instance of your resource.
diff --git a/core/extending-jsonld-context.md b/core/extending-jsonld-context.md
index bea0e172bfb..2724aa471d9 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. Everything you define
@@ -67,7 +67,7 @@ Note that you do not have to provide the `@id` attribute. If you do not provide
It's also possible to replace the Hydra context used by the documentation generator:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
diff --git a/core/extending.md b/core/extending.md
index c6294970c1b..c38b26e3c12 100644
--- a/core/extending.md
+++ b/core/extending.md
@@ -1,6 +1,6 @@
# Extending API Platform
-Because it handles the complex, tedious and repetitive task of creating an API infrastructure for you, API Platform lets you focus on what matter the most for the end user: the business logic.
+Because it handles the complex, tedious and repetitive task of creating an API infrastructure for you, API Platform lets you focus on what matters the most for the end user: the business logic.
To do so, API Platform provides a lot of extension points you can use to hook your own code.
Those extensions points are taken into account both by the REST and [GraphQL](graphql.md) subsystems.
diff --git a/core/extensions.md b/core/extensions.md
index 2b4ad229d2b..a669f7afa0d 100644
--- a/core/extensions.md
+++ b/core/extensions.md
@@ -6,7 +6,7 @@ Extensions are specific to Doctrine and Elasticsearch-PHP, and therefore, the Do
reading support must be enabled to use this feature. If you use custom providers it's up to you to implement your own
extension system or not.
-You can find a working example of a custom extension using a pagination in the [API Platform's demo application](https://github.com/api-platform/demo/blob/main/api/src/State/Extension/TopBookPaginationExtension.php).
+You can find a working example of a custom extension in the [API Platform's demo application](https://github.com/api-platform/demo/blob/main/api/src/Doctrine/Orm/Extension/BookmarkQueryCollectionExtension.php).
## Custom Doctrine ORM Extension
@@ -117,10 +117,10 @@ Note that your extensions should have a positive priority if defined. Internal e
| Service name | Priority | Class |
|------------------------------------------------------------|------|---------------------------------------------------------|
-| `api_platform.doctrine.orm.query_extension.eager_loading` (collection) | -8 | ApiPlatform\Doctrine\Orm\Extension\EagerLoadingExtension |
| `api_platform.doctrine.orm.query_extension.eager_loading` (item) | -8 | ApiPlatform\Doctrine\Orm\Extension\EagerLoadingExtension |
| `api_platform.doctrine.orm.query_extension.filter` | -16 | ApiPlatform\Doctrine\Orm\Extension\FilterExtension |
| `api_platform.doctrine.orm.query_extension.filter_eager_loading` | -17 | ApiPlatform\Doctrine\Orm\Extension\FilterEagerLoadingExtension |
+| `api_platform.doctrine.orm.query_extension.eager_loading` (collection) | -18 | ApiPlatform\Doctrine\Orm\Extension\EagerLoadingExtension |
| `api_platform.doctrine.orm.query_extension.order` | -32 | ApiPlatform\Doctrine\Orm\Extension\OrderExtension |
| `api_platform.doctrine.orm.query_extension.pagination` | -64 | ApiPlatform\Doctrine\Orm\Extension\PaginationExtension |
diff --git a/core/external-vocabularies.md b/core/external-vocabularies.md
index 7427b92bda4..4ea20590255 100644
--- a/core/external-vocabularies.md
+++ b/core/external-vocabularies.md
@@ -1,9 +1,9 @@
# Using External Vocabularies
JSON-LD allows to define classes and properties of your API with open vocabularies such as [Schema.org](https://schema.org)
-and [Good Relations](http://www.heppnetz.de/projects/goodrelations/).
+and [Good Relations](https://www.heppnetz.de/projects/goodrelations/).
-API Platform provides annotations usable on PHP classes and properties for specifying a related external [IRI](https://en.wikipedia.org/wiki/Internationalized_resource_identifier).
+API Platform provides attributes usable on PHP classes and properties for specifying a related external [IRI](https://en.wikipedia.org/wiki/Internationalized_resource_identifier).
```php
Watch the Filtering & Searching screencast
+
Watch the Filtering & Searching screencast
## Doctrine ORM and MongoDB ODM Filters
@@ -23,112 +23,112 @@ to a Resource in two ways:
1. Through the resource declaration, as the `filters` attribute.
- For example, having a filter service declaration in `services.yaml`:
+For example, having a filter service declaration in `services.yaml`:
- ```yaml
- # api/config/services.yaml
- services:
+```yaml
+# api/config/services.yaml
+services:
+ # ...
+ offer.date_filter:
+ parent: 'api_platform.doctrine.orm.date_filter'
+ arguments: [ { dateProperty: ~ } ]
+ tags: [ 'api_platform.filter' ]
+ # The following are mandatory only if a _defaults section is defined with inverted values.
+ # You may want to isolate filters in a dedicated file to avoid adding the following lines.
+ autowire: false
+ autoconfigure: false
+ public: false
+```
+
+Alternatively, you can choose to use a dedicated file to gather filters together:
+
+```yaml
+# api/config/filters.yaml
+services:
+ offer.date_filter:
+ parent: 'api_platform.doctrine.orm.date_filter'
+ arguments: [ { dateProperty: ~ } ]
+ tags: [ 'api_platform.filter' ]
+```
+
+We're linking the filter `offer.date_filter` with the resource like this:
+
+
+
+```php
+
-
-
-
-
-
-
-
- offer.date_filter
-
-
-
-
-
-
- ```
-
- [/codeSelector]
+```
+
+```xml
+
+
+
+
+
+
+
+
+ offer.date_filter
+
+
+
+
+
+
+```
+
+
2. By using the `#[ApiFilter]` attribute.
- This attribute automatically declares the service, and you just have to use the filter class you want:
+This attribute automatically declares the service, and you just have to use the filter class you want:
- ```php
-
```php
`http://localhost:8000/api/offers?price=10` will return all offers with a price being exactly `10`.
`http://localhost:8000/api/offers?description=shirt` will return all offers with a description containing the word "shirt".
@@ -204,7 +204,7 @@ Filters can be combined together: `http://localhost:8000/api/offers?price=10&des
It is possible to filter on relations too, if `Offer` has a `Product` relation:
-[codeSelector]
+
```php
With this service definition, it is possible to find all offers belonging to the product identified by a given IRI.
Try the following: `http://localhost:8000/api/offers?product=/api/products/12`.
@@ -264,7 +264,7 @@ The `after` and `before` filters will filter including the value whereas `strict
Like other filters, the date filter must be explicitly enabled:
-[codeSelector]
+
```php
Given that the collection endpoint is `/offers`, you can filter offers by date with the following query: `/offers?createdAt[after]=2018-03-19`.
@@ -325,7 +325,7 @@ Always include items | `ApiPlatform\Doctrine\Orm\Filter\DateFilt
For instance, exclude entries with a property value of `null` with the following service definition:
-[codeSelector]
+
```php
### Boolean Filter
@@ -375,7 +375,7 @@ Syntax: `?property=`
Enable the filter:
-[codeSelector]
+
```php
Given that the collection endpoint is `/offers`, you can filter offers with the following query: `/offers?isAvailableGenericallyInMyCountry=true`.
@@ -429,7 +429,7 @@ Syntax: `?property=`
Enable the filter:
-[codeSelector]
+
```php
Given that the collection endpoint is `/offers`, you can filter offers with the following query: `/offers?sold=1`.
@@ -483,7 +483,7 @@ Syntax: `?property[]=value`
Enable the filter:
-[codeSelector]
+
```php
Given that the collection endpoint is `/offers`, you can filter the price with the following query: `/offers?price[between]=12.99..15.99`.
@@ -540,7 +540,7 @@ Syntax: `?exists[property]=`
Enable the filter:
-[codeSelector]
+
```php
Given that the collection endpoint is `/offers`, you can filter offers on the nullable field with the following query: `/offers?exists[transportFees]=true`.
@@ -606,7 +606,7 @@ Syntax: `?order[property]=`
Enable the filter:
-[codeSelector]
+
```php
Given that the collection endpoint is `/offers`, you can filter offers by name in ascending order and then by ID in descending
order with the following query: `/offers?order[name]=desc&order[id]=asc`.
@@ -656,7 +656,7 @@ order with the following query: `/offers?order[name]=desc&order[id]=asc`.
By default, whenever the query does not specify the direction explicitly (e.g.: `/offers?order[name]&order[id]`), filters
will not be applied unless you configure a default order direction to use:
-[codeSelector]
+
```php
#### Comparing with Null Values
@@ -713,7 +713,7 @@ Order items always last | `ApiPlatform\Doctrine\Orm\Filter\OrderFil
For instance, treat entries with a property value of `null` as the smallest, with the following service definition:
-[codeSelector]
+
```php
The strategy to use by default can be configured globally:
@@ -781,7 +781,7 @@ api_platform:
Sometimes, you need to be able to perform filtering based on some linked resources (on the other side of a relation). All
built-in filters support nested properties using the dot (`.`) syntax, e.g.:
-[codeSelector]
+
```php
The above allows you to find offers by their respective product's color: `http://localhost:8000/api/offers?product.color=red`,
or order offers by the product's release date: `http://localhost:8000/api/offers?order[product.releaseDate]=desc`
@@ -843,7 +843,7 @@ As we have seen in previous examples, properties where filters can be applied mu
care about security and performance (e.g. an API with restricted access), it is also possible to enable built-in filters
for all properties:
-[codeSelector]
+
```php
**Note: Filters on nested properties must still be enabled explicitly, in order to keep things sane.**
@@ -909,7 +909,7 @@ Syntax: `?order[property]=`
Enable the filter:
-[codeSelector]
+
```php
Given that the collection endpoint is `/tweets`, you can filter tweets by ID and date in ascending or descending order:
`/tweets?order[id]=asc&order[date]=desc`.
@@ -1416,10 +1416,10 @@ class AndOperatorFilterExtension implements RequestBodySearchCollectionExtension
### Using Doctrine ORM Filters
-Doctrine ORM features [a filter system](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/filters.html) that allows the developer to add SQL to the conditional clauses of queries, regardless of the place where the SQL is generated (e.g. from a DQL query, or by loading associated entities).
+Doctrine ORM features [a filter system](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/filters.html) that allows the developer to add SQL to the conditional clauses of queries, regardless of the place where the SQL is generated (e.g. from a DQL query, or by loading associated entities).
These are applied to collections and items and therefore are incredibly useful.
-The following information, specific to Doctrine filters in Symfony, is based upon [a great article posted on Michaël Perrin's blog](http://blog.michaelperrin.fr/2014/12/05/doctrine-filters/).
+The following information, specific to Doctrine filters in Symfony, is based upon [a great article posted on Michaël Perrin's blog](https://www.michaelperrin.fr/blog/2014/12/doctrine-filters).
Suppose we have a `User` entity and an `Order` entity related to the `User` one. A user should only see his orders and no one else's.
diff --git a/core/getting-started.md b/core/getting-started.md
index 26e3156e667..ec462033433 100644
--- a/core/getting-started.md
+++ b/core/getting-started.md
@@ -9,11 +9,11 @@ If you plan to migrate from FOSRestBundle, you might want to read [this guide](m
If you are starting a new project, the easiest way to get API Platform up is to install the [API Platform Distribution](../distribution/index.md).
It comes with the API Platform core library integrated with [the Symfony framework](https://symfony.com), [the schema generator](../schema-generator/),
[Doctrine ORM](https://www.doctrine-project.org), [Elasticsearch-PHP](https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html),
-[NelmioCorsBundle](https://github.com/nelmio/NelmioCorsBundle) and [Behat](http://behat.org).
+[NelmioCorsBundle](https://github.com/nelmio/NelmioCorsBundle) and [Behat](https://behat.org/).
[Doctrine MongoDB ODM](https://www.doctrine-project.org/projects/mongodb-odm.html) can also be enabled by following the [MongoDB documentation](mongodb.md).
Basically, it is a Symfony edition packaged with the best tools to develop a REST API and sensible default settings.
-Alternatively, you can use [Composer](http://getcomposer.org) to install the standalone bundle in an existing Symfony Flex
+Alternatively, you can use [Composer](https://getcomposer.org/) to install the standalone bundle in an existing Symfony Flex
project:
`composer require api`
@@ -26,7 +26,7 @@ There are no mandatory configuration options although [many settings are availab
If you haven't read it already, take a look at [the Getting Started guide](../distribution/index.md).
This tutorial covers basic concepts required to understand how API Platform works including how it implements the REST pattern
-and what [JSON-LD](http://json-ld.org/) and [Hydra](http://www.hydra-cg.com/) formats are.
+and what [JSON-LD](https://json-ld.org/) and [Hydra](https://www.hydra-cg.com/) formats are.
## Mapping the Entities
@@ -34,9 +34,9 @@ and what [JSON-LD](http://json-ld.org/) and [Hydra](http://www.hydra-cg.com/) fo
API Platform is able to automatically expose entities mapped as "API resources" through a REST API supporting CRUD
operations.
-To expose your entities, you can use Docblock annotations, XML and YAML configuration files.
+To expose your entities, you can use attributes, XML and YAML configuration files.
-Here is an example of entities mapped using annotations which will be exposed through a REST API:
+Here is an example of entities mapped using attributes which will be exposed through a REST API:
```php
```yaml
# api/config/api_platform/resources.yaml
@@ -200,16 +200,16 @@ resources:
```
-[/codeSelector]
+
-If you prefer to use YAML or XML files instead of annotations, you must configure API Platform to load the appropriate files:
+If you prefer to use YAML or XML files instead of attributes, you must configure API Platform to load the appropriate files:
```yaml
# api/config/packages/api_platform.yaml
api_platform:
mapping:
paths:
- - '%kernel.project_dir%/src/Entity' # default configuration for annotations
+ - '%kernel.project_dir%/src/Entity' # default configuration for attributes
- '%kernel.project_dir%/config/api_platform' # yaml or xml directory configuration
```
@@ -220,6 +220,6 @@ If you want to serialize only a subset of your data, please refer to the [Serial
You now have a fully featured API exposing your entities.
Run the Symfony app with the [Symfony Local Web Server](https://symfony.com/doc/current/setup/symfony_server.html) (`symfony server:start`) and browse the API entrypoint at `http://localhost:8000/api`.
-Interact with the API using a REST client (we recommend [Postman](https://www.getpostman.com/)) or an Hydra-aware application
+Interact with the API using a REST client (we recommend [Postman](https://www.postman.com/)) or an Hydra-aware application
(you should give [Hydra Console](https://github.com/lanthaler/HydraConsole) a try). Take
a look at the usage examples in [the `features` directory](https://github.com/api-platform/core/tree/main/features).
diff --git a/core/graphql.md b/core/graphql.md
index 1a0d2ca88f6..f1ab7a8b771 100644
--- a/core/graphql.md
+++ b/core/graphql.md
@@ -1467,7 +1467,7 @@ final class ErrorHandler implements ErrorHandlerInterface
Then register the service:
-[codeSelector]
+
```yaml
# api/config/services.yaml
@@ -1508,7 +1508,7 @@ return function(ContainerConfigurator $configurator) {
};
```
-[/codeSelector]
+
### Formatting Exceptions and Errors
@@ -1860,7 +1860,7 @@ final class TypeConverter implements TypeConverterInterface
public function convertType(Type $type, bool $input, Operation $rootOperation, string $resourceClass, string $rootResource, ?string $property, int $depth)
{
if ('publicationDate' === $property
- && Book::class === $resourceClass
+ && Book::class === $rootResource
) {
return 'DateTime';
}
diff --git a/core/identifiers.md b/core/identifiers.md
index 84cde992956..5f8667fab97 100644
--- a/core/identifiers.md
+++ b/core/identifiers.md
@@ -9,7 +9,7 @@ To help with your development experience, we introduced an identifier normalizat
Let's say you have the following class, which is identified by a `UUID` type. In this example, `UUID` is not a simple string but an object with many attributes.
-[codeSelector]
+
```php
+
@@ -54,7 +54,7 @@ resource:
```
-[/codeSelector]
+
Once registered as an `ApiResource`, having an existing person, it will be accessible through the following URL: `/people/110e8400-e29b-11d4-a716-446655440000`.
Note that the property identifying our resource is named `code`.
@@ -136,7 +136,7 @@ final class UuidUriVariableTransformer implements UriVariableTransformerInterfac
Tag this service as an `api_platform.uri_variables.transformer`:
-[codeSelector]
+
```yaml
services:
@@ -151,7 +151,7 @@ services:
```
-[/codeSelector]
+
Your `PersonProvider` will now work as expected!
diff --git a/core/index.md b/core/index.md
index 089999ec2cd..56e1d3c3b7f 100644
--- a/core/index.md
+++ b/core/index.md
@@ -4,8 +4,8 @@ API Platform Core is an easy-to-use and powerful library to create [hypermedia-d
It is a component of the [API Platform framework](https://api-platform.com). It can be used as a standalone or with [the Symfony
framework](https://symfony.com) (recommended).
-It embraces [JSON for Linked Data (JSON-LD)](http://json-ld.org) and [Hydra Core Vocabulary](http://www.hydra-cg.com) web
-standards but also supports [HAL](http://stateless.co/hal_specification.html), [Swagger/Open API](https://www.openapis.org/), XML, JSON, CSV and YAML.
+It embraces [JSON for Linked Data (JSON-LD)](https://json-ld.org/) and [Hydra Core Vocabulary](https://www.hydra-cg.com/) web
+standards but also supports [HAL](https://stateless.co/hal_specification.html), [Swagger/Open API](https://www.openapis.org/), XML, JSON, CSV and YAML.
Build a working and fully featured CRUD API in minutes. Leverage the awesome features of the tool to develop complex and
high-performance API-first projects.
@@ -21,7 +21,7 @@ Here is the fully featured REST API you'll get in minutes:
* [Automatic CRUD](operations.md)
* Hypermedia (JSON-LD and HAL)
-* Machine-readable documentation of the API in the Hydra and [Swagger/Open API](swagger.md) formats,
+* Machine-readable documentation of the API in the Hydra and [Swagger/Open API](openapi.md) formats,
guessed from PHPDoc, Serializer, Validator and Doctrine ORM / MongoDB ODM metadata
* Nice human-readable documentation built with Swagger UI (including a sandbox) and/or ReDoc
* [Pagination](pagination.md)
diff --git a/core/json-schema.md b/core/json-schema.md
index 9c4366ea9ed..255863cba6e 100644
--- a/core/json-schema.md
+++ b/core/json-schema.md
@@ -1,6 +1,6 @@
# JSON Schema Support
-[JSON Schema](https://json-schema.org/) is a popular vocabulary to describe the shape of JSON documents. A variant of JSON Schema is also used [in OpenAPI specifications](swagger.md).
+[JSON Schema](https://json-schema.org/) is a popular vocabulary to describe the shape of JSON documents. A variant of JSON Schema is also used [in OpenAPI specifications](openapi.md).
API Platform provides an infrastructure to generate JSON Schemas for any resource, represented in any format (including JSON-LD).
The generated schema can be used with libraries such as [react-json-schema-form](https://github.com/rjsf-team/react-jsonschema-form) to build forms for the documented resources, or to [be used for validation](https://json-schema.org/implementations.html#validators).
@@ -75,7 +75,7 @@ class Greeting
}
```
-You can obtain more information about the available [JSON Schema Types and format here](http://json-schema.org/understanding-json-schema/reference/type.html).
+You can obtain more information about the available [JSON Schema Types and format here](https://json-schema.org/understanding-json-schema/reference/type.html).
## Generating a JSON Schema Programmatically
diff --git a/core/jwt.md b/core/jwt.md
index b5bd8adaaf6..a1a83cb0047 100644
--- a/core/jwt.md
+++ b/core/jwt.md
@@ -30,7 +30,7 @@ docker compose exec php sh -c '
'
```
-Note that the `setfacl` command relies on the `acl` package. This is installed by default when using the API Platform docker distribution but may need be installed in your working environment in order to execute the `setfacl` command.
+Note that the `setfacl` command relies on the `acl` package. This is installed by default when using the API Platform docker distribution but may need to be installed in your working environment in order to execute the `setfacl` command.
This takes care of keypair creation (including using the correct passphrase to encrypt the private key), and setting the correct permissions on the keys allowing the web server to read them.
@@ -73,7 +73,7 @@ security:
entity:
class: App\Entity\User
property: email
- # document:
+ # mongodb:
# class: App\Document\User
# property: email
@@ -124,9 +124,6 @@ security:
# https://symfony.com/doc/current/security.html#c-hashing-passwords
password_hashers:
App\Entity\User: 'auto'
-
- # https://symfony.com/doc/current/security/authenticator_manager.html
- enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
diff --git a/core/mercure.md b/core/mercure.md
index 10d76904f3e..ba0b5410840 100644
--- a/core/mercure.md
+++ b/core/mercure.md
@@ -4,7 +4,7 @@ API Platform can automatically push the modified version of the resources expose
> *Mercure* is a protocol allowing to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. It is especially useful to publish real-time updates of resources served through web APIs, to reactive web and mobile apps.
>
-> —
+> —[https://mercure.rocks](https://mercure.rocks)
API Platform detects changes made to your Doctrine entities, and sends the updated resources to the Mercure hub.
Then, the Mercure hub dispatches the updates to all connected clients using [Server-sent Events (SSE)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events).
@@ -106,14 +106,14 @@ In addition to `private`, the following options are available:
Use `iri` (iriConverter) and `escape` (rawurlencode) functions to add an alternative topic, in order to restrict a subscriber with `topic_selector` to receive only publications that are authorized (partner match).
-> Let's say that a subscriber wants to receive updates concerning all book resources it has access to. The subscriber can use the topic selector as value of the topic query parameter.
+> Let's say that a subscriber wants to receive updates concerning all book resources it has access to. The subscriber can use the topic selector `https://example.com/books/{id}` as value of the topic query parameter.
> Adding this same URI template to the mercure.subscribe claim of the JWS presented by the subscriber to the hub would allow this subscriber to receive all updates for all book resources. It is not what we want here: this subscriber is only authorized to access some of these resources.
>
-> To solve this problem, the mercure.subscribe claim could contain a topic selector such as: .
+> To solve this problem, the mercure.subscribe claim could contain a topic selector such as: `https://example.com/users/foo/{?topic}`.
>
-> The publisher could then take advantage of the previously described behavior by publishing a private update having as canonical topic and as alternate topic.
+> The publisher could then take advantage of the previously described behavior by publishing a private update having `https://example.com/books/1` as canonical topic and `https://example.com/users/foo/?topic=https%3A%2F%2Fexample.com%2Fbooks%2F1` as alternate topic.
>
-> —
+> —[https://mercure.rocks/spec#subscribers](https://mercure.rocks/spec#subscribers)
Below is an example using the `topics` option:
diff --git a/core/messenger.md b/core/messenger.md
index b70c8180362..da036af60a6 100644
--- a/core/messenger.md
+++ b/core/messenger.md
@@ -20,7 +20,7 @@ docker compose exec php \
Set the `messenger` attribute to `true`, and API Platform will automatically dispatch the API Resource instance as a message using the message bus provided by the Messenger Component. The following example allows you to create a new `Person` in an asynchronous manner:
-[codeSelector]
+
```php
Because the `messenger` attribute is `true`, when a `POST` is handled by API Platform, the corresponding instance of the `Person` will be dispatched.
diff --git a/core/migrate-from-fosrestbundle.md b/core/migrate-from-fosrestbundle.md
index eb432cda322..3bb3e841293 100644
--- a/core/migrate-from-fosrestbundle.md
+++ b/core/migrate-from-fosrestbundle.md
@@ -82,7 +82,7 @@ Both the request and the response body's format can be customized.
You can configure the formats of the API either globally or in specific resources or operations. API Platform provides native support for multiple formats including JSON, XML, CSV, YAML, etc.
-See [Content negociation](content-negotiation.md).
+See [Content negotiation](content-negotiation.md).
### Name conversion
diff --git a/core/nelmio-api-doc.md b/core/nelmio-api-doc.md
index 33194182f1d..f31636953fd 100644
--- a/core/nelmio-api-doc.md
+++ b/core/nelmio-api-doc.md
@@ -1,6 +1,6 @@
# NelmioApiDocBundle Integration
-NelmioApiDoc provides an alternative to [the native Swagger/Open API support](swagger.md) provided by API Platform.
+NelmioApiDoc provides an alternative to [the native Swagger/Open API support](openapi.md) provided by API Platform.
As NelmioApiDocBundle 3+ has built-in support for API Platform, this documentation is only relevant for people using
NelmioApiDocBundle between version 2.9 and 3.0.
diff --git a/core/openapi.md b/core/openapi.md
index f0a31576732..0e8d320532f 100644
--- a/core/openapi.md
+++ b/core/openapi.md
@@ -1,6 +1,6 @@
# OpenAPI Specification Support (formerly Swagger)
-API Platform natively support the [OpenAPI](https://www.openapis.org/) API specification format.
+API Platform natively supports the [OpenAPI](https://www.openapis.org/) API specification format.
![Screenshot](../distribution/images/swagger-ui-1.png)
@@ -108,9 +108,12 @@ The impact on the swagger-ui is the following:
## Using the OpenAPI and Swagger Contexts
Sometimes you may want to change the information included in your OpenAPI documentation.
+
+For the full list of available configurations, please refer to the [OpenAPI Specifications](https://spec.openapis.org/oas/latest.html). The current doc page only gives some examples but focuses mostly on the OpenAPI integration inside API Platform without telling you all you can pass into the attributes.
+
The following configuration will give you total control over your OpenAPI definitions:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
This will produce the following Swagger documentation:
@@ -260,7 +263,7 @@ To pass a context to the OpenAPI **v2** generator, use the `swaggerContext` attr
Sometimes you may want to disable an operation from the OpenAPI documentation, for example to not exposing it.
Using the `openapi` boolean option disables this operation from the OpenAPI documentation:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
Note: as your route is not exposed, you may want to return a HTTP 404 if it's called. Prefer using the `NotExposedAction` controller instead.
@@ -349,7 +352,7 @@ class User
You also have full control over both built-in and custom operations documentation.
-[codeSelector]
+
```php
```
-[/codeSelector]
+
![Impact on Swagger UI](../distribution/images/swagger-ui-2.png)
diff --git a/core/operations.md b/core/operations.md
index 2c4f37f7b28..0b6083dcc5f 100644
--- a/core/operations.md
+++ b/core/operations.md
@@ -57,15 +57,15 @@ for large projects - to define operations explicitly.
Keep in mind that once you explicitly set up an operation, the automatically registered CRUD will no longer be.
If you declare even one operation manually, such as `#[GET]`, you must declare the others manually as well if you need them.
-Operations can be configured using annotations, XML or YAML. In the following examples, we enable only the built-in operation
+Operations can be configured using attributes, XML or YAML. In the following examples, we enable only the built-in operation
for the `GET` method for both `collection` and `item` to create a readonly endpoint.
-If the operation's name matches a supported HTTP methods (`GET`, `POST`, `PUT`, `PATCH` or `DELETE`), the corresponding `method` property
+If the operation's name matches a supported HTTP method (`GET`, `POST`, `PUT`, `PATCH` or `DELETE`), the corresponding `method` property
will be automatically added.
Note: The `#[GetCollection]` attribute is an alias for `#[Get(collection: true)]`
-[codeSelector]
+
```php
```
-[/codeSelector]
+
The previous example can also be written with an explicit method definition:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
API Platform is smart enough to automatically register the applicable Symfony route referencing a built-in CRUD action
just by specifying the method name as key, or by checking the explicitly configured HTTP method.
If you do not want to allow access to the resource item (i.e. you don't want a `GET` item operation), instead of omitting it altogether, you should instead declare a `GET` item operation which returns HTTP 404 (Not Found), so that the resource item can still be identified by an IRI. For example:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
## Configuring Operations
@@ -242,7 +242,7 @@ The URL, the method and the default status code (among other options) can be con
In the next example, both `GET` and `POST` operations are registered with custom URLs. Those will override the URLs generated by default.
In addition to that, we require the `id` parameter in the URL of the `GET` operation to be an integer, and we configure the status code generated after successful `POST` request to be `301`:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
## Prefixing All Routes of All Operations
@@ -335,7 +335,7 @@ Sometimes it's also useful to put a whole resource into its own "namespace" rega
put everything that's related to a `Book` into the `library` so that URIs become `library/book/{id}`. In that case
you don't need to override all the operations to set the path but configure the `routePrefix` attribute for the whole entity instead:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
## Defining Which Operation to Use to Generate the IRI
@@ -391,7 +391,7 @@ route to regular users.
To do so, use the `itemUriTemplate` option only available on `GetCollection` and `Post` operations:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
API Platform will find the operation matching this `itemUriTemplate` and use it to generate the IRI.
@@ -564,7 +564,7 @@ class Weather
// ...
```
-This will expose the `Weather` model, but also all the default CRUD routes: `GET`, `PUT`, `PATCH`, `DELETE` and `POST`, which is a non-sense in our context.
+This will expose the `Weather` model, but also all the default CRUD routes: `GET`, `PUT`, `PATCH`, `DELETE` and `POST`, which is nonsense in our context.
Since we are required to expose at least one route, let's expose just one:
```php
diff --git a/core/pagination.md b/core/pagination.md
index 97314d95aaa..5120a2f34f3 100644
--- a/core/pagination.md
+++ b/core/pagination.md
@@ -9,7 +9,7 @@ The activation of the pagination and the number of elements per page can be conf
* the server-side (globally or per resource)
* the client-side, via a custom GET parameter (disabled by default)
-When issuing a `GET` request on a collection containing more than 1 page (here `/books`), a [Hydra collection](http://www.hydra-cg.com/spec/latest/core/#collections)
+When issuing a `GET` request on a collection containing more than 1 page (here `/books`), a [Hydra collection](https://www.hydra-cg.com/spec/latest/core/#collections)
is returned. It's a valid JSON(-LD) document containing items of the requested page and metadata.
```json
@@ -72,7 +72,7 @@ api_platform:
It can also be disabled for a specific resource:
-[codeSelector]
+
```php
### Disabling the Pagination For a Specific Operation
You can also disable an operation for a specific operation:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
### Disabling the Pagination Client-side
@@ -410,45 +410,45 @@ The [PaginationExtension](https://github.com/api-platform/core/blob/main/src/Doc
* `$fetchJoinCollection` argument: Whether there is a join to a collection-valued association. When set to `true`, the Doctrine ORM Paginator will perform an additional query, in order to get the correct number of results.
- You can configure this using the `paginationFetchJoinCollection` attribute on a resource or on a per-operation basis:
+You can configure this using the `paginationFetchJoinCollection` attribute on a resource or on a per-operation basis:
- ```php
- **Warning**: in order to trigger the `EagerLoadingExtension` you must use [Serializer groups](serialization.md) on relations properties.
+
#### Max Joins
There is a default restriction with this feature. We allow up to 30 joins per query. Beyond that, an
@@ -357,46 +357,46 @@ To configure Blackfire.io follow these simple steps:
1. Add the following to your `docker-compose.override.yml` file:
- ```yaml
- blackfire:
- image: blackfire/blackfire:2
- environment:
- # Exposes the host BLACKFIRE_SERVER_ID and TOKEN environment variables.
- - BLACKFIRE_SERVER_ID
- - BLACKFIRE_SERVER_TOKEN
- - BLACKFIRE_DISABLE_LEGACY_PORT=1
- ```
+```yaml
+ blackfire:
+ image: blackfire/blackfire:2
+ environment:
+ # Exposes the host BLACKFIRE_SERVER_ID and TOKEN environment variables.
+ - BLACKFIRE_SERVER_ID
+ - BLACKFIRE_SERVER_TOKEN
+ - BLACKFIRE_DISABLE_LEGACY_PORT=1
+```
2. Add your Blackfire.io ID and server token to your `.env` file at the root of your project (be sure not to commit this to a public repository):
- ```shell
- BLACKFIRE_SERVER_ID=xxxxxxxxxx
- BLACKFIRE_SERVER_TOKEN=xxxxxxxxxx
- ```
+```shell
+BLACKFIRE_SERVER_ID=xxxxxxxxxx
+BLACKFIRE_SERVER_TOKEN=xxxxxxxxxx
+```
- Or set it in the console before running Docker commands:
+Or set it in the console before running Docker commands:
- ```shell
- export BLACKFIRE_SERVER_ID=xxxxxxxxxx
- export BLACKFIRE_SERVER_TOKEN=xxxxxxxxxx
- ```
+```shell
+export BLACKFIRE_SERVER_ID=xxxxxxxxxx
+export BLACKFIRE_SERVER_TOKEN=xxxxxxxxxx
+```
3. Install and configure the Blackfire probe in the app container, by adding the following to your `./Dockerfile`:
- ```dockerfile
- RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \
- && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/alpine/amd64/$version \
- && mkdir -p /tmp/blackfire \
- && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \
- && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get('extension_dir');")/blackfire.so \
- && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8307\n" > $PHP_INI_DIR/conf.d/blackfire.ini
- ```
+```dockerfile
+ RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \
+ && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/alpine/amd64/$version \
+ && mkdir -p /tmp/blackfire \
+ && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \
+ && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get('extension_dir');")/blackfire.so \
+ && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8307\n" > $PHP_INI_DIR/conf.d/blackfire.ini
+```
4. Rebuild and restart all your containers
- ```console
- docker compose build
- docker compose up --wait
- ```
+```console
+docker compose build
+docker compose up --wait
+```
For details on how to perform profiling, see [the Blackfire.io documentation](https://blackfire.io/docs/integrations/docker#using-the-client-for-http-profiling).
diff --git a/core/security.md b/core/security.md
index d51a10338fd..3bc4e892ed0 100644
--- a/core/security.md
+++ b/core/security.md
@@ -1,12 +1,12 @@
# Security
-The API Platform security layer is built on top of the [Symfony Security component](http://symfony.com/doc/current/book/security.html).
-All its features, including [global access control directives](http://symfony.com/doc/current/book/security.html#securing-url-patterns-access-control) are supported.
+The API Platform security layer is built on top of the [Symfony Security component](https://symfony.com/doc/current/security.html).
+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
-[codeSelector]
+
```php
Resource signature can be modified at the property level as well:
-[codeSelector]
+
```php
In this example:
@@ -118,7 +118,7 @@ It means that for `PUT` or `PATCH` requests, `object` doesn't contain the value
In some cases, it might be useful to execute a security after the denormalization step.
To do so, use the `securityPostDenormalize` attribute:
-[codeSelector]
+
```php
This time, the `object` variable contains data that have been extracted from the HTTP request body during the denormalization process.
However, the object is not persisted yet.
@@ -168,7 +168,7 @@ In order to give the current `object` to your voter, use the expression `is_gran
For example:
-[codeSelector]
+
```php
Please note that if you use both `security: "..."` and then `"post" => ["securityPostDenormalize" => "..."]`, the `security` on top level is called first, and after `securityPostDenormalize`. This could lead to unwanted behaviour, so avoid using both of them simultaneously.
If you need to use `securityPostDenormalize`, consider adding `security` for the other operations instead of the global one.
@@ -261,7 +261,7 @@ class BookVoter extends Voter
if ( $this->security->isGranted(Role::ADMIN) ) { return true; } // only admins can create books
break;
case 'BOOK_READ':
- /** ... other autorization rules ... **/
+ /** ... other authorization rules ... **/
}
return false;
@@ -280,7 +280,7 @@ You can change it by configuring the `securityMessage` attribute or the `securit
For example:
-[codeSelector]
+
```php
## Filtering Collection According to the Current User Permissions
diff --git a/core/serialization.md b/core/serialization.md
index a5c4658d02b..350e3effb61 100644
--- a/core/serialization.md
+++ b/core/serialization.md
@@ -43,8 +43,8 @@ to limit the serialization depth.
### Configuration
-Just like other Symfony and API Platform components, the Serializer component can be configured using annotations, XML
-or YAML. Since annotations are easy to understand, we will use them in the following examples.
+Just like other Symfony and API Platform components, the Serializer component can be configured using attributes, XML
+or YAML. Since attributes are easy to understand, we will use them in the following examples.
Note: if you aren't using the API Platform distribution, you will need to enable annotation support in the serializer configuration:
@@ -74,7 +74,7 @@ It is simple to specify what groups to use in the API system:
1. Add the normalization context and denormalization context attributes to the resource, and specify which groups to use. Here you see that we add `read` and `write`, respectively. You can use any group names you wish.
2. Apply the groups to properties in the object.
-[codeSelector]
+
```php
```
-[/codeSelector]
+
In the previous example, the `name` property will be visible when reading (`GET`) the object, and it will also be available
to write (`PUT` / `PATCH` / `POST`). The `author` property will be write-only; it will not be visible when serialized responses are
@@ -174,7 +174,7 @@ returned by the API.
Internally, API Platform passes the value of the `normalizationContext` as the 3rd argument of [the `Serializer::serialize()` method](https://api.symfony.com/master/Symfony/Component/Serializer/SerializerInterface.html#method_serialize) during the normalization
process. `denormalizationContext` is passed as the 4th argument of [the `Serializer::deserialize()` method](https://api.symfony.com/master/Symfony/Component/Serializer/SerializerInterface.html#method_deserialize) during denormalization (writing).
-To configure the serialization groups of classes's properties, you must use directly [the Symfony Serializer's configuration files or annotations](https://symfony.com/doc/current/components/serializer.html#attributes-groups).
+To configure the serialization groups of classes's properties, you must use directly [the Symfony Serializer's configuration files or attributes](https://symfony.com/doc/current/components/serializer.html#attributes-groups).
In addition to the `groups` key, you can configure any Symfony Serializer option through the `$context` parameter
(e.g. the `enable_max_depth`key when using [the `@MaxDepth` annotation](https://symfony.com/doc/current/components/serializer.html#handling-serialization-depth)).
@@ -191,7 +191,7 @@ level ignored.
In the following example we use different serialization groups for the `GET` and `PUT` operations:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
The `name` and `author` properties will be included in the document generated during a `GET` operation because the configuration
defined at the resource level is inherited. However the document generated when a `PUT` request will be received will only
@@ -322,11 +322,11 @@ In the following JSON document, the relation from a book to an author is by defa
```
It is possible to embed related objects (in their entirety, or only some of their properties) directly in the parent
-response through the use of serialization groups. By using the following serialization groups annotations (`#[Groups]`),
+response through the use of serialization groups. By using the following serialization groups attributes (`#[Groups]`),
a JSON representation of the author is embedded in the book response. As soon as any of the author's attributes is in
the `book` group, the author will be embedded.
-[codeSelector]
+
```php
-[codeSelector]
+
```php
The generated JSON using previous settings is below:
@@ -423,7 +423,7 @@ Instead of embedding relations in the main HTTP response, you may want [to "push
It is also possible to embed a relation in `PUT`, `PATCH` and `POST` requests. To enable that feature, set the serialization groups
the same way as normalization. For example:
-[codeSelector]
+
```php
The following rules apply when denormalizing embedded relations:
@@ -460,7 +460,7 @@ You can specify as many embedded relation levels as you want.
It is a common problem to have entities that reference other entities of the same type:
-[codeSelector]
+
```php
The problem here is that the **$parent** property become automatically an embedded object. Besides, the property won't be shown on the OpenAPI view.
To force the **$parent** property to be used as an IRI, add an `#[ApiProperty(readableLink: false, writableLink: false)]` annotation:
-[codeSelector]
+
```php
### Plain Identifiers
@@ -706,7 +706,7 @@ class Book
Sometimes you need to expose calculated fields. This can be done by leveraging the groups. This time not on a property, but on a method.
-[codeSelector]
+
```php
## Changing the Serialization Context Dynamically
@@ -774,7 +774,7 @@ App\Entity\Greeting:
Let's imagine a resource where most fields can be managed by any user, but some can be managed only by admin users:
-[codeSelector]
+
```php
All entry points are the same for all users, so we should find a way to detect if the authenticated user is an admin, and if so
dynamically add the `admin:input` value to deserialization groups in the `$context` array.
API Platform implements a `ContextBuilder`, which prepares the context for serialization & deserialization. Let's
-[decorate this service](http://symfony.com/doc/current/service_container/service_decoration.html) to override the
+[decorate this service](https://symfony.com/doc/current/service_container/service_decoration.html) to override the
`createFromRequest` method:
```yaml
@@ -968,7 +968,7 @@ provides many useful other services that might be better suited to your use case
## Name Conversion
-The Serializer Component provides a handy way to map PHP field names to serialized names. See the related [Symfony documentation](http://symfony.com/doc/master/components/serializer.html#converting-property-names-when-serializing-and-deserializing).
+The Serializer Component provides a handy way to map PHP field names to serialized names. See the related [Symfony documentation](https://symfony.com/doc/current/components/serializer.html#converting-property-names-when-serializing-and-deserializing).
To use this feature, declare a new name converter service. For example, you can convert `CamelCase` to
`snake_case` with the following configuration:
@@ -1011,7 +1011,8 @@ Note: this normalizer will work only for JSON-LD format, if you want to process
```php
```php
```
-[/codeSelector]
+
In some cases, you will want to set the identifier of a resource from the client (e.g. a client-side generated UUID, or a slug).
In such cases, you must make the identifier property a writable class property. Specifically, to use client-generated IDs, you
@@ -1155,7 +1156,7 @@ an IRI. A client that uses JSON-LD must send a second HTTP request to retrieve i
You can configure API Platform to embed the JSON-LD context in the root document by adding the `jsonld_embed_context`
attribute to the `#[ApiResource]` annotation:
-[codeSelector]
+
```php
The JSON output will now include the embedded context:
diff --git a/core/subresources.md b/core/subresources.md
index ef240f2c4a6..abe55fa69dc 100644
--- a/core/subresources.md
+++ b/core/subresources.md
@@ -21,7 +21,7 @@ the Question about the Universe using the following URI: `/question/42/answer`.
Let's start by defining the resources:
-[codeSelector]
+
```php
```
-[/codeSelector]
+
Now to create a new way of retrieving an Answer we will declare another resource on the `Answer` class.
To make things work, API Platform needs information about how to retrieve the `Answer` belonging to
the `Question`, this is done by configuring the `uriVariables`:
-[codeSelector]
+
```php
In this example, we instructed API Platform that the `Answer` we retrieve comes **from** the **class** `Question`
**from** the **property** `answer` of that class.
@@ -183,7 +183,7 @@ URI Variables are defined using Links (`ApiPlatform\Metadata\Link`). A `Link` ca
If we had a `relatedQuestions` property on the `Answer` we could retrieve the collection of related questions via the following definition:
-[codeSelector]
+
```php
#[ApiResource(
@@ -221,7 +221,7 @@ resources:
```
-[/codeSelector]
+
### Company Employee's
diff --git a/core/testing.md b/core/testing.md
index 2cf99b74865..30261b7cbb9 100644
--- a/core/testing.md
+++ b/core/testing.md
@@ -43,7 +43,7 @@ class BooksTest extends ApiTestCase
Refer to [the Symfony HttpClient documentation](https://symfony.com/doc/current/components/http_client.html) to discover all the features of the client (custom headers, JSON encoding and decoding, HTTP Basic and Bearer authentication and cookies support, among other things).
-Note that you can create your own test case class extending the ApiTestCase. For example to set up a Json Web Token authentification:
+Note that you can create your own test case class extending the ApiTestCase. For example to set up a Json Web Token authentication:
```php
```php
```
-[/codeSelector]
+
For the above configuration, the collection will be like this:
diff --git a/core/validation.md b/core/validation.md
index 8e401050f0c..2831a885b5b 100644
--- a/core/validation.md
+++ b/core/validation.md
@@ -1,15 +1,15 @@
# Validation
API Platform takes care of validating the data sent to the API by the client (usually user data entered through forms).
-By default, the framework relies on [the powerful Symfony Validator Component](http://symfony.com/doc/current/validation.html)
+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
## Validating Submitted Data
-Validating submitted data is as simple as adding [Symfony's built-in constraints](http://symfony.com/doc/current/reference/constraints.html)
-or [custom constraints](http://symfony.com/doc/current/validation/custom_constraint.html) directly in classes marked with
+Validating submitted data is as simple as adding [Symfony's built-in constraints](https://symfony.com/doc/current/reference/constraints.html)
+or [custom constraints](https://symfony.com/doc/current/validation/custom_constraint.html) directly in classes marked with
the `#[ApiResource]` attribute:
```php
@@ -141,7 +141,7 @@ 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.
-You may also pass in a [group sequence](http://symfony.com/doc/current/validation/sequence_provider.html) in place of
+You may also pass in a [group sequence](https://symfony.com/doc/current/validation/sequence_provider.html) in place of
the array of group names.
## Using Validation Groups on Operations
@@ -196,7 +196,7 @@ With this configuration, there are three validation groups:
If you need to dynamically determine which validation groups to use for an entity in different scenarios, just pass in a
[callable](https://www.php.net/manual/en/language.types.callable.php). The callback will receive the entity object as its first
-argument, and should return an array of group names or a [group sequence](http://symfony.com/doc/current/validation/sequence_provider.html).
+argument, and should return an array of group names or a [group sequence](https://symfony.com/doc/current/validation/sequence_provider.html).
In the following example, we use a static method to return the validation groups:
@@ -297,7 +297,7 @@ class Book
## Sequential Validation Groups
-If you need to specify the order in which your validation groups must be tested against, you can use a [group sequence](http://symfony.com/doc/current/validation/sequence_provider.html).
+If you need to specify the order in which your validation groups must be tested against, you can use a [group sequence](https://symfony.com/doc/current/validation/sequence_provider.html).
First, you need to create your sequenced group.
```php
diff --git a/create-client/custom.md b/create-client/custom.md
index 8a43013d439..4af5861c0cb 100644
--- a/create-client/custom.md
+++ b/create-client/custom.md
@@ -1,6 +1,6 @@
# Custom Generator
-Create Client provides support for many of the popular JS frameworks, but you may be using another framework or language and may need a solution adapted to your specific needs. For this cenario, you can write your own generator and pass it to the CLI using a path as the `-g` argument.
+Create Client provides support for many of the popular JS frameworks, but you may be using another framework or language and may need a solution adapted to your specific needs. For this scenario, you can write your own generator and pass it to the CLI using a path as the `-g` argument.
You will probably want to extend or, at least, take a look at [BaseGenerator.js](https://github.com/api-platform/create-client/blob/main/src/generators/BaseGenerator.js), since the library expects some methods to be available, as well as one of the [included generators](https://github.com/api-platform/create-client/blob/main/src/generators/BaseGenerator.js) to make your own.
diff --git a/create-client/index.md b/create-client/index.md
index fac74db7971..26893509395 100644
--- a/create-client/index.md
+++ b/create-client/index.md
@@ -1,7 +1,7 @@
# API Platform Create Client
Create Client is the fastest way to scaffold fully featured webapps
-and native mobile apps from APIs supporting the [Hydra](http://www.hydra-cg.com/) or [OpenAPI](https://www.openapis.org/) format.
+and native mobile apps from APIs supporting the [Hydra](https://www.hydra-cg.com/) or [OpenAPI](https://www.openapis.org/) format.
![Screencast](images/create-client-demo.gif)
diff --git a/create-client/nextjs.md b/create-client/nextjs.md
index c8143221901..58301befe78 100644
--- a/create-client/nextjs.md
+++ b/create-client/nextjs.md
@@ -36,7 +36,7 @@ yarn add isomorphic-unfetch formik react-query
```
The generated HTML will contain [Tailwind CSS](https://tailwindcss.com) classes.
-Optionnaly, [follow the Tailwind installation guide for NextJS projects](https://tailwindcss.com/docs/guides/nextjs)
+Optionally, [follow the Tailwind installation guide for NextJS projects](https://tailwindcss.com/docs/guides/nextjs)
(Tailwind is preinstalled in [the API Platform distribution](../distribution/index.md))
## Generating Routes
diff --git a/create-client/troubleshooting.md b/create-client/troubleshooting.md
index f2ab81e6a04..72a16eddd7b 100644
--- a/create-client/troubleshooting.md
+++ b/create-client/troubleshooting.md
@@ -59,5 +59,5 @@ message in JSON format was being returned.
## Docker distribution on Windows and hot-reloading
Due to [a long-time known Docker for Windows issue](https://forums.docker.com/t/file-system-watch-does-not-work-with-mounted-volumes/12038),
-the files changes on the host are not notified on the `pwa` container.
+the file changes on the host are not notified on the `pwa` container.
It causes the hot-reloading feature to not working properly for Windows users.
diff --git a/deployment/heroku.md b/deployment/heroku.md
index a5ec4706a8f..5ceedfb6059 100644
--- a/deployment/heroku.md
+++ b/deployment/heroku.md
@@ -13,7 +13,7 @@ Edition.*
If you don't already have one, [create an account on Heroku](https://signup.heroku.com/signup/dc). Then install [the Heroku
toolbelt](https://devcenter.heroku.com/articles/getting-started-with-php#set-up). We're guessing you already
-have a working install of [Composer](http://getcomposer.org). Perfect, we will need it.
+have a working install of [Composer](https://getcomposer.org/). Perfect, we will need it.
Create a new [API Platform project](distribution/index.md) which will be used in the rest of this example.
diff --git a/deployment/kubernetes.md b/deployment/kubernetes.md
index bcc17af96ae..689db5884ce 100644
--- a/deployment/kubernetes.md
+++ b/deployment/kubernetes.md
@@ -29,29 +29,37 @@ Change the name "test-api-platform" to your Google project ID (not the project n
[Quickstart Google Cloud](https://cloud.google.com/sdk/docs/quickstart?hl=de)
If you do not have gcloud yet, install it with these command.
- curl https://sdk.cloud.google.com | bash
+```console
+curl https://sdk.cloud.google.com | bash
+```
#### 1. Build the PHP and Caddy Docker images and tag them
Versioning: The 0.1.0 is the version. This value should be the same as the attribute `appVersion` in `Chart.yaml`.
Infos for [Google Container pulling and pushing](https://cloud.google.com/container-registry/docs/pushing-and-pulling)
- docker build -t gcr.io/test-api-platform/php:0.1.0 -t gcr.io/test-api-platform/php:latest api --target php_prod
- docker build -t gcr.io/test-api-platform/caddy:0.1.0 -t gcr.io/test-api-platform/caddy:latest api --target caddy_prod
- docker build -t gcr.io/test-api-platform/pwa:0.1.0 -t gcr.io/test-api-platform/pwa:latest pwa --target prod
+```
+docker build -t gcr.io/test-api-platform/php:0.1.0 -t gcr.io/test-api-platform/php:latest api --target php_prod
+docker build -t gcr.io/test-api-platform/caddy:0.1.0 -t gcr.io/test-api-platform/caddy:latest api --target caddy_prod
+docker build -t gcr.io/test-api-platform/pwa:0.1.0 -t gcr.io/test-api-platform/pwa:latest pwa --target prod
+```
#### 2. Push your images to your Docker registry
- gcloud auth configure-docker
- docker push gcr.io/test-api-platform/php
- docker push gcr.io/test-api-platform/caddy
- docker push gcr.io/test-api-platform/pwa
+```console
+gcloud auth configure-docker
+docker push gcr.io/test-api-platform/php
+docker push gcr.io/test-api-platform/caddy
+docker push gcr.io/test-api-platform/pwa
+```
Optional push the version images:
- docker push gcr.io/test-api-platform/php:0.1.0
- docker push gcr.io/test-api-platform/caddy:0.1.0
- docker push gcr.io/test-api-platform/pwa:0.1.0
+```console
+docker push gcr.io/test-api-platform/php:0.1.0
+docker push gcr.io/test-api-platform/caddy:0.1.0
+docker push gcr.io/test-api-platform/pwa:0.1.0
+```
The result should look similar to these images.
@@ -62,35 +70,43 @@ The result should look similar to these images.
### 1. Check the Helm version
- helm version
+```console
+helm version
+```
If you are using version 2.x follow this [guide to migrate Helm to v3](https://helm.sh/docs/topics/v2_v3_migration/#helm)
### 2. Firstly you need to update helm dependencies by running
- helm dependency update ./helm/api-platform
+```console
+helm dependency update ./helm/api-platform
+```
This will create a folder helm/api-platform/charts/ and add all dependencies there.
Actual this is [bitnami/postgresql](https://bitnami.com/stack/postgresql/helm), a file postgresql-[VERSION].tgz is created.
### 3. Optional: If you made changes to the Helm chart, check if its format is correct
- helm lint ./helm/api-platform
+```console
+helm lint ./helm/api-platform
+```
### 4. Deploy your API to the container
- helm upgrade main ./helm/api-platform --namespace=default --create-namespace --wait \
- --install \
- --set "php.image.repository=gcr.io/test-api-platform/php" \
- --set php.image.tag=latest \
- --set "caddy.image.repository=gcr.io/test-api-platform/caddy" \
- --set caddy.image.tag=latest \
- --set "pwa.image.repository=gcr.io/test-api-platform/pwa" \
- --set pwa.image.tag=latest \
- --set php.appSecret='!ChangeMe!' \
- --set postgresql.postgresqlPassword='!ChangeMe!' \
- --set postgresql.persistence.enabled=true \
- --set "corsAllowOrigin=^https?:\/\/[a-z]*\.mywebsite.com$"
+```console
+helm upgrade main ./helm/api-platform --namespace=default --create-namespace --wait \
+ --install \
+ --set "php.image.repository=gcr.io/test-api-platform/php" \
+ --set php.image.tag=latest \
+ --set "caddy.image.repository=gcr.io/test-api-platform/caddy" \
+ --set caddy.image.tag=latest \
+ --set "pwa.image.repository=gcr.io/test-api-platform/pwa" \
+ --set pwa.image.tag=latest \
+ --set php.appSecret='!ChangeMe!' \
+ --set postgresql.postgresqlPassword='!ChangeMe!' \
+ --set postgresql.persistence.enabled=true \
+ --set "corsAllowOrigin=^https?:\/\/[a-z]*\.mywebsite.com$"
+```
The `"` are necessary for Windows. Use ^ on Windows instead of \ to split commands into multiple lines.
You can add the parameter `--dry-run` to check upfront if anything is correct.
@@ -109,10 +125,12 @@ get access on your local machine to the deploy. See image below.
If you prefer to use a managed DBMS like [Heroku Postgres](https://www.heroku.com/postgres) or
[Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/) (recommended):
- helm upgrade api-platform ./helm/api-platform \
- # ...
- --set postgresql.enabled=false \
- --set postgresql.url=pgsql://username:password@host/database?serverVersion=13
+```console
+helm upgrade api-platform ./helm/api-platform \
+ # ...
+ --set postgresql.enabled=false \
+ --set postgresql.url=pgsql://username:password@host/database?serverVersion=13
+```
Finally, build the `pwa` (client and admin) JavaScript apps and [deploy them on a static
site hosting service](https://create-react-app.dev/docs/deployment/).
@@ -122,17 +140,19 @@ site hosting service](https://create-react-app.dev/docs/deployment/).
You can access the php container of the pod with the following command.
In this example the symfony console is called.
- CADDY_PHP_POD=$(kubectl --namespace=default get pods -l app.kubernetes.io/name=api-platform -o jsonpath="{.items[0].metadata.name}")
- kubectl --namespace=default exec -it $CADDY_PHP_POD -c api-platform-php -- bin/console
+```console
+CADDY_PHP_POD=$(kubectl --namespace=default get pods -l app.kubernetes.io/name=api-platform -o jsonpath="{.items[0].metadata.name}")
+kubectl --namespace=default exec -it $CADDY_PHP_POD -c api-platform-php -- bin/console
+```
## Caution for system architecture
-If the pods do not run, and you get the following error from google kubernetes engine logs,
+If the pods do not run, and you get the following error from google Kubernetes engine logs,
there is probably a problem with the system architecture.
`standard_init_linux.go:211: exec user process caused "exec format error`
Build the images with the same system architecture as the cluster runs.
Example: Building with Mac M1 with arm64 leads to problems. Most cluster will run with x86_64.
-Solution:
+Solution: [https://blog.jaimyn.dev/how-to-build-multi-architecture-docker-images-on-an-m1-mac](https://blog.jaimyn.dev/how-to-build-multi-architecture-docker-images-on-an-m1-mac)
## Updates
@@ -140,15 +160,18 @@ There are 2 main upgrade strategies.
### 1. Always version your images (recommended)
-Change the version in the attribut "appVersion" in Chart.yaml and tag the images with this version.
+Change the version in the attribute "appVersion" in Chart.yaml and tag the images with this version.
You can upgrade with the same command from the installation and pass all parameters.
### 2. Use :latest tags
-Infos about [best practices for tagging images for kubernetes](https://kubernetes.io/docs/concepts/containers/images/)
+Infos about [best practices for tagging images for Kubernetes](https://kubernetes.io/docs/concepts/containers/images/)
You have to use the *.image.pullPolicy=Always see the last 3 parameters.
- helm upgrade api-platform ./helm/api-platform --namespace=default \
+```console
+PHP_POD=$(kubectl --namespace=bar get pods -l app=php -o jsonpath="{.items[0].metadata.name}")
+kubectl --namespace=bar exec -it $PHP_POD -- bin/console doctrine:schema:create
+helm upgrade api-platform ./helm/api-platform --namespace=default \
--set "php.image.repository=gcr.io/test-api-platform/php" \
--set php.image.tag=latest \
--set "caddy.image.repository=gcr.io/test-api-platform/caddy" \
@@ -162,6 +185,7 @@ You have to use the *.image.pullPolicy=Always see the last 3 parameters.
--set php.image.pullPolicy=Always \
--set caddy.image.pullPolicy=Always \
--set pwa.image.pullPolicy=Always
+```
## GitHub Actions Example for deployment
@@ -175,24 +199,30 @@ Start by creating a new template for the queue-worker-deployment. The `deploymen
Add the following lines under `containers` to overwrite the command.
- command:
- {{ range .Values.queue_worker.command }}
- - {{ . | quote }}
- {{ end }}
- args:
- {{ range .Values.queue_worker.commandArgs }}
- - {{ . | quote }}
- {{ end }}
+```yaml
+command:
+{{ range .Values.queue_worker.command }}
+ - {{ . | quote }}
+{{ end }}
+args:
+{{ range .Values.queue_worker.commandArgs }}
+ - {{ . | quote }}
+{{ end }}
+```
Here is an example on how to use it from your `values.yaml`:
- command: ['bin/console']
- commandArgs: ['messenger:consume', 'async', '--memory-limit=100M']
+```yaml
+command: ['bin/console']
+commandArgs: ['messenger:consume', 'async', '--memory-limit=100M']
+```
The `readinessProbe` and the `livenessProble` can not use the default `docker-healthcheck` but should test if the command is running.
- readinessProbe:
- exec:
- command: ["/bin/sh", "-c", "/bin/ps -ef | grep messenger:consume | grep -v grep"]
- initialDelaySeconds: 120
- periodSeconds: 3
+```yaml
+readinessProbe:
+ exec:
+ command: ["/bin/sh", "-c", "/bin/ps -ef | grep messenger:consume | grep -v grep"]
+ initialDelaySeconds: 120
+ periodSeconds: 3
+```
diff --git a/deployment/minikube.md b/deployment/minikube.md
index d21debe57ee..fb41c64f6d0 100644
--- a/deployment/minikube.md
+++ b/deployment/minikube.md
@@ -2,9 +2,9 @@
## Install Minikube
-If you haven't an existing installation of Minikube on your computer, [follow the official tutorial](https://minikube.sigs.k8s.io/docs/start/).
+If you have no existing installation of Minikube on your computer, [follow the official tutorial](https://minikube.sigs.k8s.io/docs/start/).
-When Minkube is installed, start the cluster:
+When Minikube is installed, start the cluster:
minikube start --addons registry --addons dashboard
diff --git a/deployment/traefik.md b/deployment/traefik.md
index 18d5df85f12..d26f1977063 100644
--- a/deployment/traefik.md
+++ b/deployment/traefik.md
@@ -2,11 +2,11 @@
> An open-source reverse proxy and load balancer for HTTP and TCP-based applications that is easy, dynamic, automatic, fast, full-featured, production proven, provides metrics and integrates with every major cluster technology.
>
-> —
+> —[https://traefik.io](https://traefik.io)
## Basic Implementation
-This tutorial will help you to define your own routes for your client, api and more generally for your containers.
+This tutorial will help you to define your own routes for your client, API and more generally for your containers.
Use this custom API Platform `docker-compose.yml` file which implements ready-to-use Træfik container configuration. Override
ports and add labels to tell Træfik to listen on the routes mentioned and redirect routes to a specified container.
@@ -14,7 +14,7 @@ ports and add labels to tell Træfik to listen on the routes mentioned and redir
A few points to note:
* `--api.insecure=true` Tells Træfik to generate a browser view to watch containers and IP/DNS associated easier
-* `--providers.docker` Tells Træfik to listen on Docker Api
+* `--providers.docker` Tells Træfik to listen on Docker API
* `labels:` Key for Træfik configuration into Docker integration
```yaml
diff --git a/distribution/index.md b/distribution/index.md
index 6194b5ff650..eb84745f5f2 100644
--- a/distribution/index.md
+++ b/distribution/index.md
@@ -20,7 +20,7 @@ The easiest and most powerful way to get started is [to download the API Platfor
* 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://facebook.github.io/react-native/), [Quasar](https://quasar.dev/) and [Vuetify](https://vuetifyjs.com/) are also supported)
+) 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
* 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
@@ -227,7 +227,7 @@ For instance, go to `https://localhost/greetings.jsonld` to retrieve the list of
`https://localhost/greetings.json` to retrieve data in raw JSON.
Of course, you can also use your favorite HTTP client to query the API.
-We are fond of [Postman](https://www.getpostman.com/). It works perfectly well with API Platform, has native OpenAPI support,
+We are fond of [Postman](https://www.postman.com/). It works perfectly well with API Platform, has native OpenAPI support,
allows to easily write functional tests and has good team collaboration features.
## Bringing your Own Model
@@ -337,7 +337,7 @@ The framework also uses these metadata to serialize and deserialize data from JS
For the sake of simplicity, in this example we used public properties (except for the ID, see below). API Platform (as well
as Symfony and Doctrine) also supports accessor methods (getters/setters), use them if you want to.
-We used a private property and a getter for the ID to enforce the fact that it is read only (we will let the DBMS generating it). API Platform also has first-grade support for UUIDs. [You should
+We used a private property and a getter for the ID to enforce the fact that it is read only (we will let the DBMS generate it). API Platform also has first-grade support for UUIDs. [You should
probably use them instead of auto-incremented IDs](https://www.clever-cloud.com/blog/engineering/2015/05/20/why-auto-increment-is-a-terrible-idea/).
Because API Platform provides all the infrastructure for us, our API is almost ready!
@@ -356,7 +356,7 @@ Be sure to read the [General Design Considerations](../core/design.md) document
Here, we will use the built-in Doctrine ORM data provider in the rest of this tutorial.
-Modify the classes to map them to database tables using the annotations provided by the Doctrine ORM.
+Modify the classes to map them to database tables using the attributes provided by the Doctrine ORM.
Modify these files as described in these patches:
@@ -469,7 +469,7 @@ docker compose exec php \
```
The `php` container is where your API app stands. Prefixing a command by `docker compose exec php` allows executing the
-given command in this container. You may want [to create an alias](http://www.linfo.org/alias.html) to make your life easier.
+given command in this container. You may want [to create an alias](https://www.linfo.org/alias.html) to make your life easier.
**We now have a working API with read and write capabilities!**
@@ -745,7 +745,7 @@ occurs**.
## A Next.js Web App
API Platform also has an awesome [client generator](../create-client/index.md) able to scaffold fully working Next.js, Nuxt.js, React/Redux, Vue.js, Quasar, and Vuetify Progressive Web Apps that you can easily tune and customize. The generator also supports
-[React Native](https://facebook.github.io/react-native/) if you prefer to leverage all capabilities of mobile devices.
+[React Native](https://reactnative.dev/) if you prefer to leverage all capabilities of mobile devices.
The distribution comes with a skeleton ready to welcome the [Next.js](https://nextjs.org/) flavor of the generated code. To bootstrap your app, run:
diff --git a/distribution/testing.md b/distribution/testing.md
index a7b690752ef..c4f093e1eae 100644
--- a/distribution/testing.md
+++ b/distribution/testing.md
@@ -365,7 +365,7 @@ Running your test suite in your [CI/CD pipeline](https://en.wikipedia.org/wiki/C
The API Platform distribution is [shipped with a GitHub Actions workflow](https://github.com/api-platform/api-platform/blob/main/.github/workflows/ci.yml) that builds the Docker images, does a [smoke test](https://en.wikipedia.org/wiki/Smoke_testing_(software)) to check that the application's entrypoint is accessible, and runs PHPUnit.
-The API Platform Demo [contains a CD worklow](https://github.com/api-platform/demo/tree/main/.github/workflows) that uses [the Helm chart provided with the distribution](../deployment/kubernetes.md) to deploy the app on a Kubernetes cluster.
+The API Platform Demo [contains a CD workflow](https://github.com/api-platform/demo/tree/main/.github/workflows) that uses [the Helm chart provided with the distribution](../deployment/kubernetes.md) to deploy the app on a Kubernetes cluster.
## Additional and Alternative Testing Tools
@@ -375,7 +375,7 @@ You may also be interested in these alternative testing tools (not included in t
* [Foundry](https://github.com/zenstruck/foundry), a modern fixtures library that will replace Alice as the recommended fixtures library soon;
* [Hoppscotch](https://docs.hoppscotch.io/documentation/features/rest-api-testing/), create functional test for your API
Platform project using a nice UI, benefit from its Swagger integration and run tests in the CI using [the command-line tool](https://docs.hoppscotch.io/cli);
-* [Behat](http://behat.org), a
+* [Behat](https://behat.org), a
[behavior-driven development (BDD)](https://en.wikipedia.org/wiki/Behavior-driven_development) framework to write the API
specification as user stories and in natural language then execute these scenarios against the application to validate
its behavior;
diff --git a/extra/contribution-guides.md b/extra/contribution-guides.md
index 179a4ed1364..ac658d5c8a1 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/extra/philosophy.md b/extra/philosophy.md
index de82e01691a..308b8923b55 100644
--- a/extra/philosophy.md
+++ b/extra/philosophy.md
@@ -6,12 +6,12 @@ In 25 years of PHP, the web changed dramatically and is now evolving faster than
[full-JavaScript Progressive Web Apps](https://en.wikipedia.org/wiki/Progressive_web_application) **are becoming the standard**.
* [Internet users spend more time on their mobile devices than on desktops](https://www.broadbandsearch.net/blog/mobile-desktop-internet-usage-statistics): having a mobile-first website is mandatory and **native mobile apps are a must-have**.
* [The semantic web](https://en.wikipedia.org/wiki/Semantic_Web) and **especially [Linked Data](https://en.wikipedia.org/wiki/Linked_data)
- is a reality**: with the [Schema.org](https://schema.org/) initiative and new open web standards such as [JSON-LD](http://json-ld.org/),
+ is a reality**: with the [Schema.org](https://schema.org/) initiative and new open web standards such as [JSON-LD](https://json-ld.org/),
search engines (among a bunch of other services and software) consume structured and machine-readable data at web scale.
Not exposing such data decrease interoperability and search engine ranking/efficiency (think rich snippets).
* HTTP/2 and HTTP/3 [dramatically improve the performance of web applications](https://vulcain.rocks) thanks to multiplexing, Server Push and their other new capabilities.
-[PHP.net](https://www.php.net), [Symfony](https://symfony.com), [Facebook](http://hhvm.com/) and many others have worked hard
+[PHP.net](https://www.php.net), [Symfony](https://symfony.com), [Facebook](https://hhvm.com/) and many others have worked hard
to improve and professionalize the PHP ecosystem. The PHP world has closed the gap with most backend solutions and is often
[more innovative](https://wiki.php.net/rfc) and [faster](https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/php-python3.html) than them.
diff --git a/extra/releases.md b/extra/releases.md
index 1c78a45d218..61afdf8526a 100644
--- a/extra/releases.md
+++ b/extra/releases.md
@@ -7,7 +7,7 @@ For example:
- version 3.0 has been released on 15 September, 2022;
- version 3.1 has been released on 23 January, 2023;
-- version 3.2 will be released on September, 2023;
+- version 3.2 has been released on 12 October, 2023;
- version 3.3 will be released on March, 2024;
- versions 3.4 and 4.0 will be released on September, 2024.
@@ -16,11 +16,13 @@ For example:
3 versions are maintained at the same time:
* **stable** (currently the **3.1** branch): regular bugfixes are integrated in this version
-* **old-stable** (currently **3.0** and **2.7** branches): [security fixes](security.md) are integrated in this version, regular bugfixes are **not** backported in it
+* **old-stable** (are the last 2 minor branches: currently **3.0** and **3.1** branches): [security fixes](security.md) are integrated in this version, regular bugfixes are **not** backported in it
* **development** (**main** branch): new features target this branch
Older versions (1.x, 2.6...) **are not maintained**. If you still use them, you must upgrade as soon as possible.
+There's a [crowdfunding for a 2.7 LTS version](https://opencollective.com/api-platform/projects/27-lts).
+
The **old-stable** branch is merged in the **stable** branch on a regular basis to propagate [security fixes](security.md).
The **stable** branch is merged in the **development** branch on a regular basis to propagate [security](security.md) and regular bugfixes.
diff --git a/extra/security.md b/extra/security.md
index 2323224bf6c..df722d517fa 100644
--- a/extra/security.md
+++ b/extra/security.md
@@ -47,7 +47,7 @@ Scores from the following areas are added together to produce a score. The score
* Integrity: Does this vulnerability cause non-public data to be accessible? If so, does the attacker have control over the data disclosed? (0-4)
* Disclosure: Can this exploit allow system data (or data handled by the system) to be compromised? If so, does the attacker have control over modification? (0-4)
-* Code Execution: Does the vulnerability allow arbitrary code to be executed on an end-users system, or the server that it runs on? (0-4)
+* Code Execution: Does the vulnerability allow arbitrary code to be executed on an end users system, or the server that it runs on? (0-4)
* Availability: Is the availability of a service or application affected? Is it reduced availability or total loss of availability of a service / application? Availability includes networked services (e.g., databases) or resources such as consumption of network bandwidth, processor cycles, or disk space. (0-4)
### Affected Projects
diff --git a/extra/troubleshooting.md b/extra/troubleshooting.md
index 49c094e5882..91bc1507c2c 100644
--- a/extra/troubleshooting.md
+++ b/extra/troubleshooting.md
@@ -12,7 +12,7 @@ Docker Toolbox is not supported anymore by API Platform. Please upgrade to [Dock
If the `php` container cannot start and display this `Error starting userland proxy: Bind for 0.0.0.0:80`, it means that port 80 is already in use. You can check to see which processes are currently listening on certain ports.
-Find out if any service listens on port 80. You can use this command on UNIX-based OSes like MacOS and Linux:
+Find out if any service listens on port 80. You can use this command on UNIX-based OSes like macOS and Linux:
```console
sudo lsof -n -i :80 | grep LISTEN
@@ -28,7 +28,7 @@ You can change the port to be used in the `docker-compose.yml` file (default is
## Using API Platform and JMS Serializer in the same project
-For the latest versions of [JMSSerializerBundle](http://jmsyst.com/bundles/JMSSerializerBundle), there is no conflict so everything should work out of the box.
+For the latest versions of [JMSSerializerBundle](https://jmsyst.com/bundles/JMSSerializerBundle), there is no conflict so everything should work out of the box.
If you are still using the old, unmaintained v1 of JMSSerializerBundle, the best way would be to [upgrade to v2](https://github.com/schmittjoh/JMSSerializerBundle/blob/2.4.2/UPGRADING.md#upgrading-from-1x-to-20) of JMSSerializerBundle.
@@ -46,9 +46,9 @@ The JMS Serializer service is available as `jms_serializer`.
## "upstream sent too big header while reading response header from upstream" NGINX 502 Error
-Some of your API calls fail with a 502 error and the logs for the api container shows the following error message `upstream sent too big header while reading response header from upstream`.
+Some of your API calls fail with a 502 error and the logs for the API container shows the following error message `upstream sent too big header while reading response header from upstream`.
-This can be due to the cache invalidation headers that are too big for NGINX. When you query the API, API Platform adds the ids of all returned entities and their dependencies in the headers like so : `Cache-Tags: /entity/1,/dependent_entity/1,/entity/2`. This can overflow the default header size (4k) when your API gets larger and more complex.
+This can be due to the cache invalidation headers that are too big for NGINX. When you query the API, API Platform adds the IDs of all returned entities and their dependencies in the headers like so : `Cache-Tags: /entity/1,/dependent_entity/1,/entity/2`. This can overflow the default header size (4k) when your API gets larger and more complex.
You can modify the `api/docker/nginx/conf.d/default.conf` file and set values to `fastcgi_buffer_size` and `fastcgi_buffers` that suit your needs, like so:
diff --git a/schema-generator/configuration.md b/schema-generator/configuration.md
index 77252fdf2de..b557e52102b 100644
--- a/schema-generator/configuration.md
+++ b/schema-generator/configuration.md
@@ -30,7 +30,7 @@ types:
## Forcing a Field Type (Range)
-RDF allows a property to have several types (ranges). However, the generator allows only one type by property.
+RDF allows a property to have several types (ranges). However, the generator allows only one type per property.
If not configured, it will use the first defined type.
The `range` option is useful to set the type of a given property.
It can also be used to force a type (even if not in the RDF vocabulary definition).
@@ -518,7 +518,7 @@ types:
## Checking GoodRelation Compatibility
If the `checkIsGoodRelations` option is set to `true`, the generator will emit a warning if an encountered property is not
-par of the [GoodRelations](http://www.heppnetz.de/projects/goodrelations/) schema.
+par of the [GoodRelations](https://www.heppnetz.de/projects/goodrelations/) schema.
This is useful when generating e-commerce data models.
diff --git a/schema-generator/getting-started.md b/schema-generator/getting-started.md
index 5dbed0d76b0..bcd90806cbc 100644
--- a/schema-generator/getting-started.md
+++ b/schema-generator/getting-started.md
@@ -129,7 +129,7 @@ Browse [the configuration documentation](configuration.md).
The Cardinality Extractor is a standalone tool (also used internally by the generator) extracting a property's cardinality.
It extracts cardinality described with the [Web Ontology Language (OWL)](https://en.wikipedia.org/wiki/Web_Ontology_Language) vocabulary
-or in [GoodRelations](http://www.heppnetz.de/projects/goodrelations/).
+or in [GoodRelations](https://www.heppnetz.de/projects/goodrelations/).
When cardinality cannot be automatically extracted, its value is set to `unknown`.
Usage:
diff --git a/schema-generator/index.md b/schema-generator/index.md
index 1cfd20e42e8..7b89930668a 100644
--- a/schema-generator/index.md
+++ b/schema-generator/index.md
@@ -1,6 +1,6 @@
# The Schema Generator
-`schema` is a command line tool part of [the API Platform framework](https://api-platform.com) that instantly generates a set
+`schema` is a command-line tool part of [the API Platform framework](https://api-platform.com) that instantly generates a set
of PHP classes from [RDF](https://en.wikipedia.org/wiki/Resource_Description_Framework) vocabularies such as (but not limited to)
[Schema.org](https://schema.org) or [ActivityStreams](https://www.w3.org/TR/activitystreams-core/).
Alternatively, it can generate PHP classes from an [OpenAPI](https://www.openapis.org/) documentation.
@@ -14,7 +14,7 @@ You get a fully featured PHP data model including:
* A set of PHP entities with properties, constants (enum values), getters, setters, adders and removers. The class
hierarchy provided by the vocabulary will be translated to a PHP class hierarchy with parents as `abstract` classes.
-The generated code complies with [PSR](http://www.php-fig.org/) coding standards;
+The generated code complies with [PSR](https://www.php-fig.org/) coding standards;
* Full, high-quality PHPDoc and type declarations for classes, properties, constants and methods extracted from the vocabulary;
* Doctrine ORM or MongoDB ODM attributes mapping including database columns / fields with type guessing, relations with cardinality guessing,
smart class inheritance (through the `#[MappedSuperclass]` or `#[InheritanceType]` attributes depending on if the resource is used in a relation);
@@ -31,7 +31,7 @@ Bonus:
and a custom generator can be added;
* The code generator can load previously generated files and add new changes while keeping the user-added ones;
* The generated code can be used as is in a [Symfony](https://symfony.com) app (but it will work too in a raw PHP project
-or any other framework including [Laravel](https://laravel.com) and [Zend Framework](http://framework.zend.com/)).
+or any other framework including [Laravel](https://laravel.com) and [Zend Framework](https://framework.zend.com/)).
## What Is Schema.org?
@@ -62,7 +62,7 @@ specific mapping nor adaptation. It's a matter of minutes.
### Be Ready for The Future
-Schema.org improves the interoperability of your applications. Used with hypermedia technologies such as [Hydra](http://www.hydra-cg.com/)
+Schema.org improves the interoperability of your applications. Used with hypermedia technologies such as [Hydra](https://www.hydra-cg.com/)
it's a big step towards the semantic and machine-readable web.
It opens the way to generic web API clients able to extract and process data from any website or app using such technologies.