Andrei Herford
Andrei Herford

Reputation: 18729

Symfony2 + FOS RestBundle: Filter/clear JSON request before applying ParamConverter

I am working on a Symfony 2 WebApp that provides a JSON webservice to communicate with mobile apps on different platforms (iOS, Android, etc.).

The WebApp uses the FOS RestBundle to process and deserialize the received the JSON data:

# app/config/config.yml
sensio_framework_extra:
    request: { converters: true }

fos_rest:
    ...
    body_converter:
        enabled: true


/**
 * Sync Controller implementation
 * @ParamConverter("post", converter="fos_rest.request_body")
 */
public function syncAction(SyncBag $syncBag) {
    // ...
}


/**
 * Sync Data Wrapper
 */
public class SyncBag {
    ...
    /**
     * @JMS\Type("DateTime<'Y-m-d'>")
     */
    private $startDate;
}

This works quite well. The Problem: Some of the mobile Apps use a wrong date format to send some of the data: While the WebApp expects "Y-m-d" the mobile Apps send "Y-m-d H:i:s". This leads to an exception:

Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\BadRequestHttpException: "Invalid datetime "2016-03-04 12:00:00", expected format Y-m-d." at /.../vendor/friendsofsymfony/rest-bundle/FOS/RestBundle/Request/AbstractRequestBodyParamConverter.php line 113

Of course updating the mobile apps to use/send the correct date format is the correct solution for this error. But implementing and publishing this bugfix will take quite a while. Passing Apples review will take some time. Waiting for the users to update the latest version will take some time. And so on.

On the other hand the problem could quite easily be solved by updating the deserializing process in the WebApp.

Question: Is it somehow possible to hook into the deserializing process within the FOS RestBundle ParamConverter? If I could filter/clean the request (simpley search/replace wrong date formats) before the data is handled by the Converter, the problem could be solved within minutes.

Any idea/suggestion how to do this?

Thanks!

Upvotes: 0

Views: 391

Answers (2)

Arthur
Arthur

Reputation: 2889

You're can create event listener for pre deserialize event

Example for JMSSerializer

This is dispatched before an object is deserialized. You can use this to modify submitted data, or modify the type that is being used for deserialization.

Also, you're can create listener for kernel.request (or for kernel.controller with priority bigger than param converter listener priotity) event, and filter data as need.

Upvotes: 1

LBA
LBA

Reputation: 4089

Why not create your own ParamConverter extending/using what you need from the existing ones (e.g. in your case from the built in DateTime ParamConverter, see documentation)

You can even set a priority for ParamConverters to be sure one is executed before another.

Or is there anything special you'd like to achieve here?

Upvotes: 1

Related Questions