api-platform/core
API Platform Core lets you quickly build hypermedia-driven REST and GraphQL APIs in PHP/Symfony. Supports JSON-LD, Hydra, OpenAPI v2/v3, JSON:API, HAL, and RFC7807. Extensible, high-performance, API-first.
ResourceClassInfoTrait::isResourceClass() is always true (#7924)SkipAutoconfigure attribute (#7467)[@type](https://github.com/type) with output and itemUriTemplate: When using output with itemUriTemplate on a collection operation, the JSON-LD [@type](https://github.com/type) now uses the resource class name instead of the output DTO class name for semantic consistency with itemUriTemplate behavior. Update any client code that relies on the DTO class name in [@type](https://github.com/type).property (#7681): Doctrine parameter-based filters (ExactFilter, IriFilter, PartialSearchFilter, UuidFilter) now throw InvalidArgumentException if the property attribute is missing. If you have filter parameters without an explicit property, you must either add one or use the :property placeholder in your parameter name.$classMetadata->markReadOnly()) will no longer expose PUT and PATCH operations. Clients sending PUT/PATCH to these resources will receive a 404. If you need write operations on readonly entities, explicitly define them in your ApiResource attribute.[@id](https://github.com/id) now always uses #ShortName (#7771): Hydra documentation classes now consistently use #ShortName as their [@id](https://github.com/id) instead of schema.org type URIs (e.g. schema:Product). This resolves class identifier collisions when multiple resources shared the same semantic type, which previously caused api-doc-parser conflation. Semantic types configured via types are now exposed through rdfs:subClassOf. Clients should expect class [@id](https://github.com/id) and property range changes in the Hydra documentation if resources had custom types configured.isGranted evaluated before provider (#7500): Security expressions are now evaluated before the state provider runs. Expressions that do not reference the object variable will be checked earlier (at the pre_read stage), improving security by preventing unnecessary database queries on unauthorized requests. Expressions that reference object still wait for the provider to resolve the entity. Review any security expressions that relied on provider side-effects running before authorization.Allow and Accept-Post headers per the Linked Data Platform specification. These are informational headers that help clients discover API capabilities and should not break existing integrations.?ui=scalar. To disable it, set enable_scalar: false in your API Platform configuration.% or _ in search filter (#7653)stale-while-revalidate and stale-if-error cache headers via config file (#7606)[@id](https://github.com/id) and [@type](https://github.com/type) properties required only in the JSON-LD schema for output (#7397)KernelBrowser::loginUser() (#7446)pagination_maximum_items_per_page same as Laravel version (#7396)Also includes v4.1.25 bug fixes
Parameters (#7492)member property out of HydraCollectionBaseSchema (#7456)mixed properties to string|null instead of null (#7489)Also includes patches from v4.1.24 and v4.2.0-alpha fixes
partial query parameter to OpenAPI when pagination_client_enabled is true (#7295)Link (#7342)#[ApiResource] attribute (#6943)JSON Streamer:
Object Mapper:
TypeInfo:
TypeInfo's Type (#7099)Type of TypeInfo instead of PropertyInfo (#6979)TypeInfo type (#7098)TypeInfo's Type (#7096)TypeInfo's Type (#7101)TypeInfo's Type (#7100)TypeInfo type (#7097)partial query parameter to OpenAPI when pagination_client_enabled is true (#7295)Link (#7342)#[ApiResource] attribute (#6943)JSON Streamer:
Object Mapper:
TypeInfo:
TypeInfo's Type (#7099)Type of TypeInfo instead of PropertyInfo (#6979)TypeInfo type (#7098)TypeInfo's Type (#7096)TypeInfo's Type (#7101)TypeInfo's Type (#7100)TypeInfo type (#7097)Introducing new Symfony components!
#[ApiResource] attribute (#6943)Object Mapper:
TypeInfo:
TypeInfo's Type (#7099)Type of TypeInfo instead of PropertyInfo (#6979)TypeInfo type (#7098)TypeInfo's Type (#7096)TypeInfo's Type (#7101)TypeInfo's Type (#7100)TypeInfo type (#7097)#[ApiResource] attribute (#6943)TypeInfo's Type (#7100)TypeInfo type (#7097)TypeInfo's Type (#7099)Type of TypeInfo instead of PropertyInfo (#6979)TypeInfo type (#7098)TypeInfo's Type (#7096)TypeInfo's Type (#7101)ParameterExtension context more generic (#7389)Laravel compatibility with api-platform/http-cache:
Link (#7342)partial query parameter to OpenAPI when pagination_client_enabled is true (#7295)InputOption::VALUE_REQUIRED) (#7266)[@id](https://github.com/id) property when genId is false (#7162) (#7251)LinksHandler to handle polymorphic relationships (#7231)Notes:
Two providers are now available on parameters (query parameters, header and uri variables Link):
ReadLinkParameterProvider previously used for link security (renamed from Symfony\Security\State\LinkedReadProvider)IriConverterParameterProvider this allows you to read a resource from an IRI usefull for filters (eg ?author=/authors/1)Previous tests on link security were left untouched we removed the experimental class Symfony\Security\State\LinkAccessCheckerProvider as well as the LinkedReadProvider as they're not used anymore.
There was an issue with the subtree split as we attempted to test lower dependencies on the subtree split, some components where wrongly tagged.
The proper fix is at: https://github.com/api-platform/core/pull/7196
example and default with nullable value not being shownalwaysBootKernel property for BC layer (#7007)Also contains v4.0.20 changes.
The hydra patch changes default hydra:title and uses the resource shortname. Previously the hydra:title information was duplicating the hydra:description.
The rdfs:label got removed from the hydra:Class as it was used instead of the hydra:title.
On hydra:property rdfs:label got renamed to label as the rdfs namespace is available in the context.
The ApiPlatform\Metadata\ErrorResource and the ConstraintViolation (ValidationException class) are now generated directly from your PHP classes, only our ConstraintViolationList is hard-written and documents the ConstraintViolation::violation property. Therefore, your own error resources are also documented. On top of that, we now set the rdfs:subClassOf to hydra:Error.
#[ApiProperty(hydra: false)] allows you to skip a documented hydra:supportedProperty on a class.
On write operations, we added the expectsHeader field.
show_webby parameter in Laravel config (#6741)show_webby parameter in Laravel config (#6741)AggregationBuilder::execute() (#6933)Also contains v3.4.6 changes.
195c4e788 fix(hydra): hydra context changed (#6710)
4f65ef2d0 fix(metadata): providing parameter constraints skips automatic ones (#6756)
5a8ef115a fix(symfony): ECMA-262 pattern with RegExp validator (#6733)
67c5a2a24 fix(laravel): jsonapi error serialization (#6755)
ac6f667f3 fix(laravel): collection relations other than HasMany (#6737)
cecd77149 feat(laravel): use laravel cache setting (#6751)
Notes:
standard_put=true is now the default, you can set it to false using extra_properties.defaults
To save some time during cache warmup we recommend to define uri variables such as: uriVariables: ['id']. More details at #6954.
Also contains v3.4.15 changes.
Also contains v3.4.14 changes.
Also contains v3.4.10 changes.
Also contains v3.4.9 changes.
af66075fd fix(laravel): fix foregin keys (relations) beeing in attributes (#6843)
2d59c6369 feat(laravel): belongs to many relations (#6818)
Also contains v3.4.8 changes.
Also contains v3.4.7 changes.
Parameter::getValue() now takes a default value as argument getValue(mixed $default = new ParameterNotFound()): mixedParametes::get(string $key, string $parameterClass = QueryParameter::class) (but also has and remove) now has a default value as second argument to QueryParameter::classproperty, fixed by using the key insteadopenapiContext in #[ApiProperty] (#6910)I mispublished a v3.4.13 on some repositories to fix them all I bumped 3.4.10 to 3.4.14 More details at #6888.
Namespaces like ApiPlatform/Api or ApiPlatform/Util are deprecated and will be removed in 4.0.
You should now install api-platform/symfony instead of api-platform/core.
Various fixes for components isolation.
Namespaces like ApiPlatform/Api or ApiPlatform/Util are deprecated and will be removed in 4.0.
You should now install api-platform/symfony instead of api-platform/core.
Namespaces like ApiPlatform/Api or ApiPlatform/Util are deprecated and will be removed in 4.0.
You should now install api-platform/symfony instead of api-platform/core.
Namespaces like ApiPlatform/Api or ApiPlatform/Util are deprecated and will be removed in 4.0.
You should now install api-platform/symfony instead of api-platform/core.
Read the upgrade guide for detailed steps.
Various fixes for components isolation.
These are enhancement to the experimental Parameter feature:
Notes:
The patch at #6426 introduces a new validateAfterResolver option to mitigate the BC-break introduced in 3.3 that does the validation before calling the resolver:
new Mutation(
resolver: 'app.graphql.mutation_resolver.activity_log',
name: 'create',
validateAfterResolver: true,
validate: false
)
You can remove the event_listeners_backward_compatibility_layer flag and set use_symfony_listeners instead. The use_symfony_listeners should be true if you use controllers or if you rely on Symfony event listeners. Note that now flags like read can be forced to true if you want to call a Provider even on POST operations. These are the rules we set up on runtime if no value has been set:
if (null === $operation->canValidate()) {
$operation = $operation->withValidate(!$request->isMethodSafe() && !$request->isMethod('DELETE'));
}
if (null === $operation->canRead()) {
$operation = $operation->withRead($operation->getUriVariables() || $request->isMethodSafe());
}
if (null === $operation->canDeserialize()) {
$operation = $operation->withDeserialize(\in_array($operation->getMethod(), ['POST', 'PUT', 'PATCH'], true));
}
Previously listeners did the checks before reading our flags and you could not force the values.
When using GraphQl, with event_listeners_backward_compatibility_layer: true, mutation resolver gets called before validation, when using false (the future default) validation occurs on the user's input.
The v3.3.0-beta.1 introduces a new QueryParameter attribute to improve the filtering system.
Components:
api-platform/parametervalidatorapi-platform/doctrine-commonapi-platform/doctrine-ormapi-platform/doctrine-odmA new interface ApiPlatform\Serializer\TagCollectorInterface allows to collect cache tags (IRIs) during serialization instead of using API Platform defaults.
An experimental feature (#5290) gives the ability to use security on sub resource links.
If you use controllers you should use:
api_platform:
use_symfony_listeners: true
The default is false you can get rid of the event_listeners_backward_compatibility_layer flag. You can now force an operation state, for example:
<?php
#[Delete(validate: true)]
#[Post(read: true)]
class Book {}
These namespaces are deprecated:
ApiPlatform\ApiApiPlatform\ExceptionApiPlatform\ProblemApiPlatform\ActionApiPlatform\UtilMost of the classes have moved to ApiPlatform\Metadata.
If a format is not specified in either the global configuration or the outputFormats of an operation, you'll get a 406 Not Acceptable error:
api_platform:
formats:
jsonld: ['application/ld+json']
form: ['multipart/form-data']
Symfony 7 support.
To have errors backward compatible with 3.1, use:
api_platform:
defaults:
extra_properties:
rfc_7807_compliant_errors: false
New extension points are available using Errors with rfc_7807_compliant_errors: true such as Error provider and Error Resource
Note:
extra_properties.skip_deprecated_exception_normalizers is set to false so that decorating Error normalizers works. Set it to true to avoid deprecations and decorate the corresponding ItemNormalizer instead.
For OpenAPI 3.0, the spec_version=3.0.0 query parameter will force OpenAPI to the 3.0 version. This option is also available through the command line.
Notes:
ApiPlatform\Api got moved to ApiPlatform\MetadataNotes:
assertMercureUpdateMatchesJsonSchema(Update $update, array $topics, array|object|string $jsonSchema = '', bool $private = false, string $id = null, string $type = null, int $retry = null, string $message = '')Use composer recipes:update to update your configuration file. The default configuration file is:
api_platform:
title: Hello API Platform
version: 1.0.0
formats:
jsonld: ['application/ld+json']
docs_formats:
jsonld: ['application/ld+json']
jsonopenapi: ['application/vnd.openapi+json']
html: ['text/html']
defaults:
stateless: true
cache_headers:
vary: ['Content-Type', 'Authorization', 'Origin']
extra_properties:
standard_put: true
rfc_7807_compliant_errors: true # this will be the default value in 4.x
event_listeners_backward_compatibility_layer: false # use symfony event listeners
keep_legacy_inflector: false # use doctrine/inflector
Listeners will not get removed in API Platform 4 but will rather use our new Providers and Processors. You can now force the request to go through a particular state for example:
#[Post(read: true)] // to force reading even though it's a POST
ApiPlatform\Api got moved to ApiPlatform\Metadata
Adds assertMercureUpdateMatchesJsonSchema(Update $update, array $topics, array|object|string $jsonSchema = '', bool $private = false, string $id = null, string $type = null, int $retry = null, string $message = '')
The handle links feature is experimental
When using GraphQl, with event_listeners_backward_compatibility_layer: true, mutation resolver gets called before validation, when using false (the future default) validation occurs on the user's input.
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\GetCollection
very useful for read only APIs, this was possible in 2.7 but not backported correctly
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)
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)This version as the 4.0.19 is compatible with Laravel 12.
The hydra patch changes default hydra:title and uses the resource shortname. Previously the hydra:title information was duplicating the hydra:description.
The rdfs:label got removed from the hydra:Class as it was used instead of the hydra:title.
On hydra:property rdfs:label got renamed to label as the rdfs namespace is available in the context.
The ApiPlatform\Metadata\ErrorResource and the ConstraintViolation (ValidationException class) are now generated directly from your PHP classes, only our ConstraintViolationList is hard-written and documents the ConstraintViolation::violation property. Therefore, your own error resources are also documented. On top of that, we now set the rdfs:subClassOf to hydra:Error.
#[ApiProperty(hydra: false)] allows you to skip a documented hydra:supportedProperty on a class.
On write operations, we added the expectsHeader field.
genId: false to disable BC_api_exception_to_status leftovers (#4992)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](https://github.com/final) annotation from filters and mark them as finalResourceAccessChecker::__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.
array cast for RDF types in ApiResource & ApiProperty constructors (#5000)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](https://github.com/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)false (#4880)$exceptionOnNoToken parameter in ResourceAccessChecker::__construct() (#4900)Various cs fixes and PHPDoc to help upgrading to 3.0.
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](https://github.com/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](https://github.com/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)AbstractPaginator class (#3827)additionalProp1 from showing in example values (#3888)hydra:mapping properties as nullable (#3877)[@type](https://github.com/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::normalizeRelationhydra:next when the item total is strictly greater than the number of items per page (#3967)SerializerContextBuilder[@ApiFilter](https://github.com/ApiFilter) annotation404 HTTP status code instead of 500 whe the identifier is invalid (e.g.: invalid UUID)[@ApiResource](https://github.com/ApiResource) annotation's attributes to improve DXfilter query parameterbody parameter if it already existsoauth2-redirect configurationSecurityBundle was not installedfetchmerge-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](https://github.com/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](https://github.com/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 installedinput_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](https://github.com/ApiResource) and [@ApiProperty](https://github.com/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](https://github.com/ApiFilter) annotations on the same classSubresourceDataProviderInterfaceDateTimeImmutable support in the date filterDocumentationAction impacting NelmioApiDoc[@ApiFilter](https://github.com/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/1207LEFT JOIN clause for filter associations\Traversable valuesdeclare(strict_types=1) and improve coding standardsConstraintViolationListeach() (deprecated since PHP 7.2)EagerLoadingExtensionhydra_context option take precedence over operation metadataItemNormalizer (raw JSON, XML)#ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter::extractProperties now always return an arrayItemDataproviderInterface: fetchData is now in the context parameterer. getItemFromIri is now context aware 7f82fd7start and word_start strategies to the Doctrine Search filterDoctrine\Orm\Filter\OrderFilter instanceHow can I help you explore Laravel packages today?