0c1c1c36f fix(symfony): enable API Platform in LexikJWTAuthenticationBundle (#5609)
You can disable this behaviour by setting the configuration key lexik_jwt_authentication.api_platform.enabled to false
146991ba4 fix(openapi): merge parameters with deprecated openApiContext (#5703)
14969aa0c fix(serializer): put replaces embed collection (#5604)
9cb0ee43c fix(metadata): missing xml/yaml properties (#5684)
a8796238d fix: filters don’t have to implement the “legacy” FilterInterface (#5619)
ada115966 fix: don’t implement deprecated CacheableSupportsMethodInterface with Symfony 6.3+ (#5696)
b8cbdb1cb fix(doctrine): search on nested sub-entity that doesn’t use “id” as its ORM identifier (#5623)
e21e9faee fix(symfony): support for custom controller with class method (#5681)
Also updates: graphiql, opensans
Notes:
#5473 changes the priority of the ApiPlatform\Symfony\EventListener\QueryParameterValidateListener from 16 to 2 so that it occurs after the security listener.
ReflectionEnum was removed as it was causing segfaults with opcache preload and an unidentified PHP extension
#5459 fixes the defaults operation declaration such as:
defaults:
- ApiPlatform\Metadata\Get
- ApiPlatform\Metadata\GetCollectionvery useful for read only APIs, this was possible in 2.7 but not backported correctly
swagger.api_keys with a key to handle multiple authorizations (#4691)Get, Query, Operation, ApiProperty etc.) as we don’t guarantee the backward compatibility on positional argumentspaginationViaCursor was removed from GraphQl operations as it had no behaviorLink::toProperty (#5352)genId: false to disable BC_api_exception_to_status leftovers (#4992)ResourceAccessChecker::__construct() (#4905)Resources/config/api_resources to config/api_resources (#4853)src/ApiResource/ is the recommended place for API models (#4874)Various cleanup in services and removal of backward compatibility layer.
api_jsonld_context route format (#4844)ApiPlatform\OpenApi\Model\Parameter BCVarious cleanup, removed Core namespace leftovers and todos.
ApiPlatform\Symfony\Security\ExpressionLanguage has been removed in favor of Symfony\Component\Security\Core\Authorization\ExpressionLanguage.Breaking changes:
string $operationName got removed in favor of ApiPlatform\Metadata\Operation $operation. (#4779)ContextAware interfaces were merged with their child interfaces you can safely remove them (#4779)Core namespace got removed (#4805)Stringableskip_null_values now defaults to truePatch is added to the automatic CRUD@final annotation from filters and mark them as finalarray cast for RDF types in ApiResource & ApiProperty constructors (#5000)false (#4880)$exceptionOnNoToken parameter in ResourceAccessChecker::__construct() (#4900)Various cs fixes and PHPDoc to help upgrading to 3.0.
previous_data to the context (#4776)BC
Doctrine: new interfaces for Filters and Extensions ready, switch to the ApiPlatform\Doctrine namespace after fixing your deprecations: (#4779)
ApiPlatform\Core\Bridge\Doctrine\Orm\Extension interfaces have an Operation instead of the $operationName, the new namespace is ApiPlatform\Doctrine\Orm\ExtensionApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension interfaces have an Operation instead of the $operationName, the new namespace is ApiPlatform\Doctrine\Odm\Extensioniri: false (#4731)getIriFromResource and getResourceFromIri (#4734)ApiPlatform\Metadata\Operation instead of operationName (#4712)CollectionOperationInterface instead of the collection flag (#4712)DeleteOperationInterface instead of the delete flag (#4712)compositeIdentifier flag only lives under the uriVariables property (#4712)provider or processor property is specified within the Operation and we removed the chain pattern (#4712)usePkceWithAuthorizationCodeGrant to Swagger UI initOAuth (#4649)mapping.paths in configuration should override bundles configuration (#4465)ApiProperty security attribute expression being passed a class string for the object variable on updates/creates - null is now passed instead if the object is not available (#4184)ApiProperty now supports a security_post_denormalize attribute, which provides access to the object variable for the object being updated/created and previous_object for the object before it was updated (#4184)make:data-provider and make :data-persister commands to generate a data provider / persister (#3850)api_platform.listener.request.add_format priority from 7 to 28 to execute it before firewall (priority 8) (#3599)@final annotation in ORM filters (#4109)exception_to_status per operation (#3519)nulls_always_first and nulls_always_last to nulls_comparison in order filter (#4103)order_nulls_comparison configuration (#3117)date_immutable support (#3940)TraversablePaginator (#3783)swagger_ui_extra_configuration to Swagger / OpenAPI configuration (#3731)$data thanks to an argument resolver (#3263)ApiProperty security (#4143)item_query security is no longer used. ApiProperty security can now be used to secure collection (or any other) properties. (#4143)allow_plain_identifiers option (#4167)_format resolving (#4292)ApiPlatform\Metadata instead of ApiPlatform\Core\Metadata, for example ApiPlatform\Metadata\ApiResource (#4351)ApiPlatform\Core\Annotation (#4351)ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface is deprecated in favor of ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface (#4351)ApiPlatform\Core\Api\OperationType class (#4351)ApiPlatform\Metadata\GraphQl follow the same metadata conventions (a Subscription operation is available and isn’t hidden behind an update Mutation anymore), interfaces got simplified (being @experimental) (#4351)ApiPlatform\Bridge\Symfony\Routing\IriConverter that adds an operationName, same for ApiPlatform\Api\IdentifiersExtractor (#4351)ApiPlatform\State\ProviderInterface that replaces DataProviders (#4351)ApiPlatform\State\ProcessorInterface that replaces DataPersisters (#4351)metadata_backward_compatibility_layer (defaults to false) (#4351)security_post_validation attributeClient::loginUser() (#4588)ApiPlatform\Core\HttpCache\PurgerInterface is deprecated in favor of ApiPlatform\HttpCache\PurgerInterface, new purger that uses PURGE (#4695)SplFileInfo class as a binary type (#4332)collectionKeyType for building JSON Schema (#4385)REMOTE_ADDR support in ApiTestCase (#4446)asset_package for all assets (#4470)@context property possible types (#4223)to thehydra:view` schema properties (#4310)response without content in the openapi_context (#4210)SchemaFactory::buildSchema() is now immutable as it no longer modifies the passed $schema)FieldsBuilder not fully unwrapping nested types before deciding if a resolver is needed (#4251)BAN regex performance (#4231)withOptions() to our HttpClient implementation (#4282)response support via the openapi_context (#4116)Link->requestBody default value (#4116)defaults.order as collection.order (#4178)pagination_use_output_walkers and pagination_fetch_join_collection for operations (#3311)psr/cache version 2 and 3 (#4117)POST operations even if no identifier is defined (#4052)hydra:next property (#4015)NullToken when using the new authenticator manager in the resource access checker (#4067)isActive and method isActive) (#4064)$ref when no type is used in context (#4076)ALLOW_EXTRA_ATTRIBUTE=false as it is a BC break and will be done in 3.0 instead see #3881 (#4007)requestBody and parameters via the openapi_context (#4001), make openapi_context work on subresources (#4004), sort paths (#4013)max_header_length configuration (#2865)stale-while-revalidate and stale-if-error cache control headers (#3439)ApiPlatform\Core\DataTransformer\DataTransformerInitializerInterface to pre-hydrate inputs (#3701)previous_data to the context passed to persisters when available (#3752)ResumableDataPersisterInterface that allows to call multiple persisters (#3912)asset_package configurable (#3764)Paginator class constructor now receives the denormalization context to support denormalizing documents using serialization groups. This change may cause potential BC breaks for existing applications as denormalization was previously done without serialization groups.order: [{foo: 'asc'}, {bar: 'desc'}] (#3468)operation is now operationName to follow the standard (#3568)paginationType is now pagination_type (#3614)iri_only attribute to simplify documents structure (useful when using Vulcain) (#3275)ApiPlatform\Core\Exception\ErrorCodeSerializableInterface (#2922)normalization_context option in mercure attribute (#3772)InheritedPropertyMetadataFactory (#3273)@Ignore annotation (#3820)id as default identifier if none provided (#3874)allowDiskUse (#3144)[a-zA-Z0-9\.\-_] to . in definition names to be compliant with OpenAPI 3.0 (#3669)url_generation_strategy (#3198)ApiResource attribute (#3436)resourceClass can now be defined as a container parameter in XML and YAML definitionsItemNormalizer without Symfony SecurityBundle (#3801)getCookieJartest.api_platform.client service when the FrameworkBundle bundle is registered after the ApiPlatformBundle bundle (#3928)exception_to_status to fallback to 400 if needed (#3808)ApiPlatform\Core\Validator\ValidationGroupsGeneratorInterfaceApiPlatform\Core\Bridge\Symfony\Validator\ValidationGroupsGeneratorInterface (#3346)ExceptionInterface now extends \Throwable (#3217)hydra:next when the item total is strictly greater than the number of items per page (#3967)AbstractPaginator class (#3827)additionalProp1 from showing in example values (#3888)hydra:mapping properties as nullable (#3877)@type from collection using output DTOs (#3699)PurgeHttpCacheListener performances (#3743)VarnishPurger max header length (#3843)SwaggerCommand (#3802)RegexFilter (#3755)For compatibility reasons with Symfony 5.2 and PHP 8, we do not test anymore the integration with these legacy packages:
Cache-Control HTTP header can be private (#3543)ManagerRegistry class (#3684)setParameter of the SearchFilter (#3331)\Traversable resources (#3463)hydra:writable => hydra:writeable (#3481)hydra:next only when it’s available (#3457)ValidationException instead of Symfony’s (#3414)before or after (#3360)ResourceClassResolver::getResourceClass()SearchFilterhasNextPage when offset > itemsPerPageApiResource::$paginationPartialAbstractItemNormalizer::normalizeRelationSerializerContextBuilder@ApiFilter annotation404 HTTP status code instead of 500 whe the identifier is invalid (e.g.: invalid UUID)@ApiResource annotation’s attributes to improve DXfilter query parameterbody parameter if it already existsoauth2-redirect configurationSecurityBundle was not installedfetchaccess_controlitem_query and collection_query typesMyTypeItem and MyTypeCollection) only if serialization groups are different for item_query and collection_query (#3083)maximum_items_per_page attribute consistent with other attributes controlling paginationmerge-patch+json format to enable PATCH support. This will be the default behavior in API Platform 3.api:json-schema:generate (#2996)ApiPlatform\Core\JsonSchema\SchemaFactoryInterface (#2983)access_control by security and adds a security_post_denormalize attribute (#2992)exists[property], old syntax still supported see #2243, fixes its behavior on GraphQL (also related #2640).cacheHeaders attributes of a resource (#2758)swagger.versions and deprecates the enable_swagger configuration option (#2998)asc/desc as enum (#2971)query resource operation attribute into item_query and collection_query operations so user can use different security and serialization groups for them (#2944, #3015)api:graphql:export > schema.graphql (#2600)serialize PHP function (#2576)TypeConverter to manage custom types, SerializerContextBuilder to modify the (de)serialization context dynamically, etc.) (#2772)Notes:
Please read #2825 if you have issues with the behavior of Readable/Writable Link
remove methodPaginationEntityManagerInterface is used in data providersprevious_dataContent-Type is sentWriteListener trying to generate IRI for non-resourcesprevious_data request attribute, and allow to access it in security expressions using the previous_object variable (useful for PUT and PATCH requests)AbstractItemNormalizer introduced in 2.4Doctrine: allow autowiring of filter classes
Doctrine: don’t use fetchJoinCollection on Paginator when not needed
Doctrine: fix a BC break in OrderFilter
GraphQL: input objects aren’t nullable anymore (compliance with the Relay spec)
Cache: Remove some useless purges
Mercure: publish to Mercure using the default response format
Mercure: use the Serializer context
OpenAPI: fix documentation of the PropertyFilter
OpenAPI: fix generation of the servers block (also fixes the compatibility with Postman)
OpenAPI: skip not readable and not writable properties from the spec
OpenAPI: add the id path parameter for POST item operation
Serializer: add support for Symfony Serializer’s @SerializedName metadata
Metadata: ApiResource’s attributes property now defaults to null, as expected
Metadata: Fix identifier support when using an interface as resource class
Metadata: the HTTP method is now always uppercased
Allow to disable listeners per operation (fix handling of empty request content)
Previously, empty request content was allowed for any POST and PUT operations. This was an unsafe assumption which caused other problems.
If you wish to allow empty request content, please add "deserialize"=false to the operation’s attributes. For example:
<?php
// api/src/Entity/Book.php
use ApiPlatform\Core\Annotation\ApiResource;
use App\Controller\PublishBookAction;
/**
* @ApiResource(
* itemOperations={
* "put_publish"={
* "method"="PUT",
* "path"="/books/{id}/publish",
* "controller"=PublishBookAction::class,
* "deserialize"=false,
* },
* },
* )
*/
class Book
{You may also need to add "validate"=false if the controller result is null (possibly because you don’t need to persist the resource).
Return the 204 HTTP status code when the output class is set to null
Be more resilient when normalizing non-resource objects
Replace the data request attribute by the return of the data persister
Fix error message in identifiers extractor
Improve the bundle’s default configuration when using symfony/symfony is required
Fix the use of MetadataAwareNameConverter when available (configuring name_converter: serializer.name_converter.metadata_aware will now result in a circular reference error)
FilterEagerLoadingExtensionNoOpScalarNormalizer handling scalar valuesapi_platform.metadata_cache parameterSearchFilterwebonyx/graphql-php is not installedDISTINCT is not used when there are no joinselasticsearch attribute can be disabled resource-wise or per-operationmessenger attribute can now take the input string as a value (messenger="input"). This will use a default transformer so that the given input is directly sent to the messenger handler.messenger attribute can be declared per-operationkernel.terminate, so the Mercure and the Messenger integration can be used together<0) for improved compatibility with Symfony’s autoconfiguration feature. If you have custom extensions we recommend to use positive priorities.| Service name | Old priority | New priority | Class |
|---|---|---|---|
| api_platform.doctrine.orm.query_extension.eager_loading (collection) | -8 | ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\EagerLoadingExtension | |
| api_platform.doctrine.orm.query_extension.eager_loading (item) | -8 | ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\EagerLoadingExtension | |
| api_platform.doctrine.orm.query_extension.filter | 32 | -16 | ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\FilterExtension |
| api_platform.doctrine.orm.query_extension.filter_eager_loading | -17 | ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\FilterEagerLoadingExtension | |
| api_platform.doctrine.orm.query_extension.order | 16 | -32 | ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\OrderExtension |
| api_platform.doctrine.orm.query_extension.pagination | 8 | -64 | ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\PaginationExtension |
endCursor behavior was wrong)clientMutationId nullable and return mutation payload as an object)_api_respond request attribute in the SerializeListener< 0). If you have custom normalizer we recommend to use positive priorities.| Service name | Old priority | New priority | Class |
|---|---|---|---|
| api_platform.hydra.normalizer.constraint_violation_list | 64 | -780 | ApiPlatform\Core\Hydra\Serializer\ConstraintViolationListNormalizer |
| api_platform.jsonapi.normalizer.constraint_violation_list | -780 | ApiPlatform\Core\JsonApi\Serializer\ConstraintViolationListNormalizer | |
| api_platform.problem.normalizer.constraint_violation_list | -780 | ApiPlatform\Core\Problem\Serializer\ConstraintViolationListNormalizer | |
| api_platform.swagger.normalizer.api_gateway | 17 | -780 | ApiPlatform\Core\Swagger\Serializer\ApiGatewayNormalizer |
| api_platform.hal.normalizer.collection | -790 | ApiPlatform\Core\Hal\Serializer\CollectionNormalizer | |
| api_platform.hydra.normalizer.collection_filters | 0 | -790 | ApiPlatform\Core\Hydra\Serializer\CollectionFiltersNormalizer |
| api_platform.jsonapi.normalizer.collection | -790 | ApiPlatform\Core\JsonApi\Serializer\CollectionNormalizer | |
| api_platform.jsonapi.normalizer.error | -790 | ApiPlatform\Core\JsonApi\Serializer\ErrorNormalizer | |
| api_platform.hal.normalizer.entrypoint | -800 | ApiPlatform\Core\Hal\Serializer\EntrypointNormalizer | |
| api_platform.hydra.normalizer.documentation | 32 | -800 | ApiPlatform\Core\Hydra\Serializer\DocumentationNormalizer |
| api_platform.hydra.normalizer.entrypoint | 32 | -800 | ApiPlatform\Core\Hydra\Serializer\EntrypointNormalizer |
| api_platform.hydra.normalizer.error | 32 | -800 | ApiPlatform\Core\Hydra\Serializer\ErrorNormalizer |
| api_platform.jsonapi.normalizer.entrypoint | -800 | ApiPlatform\Core\JsonApi\Serializer\EntrypointNormalizer | |
| api_platform.problem.normalizer.error | -810 | ApiPlatform\Core\Problem\Serializer\ErrorNormalizer | |
| serializer.normalizer.json_serializable | -900 | -900 | Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer |
| serializer.normalizer.datetime | -910 | -910 | Symfony\Component\Serializer\Normalizer\DateTimeNormalizer |
| serializer.normalizer.constraint_violation_list | -915 | Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer | |
| serializer.normalizer.dateinterval | -915 | -915 | Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer |
| serializer.normalizer.data_uri | -920 | -920 | Symfony\Component\Serializer\Normalizer\DataUriNormalizer |
| api_platform.graphql.normalizer.item | 8 | -922 | ApiPlatform\Core\GraphQl\Serializer\ItemNormalizer |
| api_platform.hal.normalizer.item | -922 | ApiPlatform\Core\Hal\Serializer\ItemNormalizer | |
| api_platform.jsonapi.normalizer.item | -922 | ApiPlatform\Core\JsonApi\Serializer\ItemNormalizer | |
| api_platform.jsonld.normalizer.item | 8 | -922 | ApiPlatform\Core\JsonLd\Serializer\ItemNormalizer |
| api_platform.serializer.normalizer.item | 0 | -923 | ApiPlatform\Core\Serializer\ItemNormalizer |
| serializer.normalizer.object | -1000 | -1000 | Symfony\Component\Serializer\Normalizer\ObjectNormalizer |
name and iri if needed)falsy boolean to disable the input/output0 limit in the paginationinput_class and output_class attributesinput_class and output_class to falsecache_headers attributestatus attributeSunset HTTP header using the sunset attributeContent-Location and Location headers when appropriate for better RFC7231 conformanceapi_persist request attribute to enable or disable the WriteListenerOptimisticLockException is thrownRequestAttributesExtractor is not internal anymore and can be used in userland codeshow_webby configuration option to hide the spider in API docswebonyx/graphql-php 0.13properties[] as a collection parameterproperties[] filterItemNormalizer when $context['resource_class'] is not definedDEFERRED_EXPLICIT change tracking policyInvalidArgumentException when trying to get an item from a collection routeroute_prefix attribute in subresourcesNumericFilterReadListener by adding the previous exception_id when id is not part of the requested fieldsOrderFilter when applied on nested entities@ApiResource and @ApiProperty annotationsaccess_control_message attribute--output option to the api:swagger:export commandCacheableSupportsMethodInterface introduced in Symfony 4.1 in all (de)normalizers (improves the performance dramatically)totalCount field in GraphQL paginated collectionsExistsFilter for inverse side of OneToOne associationFilterEagerLoadingExtension now accepts joins with class name as join valueApiPlatform\Core\EventListener\EventPriorities’s PRE_SERIALIZE and POST_SERIALIZE constantsenable_max_depth if definedExistFilter to work properly with GraphQLChainSubresourceDataProvider to take into account RestrictedDataProviderInterfacePOST request to have an empty bodyIriConverterLink HTTP header pointing to the Hydra documentation if docs are disabledOrderFilter to trigger faulty deprecation noticesfetchEager=false directive on an association in the EagerLoadingExtensionItemNormalizerConstraintViolationListNormalizerCachedRouteNameResolver and CachedSubresourceOperationFactory by adding a local memory cache layerisResourceClass when possibletry/catch in the CachedTraitIriConverterChainSubresourceDataProvider class to take into account RestrictedDataProviderInterfaceFilterEagerLoadingExtension with manual joins@ApiFilter annotations on the same classSubresourceDataProviderInterfaceDateTimeImmutable support in the date filterDocumentationAction impacting NelmioApiDoc@ApiFilter annotation to directly configure filters from resource classesCOUNT() SQL queriesallow_plain_identifiers option to allow using plain IDs as identifier instead of IRIsAbstractCollectionNormalizer to help supporting custom formatsApiPlatform\Core\Bridge\Doctrine\EventListener\WriteListener class in favor of the new ApiPlatform\Core\EventListener\WriteListener class.api_platform.doctrine.listener.view.write event listener service.ApiPlatform\Core\DataPersister\DataPersisterInterface interface.access_control_message attributePOST HTTP request0 items per page in collectionsHost from the Symfony RouterPaginator::getLastPage() now always returns a floatowl:allValuesFrom in the API documentationnullPriorityTaggedServiceTrait provided by Symfony instead of a custom implementation/posts/1/comments or /posts/1/comments/2RequestAttributesExtractorFilterCollection classpagination and itemPerPage parameters in the Swagger/Open API documentationResource-md5($groups) => Resource-groupa_groupb) - see https://github.com/api-platform/core/pull/1207hydra_context option take precedence over operation metadataItemNormalizer (raw JSON, XML)#ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter::extractProperties now always return an arrayLEFT JOIN clause for filter associations\Traversable valuesdeclare(strict_types=1) and improve coding standardsConstraintViolationListeach() (deprecated since PHP 7.2)EagerLoadingExtensionItemDataproviderInterface: fetchData is now in the context parameterer. getItemFromIri is now context aware 7f82fd7start and word_start strategies to the Doctrine Search filter/apidoc (was /vocab)Dunglas\ApiBundle\Exception\ExceptionInterfaceapi_getId() was always used)Dunglas\ApiBundle\Doctrine\Orm\DataProvider allowing to customize Doctrine paginator and performance optimization when using typical queriesDunglas\ApiBundle\JsonLd\Event\Events::CONTEXT_BUILDER event allowing to modify the JSON-LD context202 to 200 for PUT requestsDoctrine\Orm\Filter\OrderFilter instanceYou can also help us improve the documentation of this page.
Made with love by
Les-Tilleuls.coop can help you design and develop your APIs and web projects, and train your teams in API Platform, Symfony, Next.js, Kubernetes and a wide range of other technologies.
Learn more