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)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()
SearchFilter
hasNextPage
when offset > itemsPerPage
ApiResource::$paginationPartial
AbstractItemNormalizer::normalizeRelation
SerializerContextBuilder
@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 installedfetch
access_control
item_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 paginationapi: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
methodPagination
EntityManagerInterface
is used in data providersprevious_data
Content-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)
FilterEagerLoadingExtension
NoOpScalarNormalizer
handling scalar valuesapi_platform.metadata_cache
parameterSearchFilter
webonyx/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 WriteListener
OptimisticLockException
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 subresourcesNumericFilter
ReadListener
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 RestrictedDataProviderInterface
POST
request to have an empty bodyIriConverter
Link
HTTP header pointing to the Hydra documentation if docs are disabledOrderFilter
to trigger faulty deprecation noticesfetchEager=false
directive on an association in the EagerLoadingExtension
ItemNormalizer
ConstraintViolationListNormalizer
CachedRouteNameResolver
and CachedSubresourceOperationFactory
by adding a local memory cache layerisResourceClass
when possibletry/catch
in the CachedTrait
IriConverter
ChainSubresourceDataProvider
class to take into account RestrictedDataProviderInterface
FilterEagerLoadingExtension
with manual joins@ApiFilter
annotations on the same classSubresourceDataProviderInterface
DateTimeImmutable
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 float
owl:allValuesFrom
in the API documentationnull
PriorityTaggedServiceTrait
provided by Symfony instead of a custom implementation/posts/1/comments
or /posts/1/comments/2
RequestAttributesExtractor
FilterCollection
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 standardsConstraintViolationList
each()
(deprecated since PHP 7.2)EagerLoadingExtension
ItemDataproviderInterface
: 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\ExceptionInterface
api_
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
instanceMade 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