brefphp / symfony-messenger

Bridge to use Symfony Messenger on AWS Lambda with Bref
MIT License
72 stars 22 forks source link

How to specify different serializer for each Lambda / transport? #86

Open Maxell92 opened 6 months ago

Maxell92 commented 6 months ago

We are processing messages from different producers in our Lambdas, so we need different Serializers. This is an example of our definition:

framework:
    messenger:

        transports:
            priority:
                dsn: '%env(xxx)%'
                serializer: messenger.transport.symfony_serializer
            dataUpdate:
                dsn: '%env(xxx)%'
                serializer: App\DataUpdate\DataUpdateMessageSerializer
            priceUpdate:
                dsn: '%env(xxx)%'
                serializer: App\PriceUpdate\PriceUpdateMessageSerializer

According to the documentation, I tried to specify a serializer for SqsConsumer. But how to add them there? It is possible to specify only 1 serializer there.

starred-gijs commented 6 months ago

I have a similar use-case and I was able to get it working by separating the transports (SQS queues), linking to different lambdas, which have different handlers.

The following code snippets are incomplete!

serverless.yaml

functions:
  sqs-messenger-handler:
    handler: src/messenger-sqs.php
    description: 'SQS handler for Symfony Messenger'
    events:
      - sqs:
          arn:
            Fn::GetAtt: [SqsMessengerQueue, Arn]
          batchSize: 1   

  sqs-messenger-serializer:
    handler: src/messenger-sqs-symfony-serializer.php
    description: 'SQS handler for Symfony Messenger - with Symfony Serializer'
    events:
      - sqs:
          arn:
            Fn::GetAtt: [OtherSqsMessengerQueue, Arn]
          batchSize: 1

And in those php files, return a different service from the container src/messenger-sqs.php

return $kernel->getContainer()->get('bref.sqs_consumer');

src/messenger-sqs-symfony-serializer.php

return $kernel->getContainer()->get('bref.sqs_consumer.symfony_serializer');

Which are defined to have different serializers injected: services.yaml

services:
  bref.sqs_consumer:
    class: Bref\Symfony\Messenger\Service\Sqs\SqsConsumer
    public: true
    autowire: true
    arguments:
      $serializer: @Symfony\Component\Messenger\Transport\Serialization\SerializerInterface'

  bref.sqs_consumer.symfony_serializer:
    class: Bref\Symfony\Messenger\Service\Sqs\SqsConsumer
    public: true
    autowire: true
    arguments:
      $serializer: '@messenger.transport.symfony_serializer'

Hope this helps!