api-platform / core

The server component of API Platform: hypermedia and GraphQL APIs in minutes
https://api-platform.com
MIT License
2.43k stars 868 forks source link

Issues found on 2.7 #4613

Closed vincentchalamon closed 2 years ago

vincentchalamon commented 2 years ago

Write here as comment the errors you may found on api-platform/core:2.7.x-dev installed on your project. Please mention:

KDederichs commented 2 years ago

API Platform version(s) affected: 2.7-beta.4

Description
You can not define a GetCollection without defining a Get operation. If you do it'll throw this error: Screenshot 2022-07-12 at 16 37 20

How to reproduce
Define a GetCollection without a Get and then try to execute the GetCollection

Possible Solution
Either make it possible to do that, or at least throw an exception that's more clear why it's not working.

Edit: fixed by #4881

lermontex commented 2 years ago

Hi!

Issue https://github.com/api-platform/core/issues/4727 (The disable_type_enforcement option is ignored (custom GraphQl mutation name's)

I checked version v2.7.0-beta.4 - the bug is still there

Zul3s commented 2 years ago

Hello @vincentchalamon , Yes it works for me too. Thank for your job !

DenSul commented 2 years ago

Hi! API Platform version(s) affected: 2.7-beta.5 SF 5.4.10 PHP 8.1

Description: Bidirectional/Unidirectional many-to-many not working.

{ "type": "https://tools.ietf.org/html/rfc2616#section-10",
  "title": "An error occurred",
  "detail": "[Semantical Error] line 0, col 115 near 'partners IN (SELECT': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected."}

Example entities:

class Partner implements TimestampableInterface
{
    use TimestampableTrait;

    #[ORM\Id]
    #[ORM\Column(type: 'uuid')]
    private UuidInterface $id;
    /**
     * @var Collection<int, Courier>
     */
    #[ORM\ManyToMany(targetEntity: 'App\Infrastructure\Doctrine\Entity\Courier\Courier', mappedBy: 'partners', fetch: 'EXTRA_LAZY')]
    private Collection $couriers;
}
class Courier implements TimestampableInterface, UserInterface, PasswordAuthenticatedUserInterface
{
    use TimestampableTrait;

    #[ORM\Id]
    #[ORM\Column(type: 'uuid')]
    private UuidInterface $id;

    /**
     * @var Collection<int, Partner>
     */
    #[ORM\ManyToMany(targetEntity: 'App\Infrastructure\Doctrine\Entity\Partner\Partner', inversedBy: 'couriers', fetch: 'EXTRA_LAZY')]
    #[ORM\JoinTable(name: 'cd_partners_couries')]
    private Collection $partners;
}

work not work

Yoann-TYT commented 2 years ago

@KDederichs
As you can see on the documentation, you have to define Get item operation. Get collections and Get item are mandatory operations

#[ApiResource(operations: [
    new Get(
        controller: NotFoundAction::class, 
        read: false, 
        output: false
    ),
    new GetCollection()
])]

But this code generate for me a 404 Not Found. I have to inverse the order to get a success response .

#[ApiResource(operations: [
    new GetCollection(),
    new Get(
        controller: NotFoundAction::class, 
        read: false, 
        output: false
    )
])]

Edit: fixed by #4881

RobinHoutevelts commented 2 years ago

API Platform version(s) affected: 2.7-rc2 SF 5.4.10 PHP 8.1

I'm having multiple issues with the 2.7-rc2 release. This is the first time I tried to upgrade from 2.6.8 (where I have no deprecations)

POST /api/bands

{
   "title": "Wieni rock and roll"
}
Response in 2.6.8 ```json { "data": { "id": "/api/bands/8777e8db-1205-4140-92ba-bac6a95bea74", "type": "Band", "attributes": { "id": "8777e8db-1205-4140-92ba-bac6a95bea74", "title": "Wieni rock and roll", "timeZone": "Europe/Brussels", "dateFormat": "dd/mm/yyyy", "timeFormat": "24-hour", "users": [ { "data": { "id": "/api/band_users/59cbfbbc-31da-4430-bbb2-703e2279b9d7", "type": "BandUser", "attributes": { "id": "59cbfbbc-31da-4430-bbb2-703e2279b9d7", "user": { "data": { "id": "/api/users/c0bf5d3b-0a77-42df-bdcf-a6a8f5b4d592", "type": "User" } }, "firstname": "Robin", "lastname": "Woodfields", "email": "robin@wieni.be", "nickname": null, "function": null, "birthDate": "1960-03-11", "permissions": [ { "granted": true, "permission": "EDIT" }, { "granted": true, "permission": "DELETE" }, { "granted": true, "permission": "VIEW_FULL_PROFILE" } ], "category": null, "addresses": [], "phoneNumbers": [] } } } ], "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00", "eventTypes": [ { "data": { "id": "/api/event_types/8905df85-a8a9-4632-abfc-c3b3bff48db2", "type": "EventType", "attributes": { "icon": "stage", "id": "8905df85-a8a9-4632-abfc-c3b3bff48db2", "label": "Performance", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } }, { "data": { "id": "/api/event_types/ca043bd7-b6f4-4657-a336-be434d2d5426", "type": "EventType", "attributes": { "icon": "microphone", "id": "ca043bd7-b6f4-4657-a336-be434d2d5426", "label": "Rehearsal", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } } ], "eventTicketAndPassTypes": [ { "data": { "id": "/api/event_ticket_and_pass_types/23595506-2459-4ed1-813b-086bae0f7ddf", "type": "EventTicketAndPassType", "attributes": { "id": "23595506-2459-4ed1-813b-086bae0f7ddf", "label": "Guest tickets", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } }, { "data": { "id": "/api/event_ticket_and_pass_types/cf1726d2-5f14-4972-8705-f7c0cb6713b1", "type": "EventTicketAndPassType", "attributes": { "id": "cf1726d2-5f14-4972-8705-f7c0cb6713b1", "label": "VIP pass", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } } ], "eventInfoBlockTypes": [ { "data": { "id": "/api/event_info_block_types/cd44e3f7-69c7-42e0-b897-69efa9a469e0", "type": "EventInfoBlockType", "attributes": { "icon": "catering", "id": "cd44e3f7-69c7-42e0-b897-69efa9a469e0", "label": "Catering", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } }, { "data": { "id": "/api/event_info_block_types/70ddd1db-eaa1-4946-aafd-d4dea99a97d1", "type": "EventInfoBlockType", "attributes": { "icon": "contact", "id": "70ddd1db-eaa1-4946-aafd-d4dea99a97d1", "label": "Contacts", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } } ], "memberCategories": [ { "data": { "id": "/api/band_member_categories/420edc52-a2d8-45fc-a9da-803c758f746d", "type": "BandMemberCategory", "attributes": { "id": "420edc52-a2d8-45fc-a9da-803c758f746d", "label": "Band", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } }, { "data": { "id": "/api/band_member_categories/341fc7d4-5a24-4eb8-8bfd-87f8b9a7fab9", "type": "BandMemberCategory", "attributes": { "id": "341fc7d4-5a24-4eb8-8bfd-87f8b9a7fab9", "label": "Crew", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } }, { "data": { "id": "/api/band_member_categories/bcd9662a-ada9-47ff-81c5-d1952f263c9a", "type": "BandMemberCategory", "attributes": { "id": "bcd9662a-ada9-47ff-81c5-d1952f263c9a", "label": "Management", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } }, { "data": { "id": "/api/band_member_categories/9663cc2b-77f4-4c48-a6fe-1b0468961808", "type": "BandMemberCategory", "attributes": { "id": "9663cc2b-77f4-4c48-a6fe-1b0468961808", "label": "Booking agent", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } }, { "data": { "id": "/api/band_member_categories/3dd5348a-a666-4636-90f7-882a1b7d949d", "type": "BandMemberCategory", "attributes": { "id": "3dd5348a-a666-4636-90f7-882a1b7d949d", "label": "Record label", "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00" } } } ], "subscription": { "data": { "id": "/api/subscriptions/691a50b9-e2ca-49de-a850-eadbe303a39e", "type": "Subscription", "attributes": { "id": "691a50b9-e2ca-49de-a850-eadbe303a39e", "paymentMethod": null, "company": null, "status": "active", "plan": "trial", "billingStatus": "not_automatically_renewed", "start": "2022-07-30T00:00:00+00:00", "stop": "2022-08-29T23:59:59+00:00", "nextBillingDate": null, "permissions": [ { "granted": false, "permission": "EDIT" }, { "granted": false, "permission": "CANCEL" }, { "granted": false, "permission": "CHANGE_PLAN" } ], "createdAt": "2022-07-30T21:36:39+00:00", "updatedAt": "2022-07-30T21:36:39+00:00", "deactivatedAt": null, "nextPhasePlan": null, "nextPhaseStart": null, "createdBy": null } } }, "permissions": [ { "granted": true, "permission": "EDIT" }, { "granted": true, "permission": "DELETE" }, { "granted": true, "permission": "MANAGE_SUBSCRIPTIONS" }, { "granted": true, "permission": "CREATE_EVENT" }, { "granted": true, "permission": "CREATE_EVENT_TYPE" }, { "granted": true, "permission": "CREATE_EVENT_INFOBLOCK_TYPE" }, { "granted": true, "permission": "CREATE_EVENT_TICKET_AND_PASS_TYPE" }, { "granted": true, "permission": "CREATE_MEMBER_CATEGORY" }, { "granted": true, "permission": "ADD_USER" } ] } } } ```
Response in 2.7-rc2 ```json { "data": { "id": "/.well-known/genid/0c739a35e0545a815726", "type": "Band", "attributes": { "title": "Wieni rock and roll", "timeZone": "Europe/Brussels", "dateFormat": "dd/mm/yyyy", "timeFormat": "24-hour", "users": { "links": { "self": "/api/bands" }, "meta": { "totalItems": 0 }, "data": [] }, "eventTypes": { "links": { "self": "/api/bands" }, "meta": { "totalItems": 0 }, "data": [] }, "eventTicketAndPassTypes": { "links": { "self": "/api/bands" }, "meta": { "totalItems": 0 }, "data": [] }, "eventInfoBlockTypes": { "links": { "self": "/api/bands" }, "meta": { "totalItems": 0 }, "data": [] }, "memberCategories": { "links": { "self": "/api/bands" }, "meta": { "totalItems": 0 }, "data": [] } } } } ```

I'll try to ask for some time to debug this further.

I tried to kindof replicate our setup using a fork of the demo. But there I got a whole other set of issues 🤯

You can find my fork at RobinHoutevelts/api-pf-2.7.rc2-regression

I changed /tests/Api/BooksTest.php. It passes in 2.6.8 but fails in 2.7-rc2

Output docker compose exec php bin/phpunit tests/Api/BooksTest.php ``` PHPUnit 9.5.21 Testing App\Tests\Api\BooksTest Time: 00:01.296, Memory: 68.50 MB There were 2 failures: 1) App\Tests\Api\BooksTest::testItSeesABook Failed asserting that two arrays are equal. --- Expected +++ Actual @@ @@ 'id' => '/reviews/b8297679-1c68-459a-a...1d2249' 'type' => 'Review' 'attributes' => Array ( - 'id' => 'b8297679-1c68-459a-a277-2e7def1d2249' 'body' => 'Ut dolor aut ratione maxime e...io ab.' + '_id' => 'b8297679-1c68-459a-a277-2e7def1d2249' ) ) ) @@ @@ 'id' => '/reviews/aa053d11-05a5-4557-b...daa46a' 'type' => 'Review' 'attributes' => Array ( - 'id' => 'aa053d11-05a5-4557-bf14-ff9d60daa46a' 'body' => 'Rerum porro omnis voluptas te...iores.' + '_id' => 'aa053d11-05a5-4557-bf14-ff9d60daa46a' ) ) ) @@ @@ 'id' => '/reviews/e6c21a91-fe13-4e02-b...7d8db6' 'type' => 'Review' 'attributes' => Array ( - 'id' => 'e6c21a91-fe13-4e02-b52a-6977ba7d8db6' 'body' => 'Facilis iste esse praesentium...illum.' + '_id' => 'e6c21a91-fe13-4e02-b52a-6977ba7d8db6' ) ) ) /srv/api/tests/Api/BooksTest.php:44 2) App\Tests\Api\BooksTest::testItCreatesABook Failed asserting that the Response status code is 201. HTTP/1.1 400 Bad Request Cache-Control: no-cache, private Content-Type: application/problem+json; charset=utf-8 Date: Sat, 30 Jul 2022 21:54:12 GMT X-Content-Type-Options: nosniff X-Frame-Options: deny X-Robots-Tag: noindex {"type":"https:\/\/tools.ietf.org\/html\/rfc2616#section-10","title":"An error occurred","detail":"No resource class found for object of type \u0022App\\Dto\\Book\u0022.","trace":[{"namespace":"","short_class":"","class":"","type":"","function":"","file":"\/srv\/api\/vendor\/api-platform\/core\/src\/Api\/ResourceClassResolver.php","line":56,"args":[]},{"namespace":"ApiPlatform\\Api","short_class":"ResourceClassResolver","class":"ApiPlatform\\Api\\ResourceClassResolver","type":"-\u003E","function":"getResourceClass","file":"\/srv\/api\/vendor\/api-platform\/core\/src\/Util\/ResourceClassInfoTrait.php","line":60,"args":[["object","App\\Dto\\Book"]]},{"namespace":"ApiPlatform\\Core\\Bridge\\Symfony\\Routing","short_class":"IriConverter","class":"ApiPlatform\\Core\\Bridge\\Symfony\\Routing\\IriConverter","type":"-\u003E","function":"getResourceClass","file":"\/srv\/api\/vendor\/api-platform\/core\/src\/Core\/Bridge\/Symfony\/Routing\/IriConverter.php","line":123,"args":[["object","App\\Dto\\Book"],["boolean",true]]},{"namespace":"ApiPlatform\\Core\\Bridge\\Symfony\\Routing","short_class":"IriConverter","class":"ApiPlatform\\Core\\Bridge\\Symfony\\Routing\\IriConverter","type":"-\u003E","function":"getIriFromItem","file":"\/srv\/api\/vendor\/api-platform\/core\/src\/JsonApi\/Serializer\/ItemNormalizer.php","line":89,"args":[["object","App\\Dto\\Book"]]},{"namespace":"ApiPlatform\\JsonApi\\Serializer","short_class":"ItemNormalizer","class":"ApiPlatform\\JsonApi\\Serializer\\ItemNormalizer","type":"-\u003E","function":"normalize","file":"\/srv\/api\/vendor\/symfony\/serializer\/Serializer.php","line":161,"args":[["object","App\\Dto\\Book"],["string","jsonapi"],["array",{"groups":["array",[["string","book:read"]]],"operation_type":["string","collection"],"collection_operation_name":["string","post"],"iri_only":["boolean",false],"input":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"resource_class":["string","App\\Dto\\Book"],"request_uri":["string","\/books"],"uri":["string","http:\/\/localhost\/books"],"resources":["object","ApiPlatform\\Serializer\\ResourceList"],"exclude_from_cache_key":["array",[["string","resources"],["string","resources_to_push"]]],"resources_to_push":["object","ApiPlatform\\Serializer\\ResourceList"],"api_sub_level":["boolean",true],"allow_extra_attributes":["boolean",false],"cache_key":["string","284f8abaa7074da39793c32dc6c12577"]}]]},{"namespace":"Symfony\\Component\\Serializer","short_class":"Serializer","class":"Symfony\\Component\\Serializer\\Serializer","type":"-\u003E","function":"normalize","file":"\/srv\/api\/vendor\/api-platform\/core\/src\/Serializer\/AbstractItemNormalizer.php","line":198,"args":[["object","App\\Dto\\Book"],["string","jsonapi"],["array",{"groups":["array",[["string","book:read"]]],"operation_type":["string","collection"],"collection_operation_name":["string","post"],"iri_only":["boolean",false],"input":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"resource_class":["string","App\\Dto\\Book"],"request_uri":["string","\/books"],"uri":["string","http:\/\/localhost\/books"],"resources":["object","ApiPlatform\\Serializer\\ResourceList"],"exclude_from_cache_key":["array",[["string","resources"],["string","resources_to_push"]]],"resources_to_push":["object","ApiPlatform\\Serializer\\ResourceList"],"api_sub_level":["boolean",true],"allow_extra_attributes":["boolean",false]}]]},{"namespace":"ApiPlatform\\Serializer","short_class":"AbstractItemNormalizer","class":"ApiPlatform\\Serializer\\AbstractItemNormalizer","type":"-\u003E","function":"normalize","file":"\/srv\/api\/vendor\/api-platform\/core\/src\/JsonApi\/Serializer\/ItemNormalizer.php","line":77,"args":[["object","App\\Dto\\Book"],["string","jsonapi"],["array",{"groups":["array",[["string","book:read"]]],"operation_type":["string","collection"],"collection_operation_name":["string","post"],"iri_only":["boolean",false],"input":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"resource_class":["string","App\\Dto\\Book"],"request_uri":["string","\/books"],"uri":["string","http:\/\/localhost\/books"],"resources":["object","ApiPlatform\\Serializer\\ResourceList"],"exclude_from_cache_key":["array",[["string","resources"],["string","resources_to_push"]]],"resources_to_push":["object","ApiPlatform\\Serializer\\ResourceList"],"api_sub_level":["boolean",true],"allow_extra_attributes":["boolean",false]}]]},{"namespace":"ApiPlatform\\JsonApi\\Serializer","short_class":"ItemNormalizer","class":"ApiPlatform\\JsonApi\\Serializer\\ItemNormalizer","type":"-\u003E","function":"normalize","file":"\/srv\/api\/vendor\/symfony\/serializer\/Serializer.php","line":161,"args":[["object","App\\Dto\\Book"],["string","jsonapi"],["array",{"groups":["array",[["string","book:read"]]],"operation_type":["string","collection"],"collection_operation_name":["string","post"],"iri_only":["boolean",false],"input":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"output":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"resource_class":["string","App\\Entity\\Book"],"request_uri":["string","\/books"],"uri":["string","http:\/\/localhost\/books"],"resources":["object","ApiPlatform\\Serializer\\ResourceList"],"exclude_from_cache_key":["array",[["string","resources"],["string","resources_to_push"]]],"resources_to_push":["object","ApiPlatform\\Serializer\\ResourceList"]}]]},{"namespace":"Symfony\\Component\\Serializer","short_class":"Serializer","class":"Symfony\\Component\\Serializer\\Serializer","type":"-\u003E","function":"normalize","file":"\/srv\/api\/vendor\/symfony\/serializer\/Serializer.php","line":134,"args":[["object","App\\Dto\\Book"],["string","jsonapi"],["array",{"groups":["array",[["string","book:read"]]],"operation_type":["string","collection"],"collection_operation_name":["string","post"],"iri_only":["boolean",false],"input":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"output":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"resource_class":["string","App\\Entity\\Book"],"request_uri":["string","\/books"],"uri":["string","http:\/\/localhost\/books"],"resources":["object","ApiPlatform\\Serializer\\ResourceList"],"exclude_from_cache_key":["array",[["string","resources"],["string","resources_to_push"]]],"resources_to_push":["object","ApiPlatform\\Serializer\\ResourceList"]}]]},{"namespace":"Symfony\\Component\\Serializer","short_class":"Serializer","class":"Symfony\\Component\\Serializer\\Serializer","type":"-\u003E","function":"serialize","file":"\/srv\/api\/vendor\/api-platform\/core\/src\/Symfony\/EventListener\/SerializeListener.php","line":121,"args":[["object","App\\Dto\\Book"],["string","jsonapi"],["array",{"groups":["array",[["string","book:read"]]],"operation_type":["string","collection"],"collection_operation_name":["string","post"],"iri_only":["boolean",false],"input":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"output":["array",{"class":["string","App\\Dto\\Book"],"name":["string","Book"]}],"resource_class":["string","App\\Entity\\Book"],"request_uri":["string","\/books"],"uri":["string","http:\/\/localhost\/books"],"resources":["object","ApiPlatform\\Serializer\\ResourceList"],"exclude_from_cache_key":["array",[["string","resources"],["string","resources_to_push"]]],"resources_to_push":["object","ApiPlatform\\Serializer\\ResourceList"]}]]},{"namespace":"ApiPlatform\\Symfony\\EventListener","short_class":"SerializeListener","class":"ApiPlatform\\Symfony\\EventListener\\SerializeListener","type":"-\u003E","function":"onKernelView","file":"\/srv\/api\/vendor\/symfony\/event-dispatcher\/Debug\/WrappedListener.php","line":115,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\ViewEvent"],["string","kernel.view"],["object","Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"]]},{"namespace":"Symfony\\Component\\EventDispatcher\\Debug","short_class":"WrappedListener","class":"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener","type":"-\u003E","function":"__invoke","file":"\/srv\/api\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php","line":230,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\ViewEvent"],["string","kernel.view"],["object","Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"]]},{"namespace":"Symfony\\Component\\EventDispatcher","short_class":"EventDispatcher","class":"Symfony\\Component\\EventDispatcher\\EventDispatcher","type":"-\u003E","function":"callListeners","file":"\/srv\/api\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php","line":59,"args":[["array",[["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"]]],["string","kernel.view"],["object","Symfony\\Component\\HttpKernel\\Event\\ViewEvent"]]},{"namespace":"Symfony\\Component\\EventDispatcher","short_class":"EventDispatcher","class":"Symfony\\Component\\EventDispatcher\\EventDispatcher","type":"-\u003E","function":"dispatch","file":"\/srv\/api\/vendor\/symfony\/event-dispatcher\/Debug\/TraceableEventDispatcher.php","line":153,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\ViewEvent"],["string","kernel.view"]]},{"namespace":"Symfony\\Component\\EventDispatcher\\Debug","short_class":"TraceableEventDispatcher","class":"Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher","type":"-\u003E","function":"dispatch","file":"\/srv\/api\/vendor\/symfony\/http-kernel\/HttpKernel.php","line":157,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\ViewEvent"],["string","kernel.view"]]},{"namespace":"Symfony\\Component\\HttpKernel","short_class":"HttpKernel","class":"Symfony\\Component\\HttpKernel\\HttpKernel","type":"-\u003E","function":"handleRaw","file":"\/srv\/api\/vendor\/symfony\/http-kernel\/HttpKernel.php","line":74,"args":[["object","Symfony\\Component\\HttpFoundation\\Request"],["integer",1]]},{"namespace":"Symfony\\Component\\HttpKernel","short_class":"HttpKernel","class":"Symfony\\Component\\HttpKernel\\HttpKernel","type":"-\u003E","function":"handle","file":"\/srv\/api\/vendor\/symfony\/http-kernel\/Kernel.php","line":202,"args":[["object","Symfony\\Component\\HttpFoundation\\Request"],["integer",1],["boolean",true]]},{"namespace":"Symfony\\Component\\HttpKernel","short_class":"Kernel","class":"Symfony\\Component\\HttpKernel\\Kernel","type":"-\u003E","function":"handle","file":"\/srv\/api\/vendor\/symfony\/http-kernel\/HttpKernelBrowser.php","line":65,"args":[["object","Symfony\\Component\\HttpFoundation\\Request"],["integer",1],["boolean",true]]},{"namespace":"Symfony\\Component\\HttpKernel","short_class":"HttpKernelBrowser","class":"Symfony\\Component\\HttpKernel\\HttpKernelBrowser","type":"-\u003E","function":"doRequest","file":"\/srv\/api\/vendor\/symfony\/framework-bundle\/KernelBrowser.php","line":172,"args":[["object","Symfony\\Component\\HttpFoundation\\Request"]]},{"namespace":"Symfony\\Bundle\\FrameworkBundle","short_class":"KernelBrowser","class":"Symfony\\Bundle\\FrameworkBundle\\KernelBrowser","type":"-\u003E","function":"doRequest","file":"\/srv\/api\/vendor\/symfony\/browser-kit\/AbstractBrowser.php","line":370,"args":[["object","Symfony\\Component\\HttpFoundation\\Request"]]},{"namespace":"Symfony\\Component\\BrowserKit","short_class":"AbstractBrowser","class":"Symfony\\Component\\BrowserKit\\AbstractBrowser","type":"-\u003E","function":"request","file":"\/srv\/api\/vendor\/api-platform\/core\/src\/Symfony\/Bundle\/Test\/Client.php","line":124,"args":[["string","POST"],["string","http:\/\/localhost\/books"],["array",[]],["array",[]],["array",{"HTTP_USER_AGENT":["string","Symfony BrowserKit"],"CONTENT_TYPE":["string","application\/json"],"HTTP_ACCEPT":["string","application\/vnd.api+json"],"HTTP_CONTENT_LENGTH":["string","131"],"HTTP_HOST":["string","localhost"],"HTTPS":["boolean",false]}],["string","{\u0022title\u0022:\u0022Api-Platform is awesome\u0022,\u0022isbn\u0022:\u00220983769001\u0022,\u0022author\u0022:\u0022Santa Claus\u0022,\u0022description\u0022:\u0022Great\u0022,\u0022publicationDate\u0022:\u00222022-12-25\u0022}"]]},{"namespace":"ApiPlatform\\Symfony\\Bundle\\Test","short_class":"Client","class":"ApiPlatform\\Symfony\\Bundle\\Test\\Client","type":"-\u003E","function":"request","file":"\/srv\/api\/tests\/Api\/BooksTest.php","line":105,"args":[["string","POST"],["array",{"scheme":["string","http:"],"authority":["string","\/\/localhost"],"path":["string","\/books"],"query":["null",null],"fragment":["null",null]}],["array",{"headers":["array",[["string","Content-Type: application\/json"],["string","Accept: application\/vnd.api+json"],["string","Content-Length: 131"]]],"normalized_headers":["array",{"content-type":["array",[["string","Content-Type: application\/json"]]],"accept":["array",[["string","Accept: application\/vnd.api+json"]]],"content-length":["array",[["string","Content-Length: 131"]]]}],"query":["array",[]],"body":["string","{\u0022title\u0022:\u0022Api-Platform is awesome\u0022,\u0022isbn\u0022:\u00220983769001\u0022,\u0022author\u0022:\u0022Santa Claus\u0022,\u0022description\u0022:\u0022Great\u0022,\u0022publicationDate\u0022:\u00222022-12-25\u0022}"],"base_uri":["array",{"scheme":["string","http:"],"authority":["string","\/\/localhost"],"path":["null",null],"query":["null",null],"fragment":["null",null]}],"extra":["array",[]],"http_version":["null",null],"timeout":["float",60],"max_duration":["float",0]}]]},{"namespace":"App\\Tests\\Api","short_class":"BooksTest","class":"App\\Tests\\Api\\BooksTest","type":"-\u003E","function":"doRequest","file":"\/srv\/api\/tests\/Api\/BooksTest.php","line":73,"args":[["string","POST"],["string","\/books"],["array",{"title":["string","Api-Platform is awesome"],"isbn":["string","0983769001"],"author":["string","Santa Claus"],"description":["string","Great"],"publicationDate":["string","2022-12-25"]}]]},{"namespace":"App\\Tests\\Api","short_class":"BooksTest","class":"App\\Tests\\Api\\BooksTest","type":"-\u003E","function":"doPost","file":"\/srv\/api\/tests\/Api\/BooksTest.php","line":52,"args":[["string","\/books"],["array",{"title":["string","Api-Platform is awesome"],"isbn":["string","0983769001"],"author":["string","Santa Claus"],"description":["string","Great"],"publicationDate":["string","2022-12-25"]}]]},{"namespace":"App\\Tests\\Api","short_class":"BooksTest","class":"App\\Tests\\Api\\BooksTest","type":"-\u003E","function":"testItCreatesABook","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/src\/Framework\/TestCase.php","line":1546,"args":[]},{"namespace":"PHPUnit\\Framework","short_class":"TestCase","class":"PHPUnit\\Framework\\TestCase","type":"-\u003E","function":"runTest","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/src\/Framework\/TestCase.php","line":1152,"args":[]},{"namespace":"PHPUnit\\Framework","short_class":"TestCase","class":"PHPUnit\\Framework\\TestCase","type":"-\u003E","function":"runBare","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/src\/Framework\/TestResult.php","line":726,"args":[]},{"namespace":"PHPUnit\\Framework","short_class":"TestResult","class":"PHPUnit\\Framework\\TestResult","type":"-\u003E","function":"run","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/src\/Framework\/TestCase.php","line":904,"args":[["object","App\\Tests\\Api\\BooksTest"]]},{"namespace":"PHPUnit\\Framework","short_class":"TestCase","class":"PHPUnit\\Framework\\TestCase","type":"-\u003E","function":"run","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/src\/Framework\/TestSuite.php","line":670,"args":[["object","PHPUnit\\Framework\\TestResult"]]},{"namespace":"PHPUnit\\Framework","short_class":"TestSuite","class":"PHPUnit\\Framework\\TestSuite","type":"-\u003E","function":"run","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/src\/TextUI\/TestRunner.php","line":673,"args":[["object","PHPUnit\\Framework\\TestResult"]]},{"namespace":"PHPUnit\\TextUI","short_class":"TestRunner","class":"PHPUnit\\TextUI\\TestRunner","type":"-\u003E","function":"run","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/src\/TextUI\/Command.php","line":143,"args":[["object","PHPUnit\\Framework\\TestSuite"],["array",{"extensions":["array",[]],"listGroups":["boolean",false],"listSuites":["boolean",false],"listTests":["boolean",false],"listTestsXml":["boolean",false],"loader":["null",null],"useDefaultConfiguration":["boolean",true],"loadedExtensions":["array",[]],"unavailableExtensions":["array",[]],"notLoadedExtensions":["array",[]],"colors":["string","always"],"testSuffixes":["array",[["string","Test.php"],["string",".phpt"]]],"configuration":["string","\/srv\/api\/phpunit.xml.dist"],"configurationObject":["object","PHPUnit\\TextUI\\XmlConfiguration\\Configuration"],"stderr":["boolean",false],"columns":["integer",80],"listeners":["array",[["object","Symfony\\Bridge\\PhpUnit\\Legacy\\SymfonyTestsListenerForV7"]]],"warnings":["array",[]],"debug":["boolean",false],"filter":["boolean",false],"backupGlobals":["boolean",false],"backupStaticAttributes":["boolean",false],"beStrictAboutChangesToGlobalState":["boolean",false],"cacheResult":["boolean",true],"convertDeprecationsToExceptions":["boolean",false],"convertErrorsToExceptions":["boolean",true],"convertNoticesToExceptions":["boolean",true],"convertWarningsToExceptions":["boolean",true],"processIsolation":["boolean",false],"stopOnDefect":["boolean",false],"stopOnError":["boolean",false],"stopOnFailure":["boolean",false],"stopOnWarning":["boolean",false],"stopOnIncomplete":["boolean",false],"stopOnRisky":["boolean",false],"stopOnSkipped":["boolean",false],"failOnEmptyTestSuite":["boolean",false],"failOnIncomplete":["boolean",false],"failOnRisky":["boolean",false],"failOnSkipped":["boolean",false],"failOnWarning":["boolean",false],"enforceTimeLimit":["boolean",false],"defaultTimeLimit":["integer",1],"timeoutForSmallTests":["integer",1],"timeoutForMediumTests":["integer",10],"timeoutForLargeTests":["integer",60],"reportUselessTests":["boolean",true],"strictCoverage":["boolean",false],"ignoreDeprecatedCodeUnitsFromCodeCoverage":["boolean",false],"disallowTestOutput":["boolean",false],"disallowTodoAnnotatedTests":["boolean",false],"beStrictAboutResourceUsageDuringSmallTests":["boolean",false],"verbose":["boolean",false],"reverseDefectList":["boolean",false],"forceCoversAnnotation":["boolean",false],"disableCodeCoverageIgnore":["boolean",false],"registerMockObjectsFromTestArgumentsRecursively":["boolean",false],"noInteraction":["boolean",false],"executionOrder":["integer",0],"resolveDependencies":["boolean",true],"bootstrap":["string","\/srv\/api\/tests\/bootstrap.php"],"executionOrderDefects":["integer",0],"crap4jThreshold":["integer",30],"excludeGroups":["array",[]],"groups":["array",[]],"randomOrderSeed":["integer",1659218051],"repeat":["boolean",false],"reportHighLowerBound":["integer",90],"reportLowUpperBound":["integer",50],"reverseList":["boolean",false],"testdoxExcludeGroups":["array",[]],"testdoxGroups":["array",[]],"cacheResultFile":["string","\/srv\/api"]}],["array",[]],["boolean",true]]},{"namespace":"PHPUnit\\TextUI","short_class":"Command","class":"PHPUnit\\TextUI\\Command","type":"-\u003E","function":"run","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/src\/TextUI\/Command.php","line":96,"args":[["array",[["string","bin\/phpunit"],["string","--colors=always"],["string","tests\/Api\/BooksTest.php"]]],["boolean",true]]},{"namespace":"PHPUnit\\TextUI","short_class":"Command","class":"PHPUnit\\TextUI\\Command","type":"::","function":"main","file":"\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/phpunit","line":22,"args":[]},{"namespace":"","short_class":"","class":"","type":"","function":"include","file":"\/srv\/api\/vendor\/symfony\/phpunit-bridge\/bin\/simple-phpunit.php","line":437,"args":[["string","\/srv\/api\/vendor\/bin\/.phpunit\/phpunit-9-0\/phpunit"]]},{"namespace":"","short_class":"","class":"","type":"","function":"require","file":"\/srv\/api\/bin\/phpunit","line":18,"args":[["string","\/srv\/api\/vendor\/symfony\/phpunit-bridge\/bin\/simple-phpunit.php"]]}]} /srv/api/vendor/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php:142 /srv/api/vendor/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php:38 /srv/api/tests/Api/BooksTest.php:59 ```
louismariegaborit commented 2 years ago

Hello,

I have an error on test when I use assertMatchesResourceCollectionJsonSchema assertion. In my ApiProperty I use the jsonSchemaContext property to specify the format of datetime. #[ApiProperty(jsonSchemaContext: ['type' => 'string', 'format' => 'YYYY-MM-DD'])] The error : hydra:member[1].date: Invalid date-time "2022-04-10", expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm

API Platform version : 2.7-rc2 SF 6.1.2 PHP 8.1

yobrx commented 2 years ago

@KDederichs As you can see on the documentation, you have to define Get item operation. Get collections and Get item are mandatory operations

@Yoann-TYT I had the same issue, I found on my own with the documentation after wasting an hour. The exception should be a little more precise, don't you think?

alanpoulain commented 2 years ago

It is gonna change soon: https://github.com/api-platform/core/issues/4879

Zul3s commented 2 years ago

Hello, I found a problem with Api platform > 2.7.0-beta-2 when i use provider and output dto.

API Platform version(s) affected:  >2.7-beta-2
SF >=5.4.|| >=6.0
PHP 7.4 || 8.1

Error

"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Operation \"\" not found for resource \"CarOutput\".",
"trace": [...]

You can see an exemple of non working code here : https://github.com/Zul3s/api-platform_2.7.-_demo . Just run and try to execute /api/cars

This problem was introduced with this changement : https://github.com/api-platform/core/compare/v2.7.0-beta.2...v2.7.0-beta.3#diff-d87efa25fbf52904daa06047002652f08645e3ad4a7f4985ffeec5a7c8e39c4fR145

If we delete output declaration, it's work fine, but we loose api documentation.

I don't know how i can help you ?

vincentchalamon commented 2 years ago

@Zul3s it looks like the same bug as #4879. Can you try #4881 to see if it fixes your issue?

Zul3s commented 2 years ago

Hi @vincentchalamon , I try your branch, but i still have the problem.

vincentchalamon commented 2 years ago

@Zul3s OK I've seen the issue from your project. I'm working on it and will try to publish a fix on 2.7 soon

webda2l commented 2 years ago

Hi,

So, I repost here my comment https://github.com/api-platform/core/pull/4881#issuecomment-1209445989

From my testing of the latest 2.7 (kudos to the team!) GraphQl will need a fix as well when there is a field with sub collection like this minimal code (videos.collection.xxx) :

{
  collectionPageQueryVideoGroups {
    collection {
      videos {
        collection {
          thumbnailPath
        }
      }
    }
  }
}

I get the error:

{
  "errors": [
    {
      "debugMessage": "[Semantical Error] line 0, col 41 near 'groups IN (SELECT': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.",
      "message": "Internal server error",
      "extensions": {
        "category": "internal"
      },
      "locations": [
        {
          "line": 4,
          "column": 7
        }
      ],
      "path": [
        "collectionPageQueryVideoGroups",
        "collection",
        0,
        "videos"
      ],
      "trace": [
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php",
          "line": 546,
          "call": "Doctrine\\ORM\\Query\\QueryException::semanticalError()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php",
          "line": 862,
          "call": "Doctrine\\ORM\\Query\\Parser::semanticalError()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php",
          "line": 319,
          "call": "Doctrine\\ORM\\Query\\Parser::processDeferredPathExpressions()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php",
          "line": 408,
          "call": "Doctrine\\ORM\\Query\\Parser::getAST()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php",
          "line": 274,
          "call": "Doctrine\\ORM\\Query\\Parser::parse()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php",
          "line": 286,
          "call": "Doctrine\\ORM\\Query::parse()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php",
          "line": 1188,
          "call": "Doctrine\\ORM\\Query::_doExecute()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php",
          "line": 1142,
          "call": "Doctrine\\ORM\\AbstractQuery::executeIgnoreQueryCache()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php",
          "line": 878,
          "call": "Doctrine\\ORM\\AbstractQuery::execute()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/Paginator.php",
          "line": 171,
          "call": "Doctrine\\ORM\\AbstractQuery::getResult()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/api-platform/core/src/Doctrine/Orm/AbstractPaginator.php",
          "line": 69,
          "call": "Doctrine\\ORM\\Tools\\Pagination\\Paginator::getIterator()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/api-platform/core/src/Doctrine/Orm/AbstractPaginator.php",
          "line": 77,
          "call": "ApiPlatform\\Doctrine\\Orm\\AbstractPaginator::getIterator()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/api-platform/core/src/GraphQl/Resolver/Stage/SerializeStage.php",
          "line": 130,
          "call": "ApiPlatform\\Doctrine\\Orm\\AbstractPaginator::count()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/api-platform/core/src/GraphQl/Resolver/Stage/SerializeStage.php",
          "line": 98,
          "call": "ApiPlatform\\GraphQl\\Resolver\\Stage\\SerializeStage::serializeCursorBasedPaginatedCollection()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/api-platform/core/src/GraphQl/Resolver/Factory/CollectionResolverFactory.php",
          "line": 99,
          "call": "ApiPlatform\\GraphQl\\Resolver\\Stage\\SerializeStage::__invoke()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 623,
          "call": "ApiPlatform\\GraphQl\\Resolver\\Factory\\CollectionResolverFactory::ApiPlatform\\GraphQl\\Resolver\\Factory\\{closure}()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 550,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveFieldValueOrError()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 1195,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 1145,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeFields()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 1106,
          "call": "GraphQL\\Executor\\ReferenceExecutor::collectAndExecuteSubfields()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 793,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeObjectValue()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 654,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeValue()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 887,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeValueCatchingError()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 761,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeListValue()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 654,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeValue()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 557,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeValueCatchingError()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 1195,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 1145,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeFields()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 1106,
          "call": "GraphQL\\Executor\\ReferenceExecutor::collectAndExecuteSubfields()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 793,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeObjectValue()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 654,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeValue()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 557,
          "call": "GraphQL\\Executor\\ReferenceExecutor::completeValueCatchingError()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 1195,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 264,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeFields()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 215,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeOperation()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 156,
          "call": "GraphQL\\Executor\\ReferenceExecutor::doExecute()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/GraphQL.php",
          "line": 162,
          "call": "GraphQL\\Executor\\Executor::promiseToExecute()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/webonyx/graphql-php/src/GraphQL.php",
          "line": 94,
          "call": "GraphQL\\GraphQL::promiseToExecute()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/api-platform/core/src/GraphQl/Executor.php",
          "line": 32,
          "call": "GraphQL\\GraphQL::executeQuery()"
        },
        {
          "file": "/home/david/Works/OLYBe/graphql-api/vendor/api-platform/core/src/GraphQl/Action/EntrypointAction.php",
          "line": 86,
          "call": "ApiPlatform\\GraphQl\\Executor::executeQuery()"
        },

whereas my video resource is well defined with the Get operation (all my resources are)

#[APIP\ApiResource(
    normalizationContext: ['groups' => ['videoGroup:read', 'timestamp']],
    paginationItemsPerPage: 12,
    operations: [new APIP\Get()],
    graphQlOperations: [
        new APIP\GraphQl\QueryCollection(
            name: 'collectionPageQuery',
            resolver: VideoGroupCollectionResolver::class,
            paginationType: 'page'
        ),
        new APIP\GraphQl\QueryCollection(
            name: 'collectionPageQueryEnriched',
            resolver: VideoGroupEnrichedCollectionResolver::class,
            paginationType: 'page'
        ),
    ],
)]
#[ORM\Entity(repositoryClass: VideoGroupRepository::class)]
#[ORM\Table(name: 'videogroup')]
class VideoGroup
{
    use EnableTrait;

    #[ORM\Id]
    #[ORM\Column(type: 'uuid', unique: true)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: UuidGenerator::class)]
    private ?UuidInterface $uuid = null;

    #[Groups(['videoGroup:read'])]
    #[ORM\ManyToMany(targetEntity: Video::class, mappedBy: 'groups', fetch: 'EXTRA_LAZY')]
    private Collection $videos;

    public function getUuid(): ?UuidInterface
    {
        return $this->uuid;
    }

    public function getVideos(): ?Collection
    {
        return $this->videos;
    }

    public function setVideos(ArrayCollection $videos): self
    {
        $this->videos = $videos;

        return $this;
    }
}
#[APIP\ApiResource(
    normalizationContext: ['groups' => ['video:read', 'propKey:read', 'propValue:read', 'teacher:read', 'timestamp']],
    order: ['createdAt' => 'DESC'],
    paginationItemsPerPage: 12,
    operations: [new APIP\Get()],
)]
#[ORM\Entity(repositoryClass: VideoRepository::class)]
class Video
{
    #[ORM\Id]
    #[ORM\Column(type: 'uuid', unique: true)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: UuidGenerator::class)]
    private ?UuidInterface $uuid = null;

    #[Groups(['video:read'])]
    #[ORM\ManyToMany(targetEntity: VideoGroup::class, inversedBy: 'videos', fetch: 'EXTRA_LAZY')]
    #[ORM\JoinTable(name: 'videos_groups')]
    #[ORM\JoinColumn(name: 'video_uuid', referencedColumnName: 'uuid')]
    #[ORM\InverseJoinColumn(name: 'videogroup_uuid', referencedColumnName: 'uuid')]
    private Collection $groups;

    public function __construct()
    {
        $this->groups = new ArrayCollection();
    }

    public function getUuid(): ?UuidInterface
    {
        return $this->uuid;
    }

    public function getGroups(): ?Collection
    {
        return $this->groups;
    }

    public function setGroups(ArrayCollection $groups): self
    {
        $this->groups = $groups;

        return $this;
    }
}

I tried adding operations: [new APIP\GetCollection(), new APIP\Get()], without more success

alanpoulain commented 2 years ago

@webda2l Could you try to use a Link like this:

    #[Groups(['videoGroup:read'])]
    #[ORM\ManyToMany(targetEntity: Video::class, mappedBy: 'groups', fetch: 'EXTRA_LAZY')]
    #[Link(toProperty: 'groups')]
    private Collection $videos;

Not totally sure, but worth a try!

webda2l commented 2 years ago

@webda2l Could you try to use a Link like this:

    #[Groups(['videoGroup:read'])]
    #[ORM\ManyToMany(targetEntity: Video::class, mappedBy: 'groups', fetch: 'EXTRA_LAZY')]
    #[Link(toProperty: 'groups')]
    private Collection $videos;

Not totally sure, but worth a try!

Perfect, good catch! Thanks!

webda2l commented 2 years ago

About other founds during this 3.0 in progress migration, I found that with a resource paginationEnabled: false like this:

#[APIP\ApiResource(
    normalizationContext: ['groups' => ['propValue:read']],
    paginationEnabled: false,
    order: ['weight' => 'DESC'],
    operations: [new APIP\Get()],
    graphQlOperations: [
      ...
class PropertyValue

And the use of a field of this resource as a collection from another resource in graphql. Previously i was doing:

     videos: collectionPageQueryVideos (
        slug: $videoSlug
      ) {
        collection {
            materials {
                _id
                 ...
            }
            ...

But now, I have to embed with a collection, like:

     videos: collectionPageQueryVideos (
        slug: $videoSlug
      ) {
        collection {
            materials {
                collection {
                     _id
                     ...
                }
            }
            ...

I am ok with the new behavior that seems more correct to me. But it seems not set in the https://github.com/api-platform/core/blob/main/CHANGELOG.md as BC break, or I missed it, or the new behavior is a mistake?

alanpoulain commented 2 years ago

Not sure why, but if you can bissect it and find which commit does it, it would be great!

webda2l commented 2 years ago

Not sure why, but if you can bissect it and find which commit does it, it would be great!

Ok will try to do this a bit later.

webda2l commented 2 years ago

Not sure why, but if you can bissect it and find which commit does it, it would be great!

So the change appear in 2.7.beta1, paginationEnabled: false, works ok when the resource is directly used, but not when the resource is embed by another. Like I said previously, not a big deal, because it's a collection, pagination enabled or not, it's better this way I think. But a BC.

// alpha7
{
  videos {
    collection {
      id
      materials {
          id
          slug
      }
    }
  }
}

// beta1
{
  videos {
    collection {
      id
      materials {
        collection {
          id
          slug
        }
      }
    }
  }
}
#[APIP\ApiResource(
    normalizationContext: ['groups' => ['video:read', 'propKey:read', 'propValue:read', 'teacher:read', 'timestamp']],
    order: ['createdAt' => 'DESC'],
    paginationItemsPerPage: 12,
    operations: [new APIP\Get()],
    graphQlOperations: [
        new APIP\GraphQl\QueryCollection(
            name: 'collection_query',
            paginationType: 'page'
        ),
    ],
)]
class Video
{
...
    #[Groups(['video:read'])]
    #[ORM\ManyToMany(targetEntity: PropertyValue::class)]
    #[ORM\JoinTable(name: 'videos_materials')]
    #[ORM\JoinColumn(name: 'video_uuid', referencedColumnName: 'uuid')]
    #[ORM\InverseJoinColumn(name: 'videopropvalue_id', referencedColumnName: 'id')]
    private Collection $materials;

    // #[Groups(['video:read'])]
    // #[ORM\ManyToMany(targetEntity: PropertyValue::class)]
    // #[ORM\JoinTable(name: 'videos_bodyparts')]
    // #[ORM\JoinColumn(name: 'video_uuid', referencedColumnName: 'uuid')]
    // #[ORM\InverseJoinColumn(name: 'videopropvalue_id', referencedColumnName: 'id')]
    // private Collection $bodyParts;
...
}

#[APIP\ApiResource(
    normalizationContext: ['groups' => ['propValue:read']],
    paginationEnabled: false,
    operations: [new APIP\Get()],
    graphQlOperations: [
        new APIP\GraphQl\QueryCollection(
            name: 'collection_query',
            paginationType: 'page'
        ),
    ],
)]
...
class PropertyValue
{
...

Note that there is another issue, maybe related to a missed Link again (I met another case, with a different error, after your comment on a ManyToMany that was required this time a #[APIP\Link(toClass: Company::class, toProperty: 'users')]: this is a bit tricky these Link): note that in the code upper, there is a conflict between the both PropertyValue Collection $materials & $bodyParts, and it requires me to comment the $bodyParts one if I want that the $materials one return something.


Last feedback on the 2.7 that can be a bit severe at a security level :/ Previously I had this configuration, to disable all graphql & rest operation by default and it was ok.

api_platform:
    metadata_backward_compatibility_layer: false
    defaults:
        stateless: true
        graphql: null
        itemOperations: []
        collectionOperations: []
        pagination_items_per_page: 10
        pagination_client_items_per_page: true

But now, with the 2.7, with this same configuration, some mutation has been enabled on some of my entities whose I didn't enable graphql, on this entity by example:

#[APIP\ApiResource(
    security: "is_granted('ROLE_USER')",
    normalizationContext: ['groups' => ['company:read']],
    paginationType: 'page',
    operations: [new APIP\Get()],
)]
class Company
alanpoulain commented 2 years ago

So the change appear in 2.7.beta1, paginationEnabled: false, works ok when the resource is directly used, but not when the resource is embed by another. Like I said previously, not a big deal, because it's a collection, pagination enabled or not, it's better this way I think. But a BC.

Thanks for the search! It's a bug: since the pagination is disabled for PropertyValue, it should also affect its behavior when this resource is nested inside a query. I'm guessing the bug comes because Operation has been used instead of operationName and resourceClass has been not used anymore: the root operation of the "main" resource is probably taken instead of the "current" resource one. If you have some time, could you add a failing test in 2.7? It will help me fix this bug.

Your conflict seems to be a bug too.

For the security part, you probably need to change your default configuration like this:

api_platform:
    metadata_backward_compatibility_layer: false
    defaults:
        stateless: true
        graphql_operations: []
        operations: []
        pagination_items_per_page: 10
        pagination_client_items_per_page: true
webda2l commented 2 years ago

So the change appear in 2.7.beta1, paginationEnabled: false, works ok when the resource is directly used, but not when the resource is embed by another. Like I said previously, not a big deal, because it's a collection, pagination enabled or not, it's better this way I think. But a BC.

Thanks for the search! It's a bug: since the pagination is disabled for PropertyValue, it should also affect its behavior when this resource is nested inside a query. I'm guessing the bug comes because Operation has been used instead of operationName and resourceClass has been not used anymore: the root operation of the "main" resource is probably taken instead of the "current" resource one. If you have some time, could you add a failing test in 2.7? It will help me fix this bug.

Your conflict seems to be a bug too.

For the security part, you probably need to change your default configuration like this:

api_platform:
    metadata_backward_compatibility_layer: false
    defaults:
        stateless: true
        graphql_operations: []
        operations: []
        pagination_items_per_page: 10
        pagination_client_items_per_page: true

You're welcome. I'll see if I have time later this week ok.

For the security part, I tried quickly, same bad result with the latest 2.7 like the 3.0, no :/

KDederichs commented 2 years ago

In 2.7-rc.2 it seems the the open api docs can't handle a GroupSequenceProvider. PHP 8.1.9

I have a setup like this:

class A
{
    #[NotBlank]
    #[Valid]
    private B $recipient;
}

#[GroupSequenceProvider]
class B implements GroupSequenceProviderInterface
{
    private bool $someCondition = false;
   #[NotBlank(groups: ['other_group])]
   private ?string $someValue = null;
    public function getGroupSequence(): array|GroupSequence
    {
        $groups = ['B'];
        if ($someCondition) {
             $groups[] = 'other_group';
        }
        return $groups;
    }
}

And it's giving me this error:

Symfony\Component\Validator\Exception\GroupDefinitionException:
The group "GroupSequence" is missing in the group sequence.

  at vendor/symfony/validator/Mapping/ClassMetadata.php:414
  at Symfony\Component\Validator\Mapping\ClassMetadata->setGroupSequence(object(GroupSequence))
     (vendor/symfony/validator/Mapping/Loader/AnnotationLoader.php:48)
  at Symfony\Component\Validator\Mapping\Loader\AnnotationLoader->loadClassMetadata(object(ClassMetadata))
     (vendor/symfony/validator/Mapping/Loader/LoaderChain.php:54)
  at Symfony\Component\Validator\Mapping\Loader\LoaderChain->loadClassMetadata(object(ClassMetadata))
     (vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php:101)
  at Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory->getMetadataFor('Symfony\\Component\\Validator\\Constraints\\GroupSequence')
     (vendor/symfony/validator/Validator/RecursiveValidator.php:80)
  at Symfony\Component\Validator\Validator\RecursiveValidator->getMetadataFor('Symfony\\Component\\Validator\\Constraints\\GroupSequence')
     (vendor/symfony/validator/Validator/TraceableValidator.php:51)
  at Symfony\Component\Validator\Validator\TraceableValidator->getMetadataFor('Symfony\\Component\\Validator\\Constraints\\GroupSequence')
     (vendor/api-platform/core/src/Symfony/Validator/Metadata/Property/ValidatorPropertyMetadataFactory.php:103)
  at ApiPlatform\Symfony\Validator\Metadata\Property\ValidatorPropertyMetadataFactory->create('Symfony\\Component\\Validator\\Constraints\\GroupSequence', 'groups', array('enable_getter_setter_extraction' => true))
     (vendor/api-platform/core/src/Metadata/Property/Factory/CachedPropertyMetadataFactory.php:47)
  at ApiPlatform\Metadata\Property\Factory\CachedPropertyMetadataFactory->ApiPlatform\Metadata\Property\Factory\{closure}()
     (vendor/api-platform/core/src/Util/CachedTrait.php:44)
  at ApiPlatform\Metadata\Property\Factory\CachedPropertyMetadataFactory->getCached('property_metadata_db9d5a55e96a484ac7c53512d53972df', object(Closure))
     (vendor/api-platform/core/src/Metadata/Property/Factory/CachedPropertyMetadataFactory.php:48)
  at ApiPlatform\Metadata\Property\Factory\CachedPropertyMetadataFactory->create('Symfony\\Component\\Validator\\Constraints\\GroupSequence', 'groups', array('enable_getter_setter_extraction' => true))
     (vendor/api-platform/core/src/JsonSchema/SchemaFactory.php:132)
  at ApiPlatform\JsonSchema\SchemaFactory->buildSchema('Symfony\\Component\\Validator\\Constraints\\GroupSequence', 'jsonld', 'output', null, object(Schema), array(), false)
     (vendor/api-platform/core/src/Hydra/JsonSchema/SchemaFactory.php:76)
  at ApiPlatform\Hydra\JsonSchema\SchemaFactory->buildSchema('Symfony\\Component\\Validator\\Constraints\\GroupSequence', 'jsonld', 'output', null, object(Schema), array(), false)
     (vendor/api-platform/core/src/JsonSchema/TypeFactory.php:157)
  at ApiPlatform\JsonSchema\TypeFactory->getClassType('Symfony\\Component\\Validator\\Constraints\\GroupSequence', 'jsonld', null, array(), object(Schema))
     (vendor/api-platform/core/src/JsonSchema/TypeFactory.php:90)
  at ApiPlatform\JsonSchema\TypeFactory->makeBasicType(object(Type), 'jsonld', null, array(), object(Schema))
     (vendor/api-platform/core/src/JsonSchema/TypeFactory.php:77)
  at ApiPlatform\JsonSchema\TypeFactory->getType(object(Type), 'jsonld', null, array(), object(Schema))
     (vendor/api-platform/core/src/JsonSchema/SchemaFactory.php:218)
  at ApiPlatform\JsonSchema\SchemaFactory->buildPropertySchema(object(Schema), 'CreateBoxOrderRecipient.jsonld', 'groupSequence', object(ApiProperty), array(), 'jsonld')
     (vendor/api-platform/core/src/JsonSchema/SchemaFactory.php:142)
  at ApiPlatform\JsonSchema\SchemaFactory->buildSchema('App\\Entity\\DTO\\CreateBoxOrder\\CreateBoxOrderRecipient', 'jsonld', 'output', null, object(Schema), array(), false)
     (vendor/api-platform/core/src/Hydra/JsonSchema/SchemaFactory.php:76)
  at ApiPlatform\Hydra\JsonSchema\SchemaFactory->buildSchema('App\\Entity\\DTO\\CreateBoxOrder\\CreateBoxOrderRecipient', 'jsonld', 'output', null, object(Schema), array(), false)
     (vendor/api-platform/core/src/JsonSchema/TypeFactory.php:157)
  at ApiPlatform\JsonSchema\TypeFactory->getClassType('App\\Entity\\DTO\\CreateBoxOrder\\CreateBoxOrderRecipient', 'jsonld', null, array(), object(Schema))
     (vendor/api-platform/core/src/JsonSchema/TypeFactory.php:90)
  at ApiPlatform\JsonSchema\TypeFactory->makeBasicType(object(Type), 'jsonld', null, array(), object(Schema))
     (vendor/api-platform/core/src/JsonSchema/TypeFactory.php:77)
  at ApiPlatform\JsonSchema\TypeFactory->getType(object(Type), 'jsonld', null, array(), object(Schema))
     (vendor/api-platform/core/src/JsonSchema/SchemaFactory.php:218)
  at ApiPlatform\JsonSchema\SchemaFactory->buildPropertySchema(object(Schema), 'BoxOrder.CreateBoxOrderInput.jsonld', 'recipient', object(ApiProperty), array(), 'jsonld')
     (vendor/api-platform/core/src/JsonSchema/SchemaFactory.php:142)
  at ApiPlatform\JsonSchema\SchemaFactory->buildSchema('App\\Entity\\BoxOrder', 'jsonld', 'input', object(Post), object(Schema), array(), false)
     (vendor/api-platform/core/src/Hydra/JsonSchema/SchemaFactory.php:76)
  at ApiPlatform\Hydra\JsonSchema\SchemaFactory->buildSchema('App\\Entity\\BoxOrder', 'jsonld', 'input', object(Post), object(Schema), null, false)
     (vendor/api-platform/core/src/OpenApi/Factory/OpenApiFactory.php:261)
  at ApiPlatform\OpenApi\Factory\OpenApiFactory->collectPaths(object(ApiResource), object(ResourceMetadataCollection), object(Paths), object(ArrayObject))
     (vendor/api-platform/core/src/OpenApi/Factory/OpenApiFactory.php:103)
  at ApiPlatform\OpenApi\Factory\OpenApiFactory->__invoke(array('base_url' => '/'))
     (src/OpenApi/JwtDecorator.php:21)
  at App\OpenApi\JwtDecorator->__invoke(array('base_url' => '/'))
     (vendor/api-platform/core/src/Symfony/Bundle/SwaggerUi/SwaggerUiAction.php:66)
  at ApiPlatform\Symfony\Bundle\SwaggerUi\SwaggerUiAction->__invoke(object(Request))
     (vendor/api-platform/core/src/Core/Bridge/Symfony/Bundle/Action/SwaggerUiAction.php:136)
  at ApiPlatform\Core\Bridge\Symfony\Bundle\Action\SwaggerUiAction->__invoke(object(Request))
     (vendor/symfony/http-kernel/HttpKernel.php:152)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:74)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:202)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php:35)
  at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
     (vendor/autoload_runtime.php:29)
  at require_once('/srv/api/vendor/autoload_runtime.php')
     (public/index.php:5) 
KDederichs commented 2 years ago

Here's a minimal reproducer for that: https://github.com/KDederichs/api-platform_groupsequence (using the v3-rc template, the bug is also in there) Turns out it's already enough to designate a ApiResource as GroupSequenceProvider for it to break.

KDederichs commented 2 years ago

Yeah Ok found it, it's picking up on the getter for the GroupSequenceProvider and it's fixable by ignoring it in serialization. I guess I'll add a doc PR for that since I assume that's also an issue in older versions.

yobrx commented 2 years ago

Hi,

How initialize input DTO for partial update on 2.7/3.0 ?

DataTransformerInitializerInterface is deprecated on 2.7, removed on 3.0 but i can't found an alternative for this.

I must use DenormalizerInterface ?

rvanlaak commented 2 years ago

Not sure if this also is the place where to report 3.0.0-rc.2 issues, but I've created https://github.com/api-platform/core/issues/4897 for an exception on GraphiQL when twig is not enabled.

Zul3s commented 2 years ago

Hello @yobrx , Api Platform >= 2.7 "replace" DateTransformer by State providers and State processors. You can found documentation here : https://api-platform.com/docs/main/core/dto/ . Please, make sur you use documentation for 2.7 (on the top at left).

RobinHoutevelts commented 2 years ago

( Also unclear to me how to migrate from DataTransformerInitializerInterface. Even after reading the docs. For example I just want to update the title attribute without having to send all other attributes. )

yobrx commented 2 years ago

@Zul3s Hello ! I have read the good page of documentation before post my message, and unlike version 2.6, 2.7 doesn't mention how to proceed for a patch :(

lchrusciel commented 2 years ago

Minor thing -

the ApiPlatform\Core\Metadata\Resource\ResourceNameCollection class exists in AP2.6, but it was moved to ApiPlatform\Metadata\Resource\ResourceNameCollection, the Core was removed. It is not a big problem, but kind of BC Break

alanpoulain commented 2 years ago

@lchrusciel I think this behavior is normal: if you migrate from 2.6 to 2.7 you should have deprecations for the namespace changes. Once you have resolved the deprecations, the upgrade path is to migrate your attributes and disable the BC layer (metadata_backward_compatibility_layer: false). And then you can upgrade to 3.0. More details here: https://api-platform.com/docs/main/core/upgrade-guide/

Zul3s commented 2 years ago

Hello @vincentchalamon , Did you have any news ? Can i help you ?

vincentchalamon commented 2 years ago

Hi @Zul3s, the PR is still in review. But as a lot of people are still in holidays, reviews can be slower than usual.

MariusJam commented 2 years ago

Hi,

I'm currently testing the upgrade to API-P 2.7-rc2 and I have question regarding custom doctrine extensions. We are indeed using a lot of those currently and have implemented them in the 2.6 way.

On 2.7, these extensions are not passed any more in the $extensions parameter of our DataProviders.

Given:

services:
    'App\DataProvider\CommitmentStepDataProvider':
        arguments:
            $extensions: !tagged api_platform.doctrine.orm.query_extension.collection
class CommitmentStepDataProvider implements ContextAwareCollectionDataProviderInterface
{
    public function __construct(
        iterable $extensions
    ) {
        foreach ($extensions as $extension) {
            dump($extension);
        }
    }
}

Is that normal that there is no backward compatibility here?

soyuka commented 2 years ago

@MariusJam does the debug:container with the extension tag shows your extensions ? What interface do you use ? The metadata flag was kept to default ?

MariusJam commented 2 years ago

Hi @soyuka,

debug:container shows the extensions both in 2.6 and 2.7. However, in 2.7, the tags row is empty whereas it is not in 2.6:

---------------- --------------------------------------------------- 
  Option           Value                                              
 ---------------- --------------------------------------------------- 
  Service ID       App\Doctrine\InscriptionCollectionFilterExtension  
  Class            App\Doctrine\InscriptionCollectionFilterExtension  
  Tags             -                                                  
  Public           no                                                 
  Synthetic        no                                                 
  Lazy             no                                                 
  Shared           yes                                                
  Abstract         no                                                 
  Autowired        yes                                                
  Autoconfigured   yes                                                
 ---------------- --------------------------------------------------- 

Concerning the interfaces, that depends of the extension but we can use:

But in each case, the tags row remains empty in 2.7.

For the metadata flag, I've just upgraded to 2.7 so far so yes, I kept it to default.

soyuka commented 2 years ago

Okay this is because you rely on autoconfiguration, I'll provide a fix thanks for the details.

DesLynx commented 2 years ago

Hi!

The Cursor Based Pagination doesn't seems to work.

RobinHoutevelts commented 2 years ago

Why has this issue been closed?

norkunas commented 2 years ago

( Also unclear to me how to migrate from DataTransformerInitializerInterface. Even after reading the docs. For example I just want to update the title attribute without having to send all other attributes. )

So are there any suggestions how to work with input dto without DataTransformerInitializer for PUT requests?