Albertobeiz

Albertobeiz

Symfony Tips #06 - Decode input in an Event Subscriber

Symfony Tips #06 - Decode input in an Event Subscriber

Subscribe to my newsletter and never miss my upcoming articles

🖥 Symfony Tips: Quick and practical tricks to develop solid backend systems.

Let's remove some non-business related dependencies from the constructor. We'll start with input decoding using a Symfony EventSubscriber.

This is OK

public function __invoke(Request $request): Response
{
    $body = json_decode($request->getContent(), true);

     if($this->userRepository->findOneBy(['email' => $body['email']])) {
         return new Response('[Error] Email Already Exists', Response::HTTP_CONFLICT);
     }
    .
    .
    .
}

This is better

We move the decoding logic to an EventSubscriber and use the request

public function __invoke(Request $request): Response
{
     if($this->userRepository->findOneBy(['email' => $request->get('email')])) {
         return new Response('[Error] Email Already Exists', Response::HTTP_CONFLICT);
     }
    .
    .
    .
}

Decode JSON only if the request has the correct header

namespace App\SymfonyEventSubscriber;

class OnRequest_DecodeBody implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): iterable
    {
        return [
            KernelEvents::REQUEST => 'onRequest'
        ];
    }

    public function onRequest(RequestEvent $event): void
    {
        $request = $event->getRequest();
        $contentType = $request->headers->get('Content-Type');

        if (str_starts_with($contentType, 'application/json')) {
            $data = json_decode($request->getContent(), true);
            $request->request->replace(is_array($data) ? $data : []);
        }
    }
}

Why?

As stated before, we are removing as much logic as we can from Use Cases, to improve testability and reduce bugs, and parsing JSON is definitely not a business related problem.

You can re-run test.sh to see that everything keeps working.

Symfony tip completed 👍! Check the final code and leave a ⭐️!

Next Tip -> Symfony Tips #07 - Serialize output in an Event Subscriber

Previous Tip -> Symfony Tips #05 - One line per service

HEY! Follow me at @albertobeiz if you found this tip useful or have any question.

Interested in reading more such articles from Alberto Beiz?

Support the author by donating an amount of your choice.

 
Share this