The public process method on the classes extending the ResourceBase can have different definitions depending on the request method. When trying to handle GET and POST on the same route with:

methods: ['GET', 'POST']

I need:

GET:
public function process(Request $request): ResourceResponse

POST:
public function process(Request $request, JsonApiDocumentTopLevel $document): ResourceResponse

Because the arguments depend on the process definition:

$args = $this->argumentResolver->getArguments($request, [$resource, 'process']);
$response = $resource->process(...$args);

I can't make both methods work with an unique definition of the process function. Adding a default NULL value on the $document doesn't work on POST either.

I could create a custom _controller and handle the logic depending on the request method or have one separated route per method. But I think this could be a common enough use case to be supported within the module.

Is there a different approach? Am I missing something?

What do you think?
Thanks.

Comments

sam711 created an issue. See original summary.

sam711’s picture

Looking further into this I found that this code (default NULL value for $document) ...

public function process(Request $request, JsonApiDocumentTopLevel $document = NULL): ResourceResponse

doesn't work because of the order of the arguments in jsonapi_resources.controller.argument_resolver. The default resolver is being processed before than the document resolver.

  jsonapi_resources.controller.argument_resolver:
    class: Symfony\Component\HttpKernel\Controller\ArgumentResolver
    arguments: ['@http_kernel.controller.argument_metadata_factory', ['@argument_resolver.request_attribute', '@argument_resolver.raw_parameter', '@argument_resolver.request', '@argument_resolver.psr7_request', '@argument_resolver.route_match', '@argument_resolver.default', '@jsonapi_resources.argument_resolver.document']]
    public: false

It looks like it's working if I change the order to:

  jsonapi_resources.controller.argument_resolver:
    class: Symfony\Component\HttpKernel\Controller\ArgumentResolver
    arguments: ['@http_kernel.controller.argument_metadata_factory', ['@argument_resolver.request_attribute', '@argument_resolver.raw_parameter', '@argument_resolver.request', '@argument_resolver.psr7_request', '@argument_resolver.route_match', '@jsonapi_resources.argument_resolver.document', '@argument_resolver.default']]
    public: false

Are you aware of any side effects if we change the order?

This would solve the problem of supporting several methods with the same route/controller.

sam711’s picture

Title: How to allow GET and POST to be handled with the same _jsonapi_resource class » Resolve document before default in the argument_resolver service
Version: 8.x-1.0-beta1 » 8.x-1.x-dev
Category: Support request » Bug report
StatusFileSize
new1.1 KB

Patch changing the order of the arguments.

sam711’s picture

sam711’s picture

Status: Active » Needs review
sam711’s picture

Tests fixed, passing now.

mglaman’s picture

Assigned: Unassigned » mglaman

I think this makes sense, as default is supposed to be last. I'll take a look at this before we fix #3096424: The service argument_resolver.raw_parameter has been removed

sam711’s picture

Thanks!

sam711’s picture

StatusFileSize
new1.06 KB

See if this works for both issues since both are changing the same line.

sam711’s picture

sam711’s picture

The reason for changing the argument order is that when the default value is specified, the argument_resolver.default returns NULL and ends the chain, so jsonapi_resources.argument_resolver.document never runs.

Changing the order affects the chain resolver flow.

Sorry for not being able to make it clear before. Thanks @mglaman and @gabesullice!

mglaman’s picture

Assigned: mglaman » Unassigned
Status: Needs review » Reviewed & tested by the community

  • mglaman committed aa42e72 on 8.x-1.x authored by sam711
    Issue #3094907 by sam711: Resolve document before default in the...
mglaman’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.