Message handlers | Laravel Kafka              

 [ K Laravel Kafka ](/) [Docs](/docs) [Blog](https://laravelkafka.com/blog) [GitHub](https://github.com/mateusjunges/laravel-kafka) 

     Search ⌘K       [    Login with GitHub Login ](https://laravelkafka.com/oauth/github/redirect) 

    Docs for version         

   selected

 v3.0     

 v2.13     

 v2.12     

 v2.11     

 v2.10     

 v2.9     

 v2.8     

 v1.13   

- - [ Introduction ](/docs/v3.0/introduction)
    - [ Requirements ](/docs/v3.0/requirements)
    - [ Installation and Setup ](/docs/v3.0/installation-and-setup)
    - [ Questions and issues ](/docs/v3.0/questions-and-issues)
    - [ Changelog ](/docs/v3.0/changelog)
    - [ Upgrade guide ](/docs/v3.0/upgrade-guide)
    - [ Example docker-compose file ](/docs/v3.0/example-docker-compose)
- Producing messages
    ------------------

    - [ Producing messages ](/docs/v3.0/producing-messages/producing-messages)
    - [ Configuring your kafka producer ](/docs/v3.0/producing-messages/configuring-producers)
    - [ Configuring message payload ](/docs/v3.0/producing-messages/configuring-message-payload)
    - [ Custom serializers ](/docs/v3.0/producing-messages/custom-serializers)
    - [ Publishing to kafka ](/docs/v3.0/producing-messages/publishing-to-kafka)
- Consuming messages
    ------------------

    - [ Creating a kafka consumer ](/docs/v3.0/consuming-messages/creating-consumer)
    - [ Subscribing to kafka topics ](/docs/v3.0/consuming-messages/subscribing-to-kafka-topics)
    - [ Using regex to subscribe to kafka topics ](/docs/v3.0/consuming-messages/using-regex-to-subscribe-to-kafka-topics)
    - [ Assigning consumers to a topic partition ](/docs/v3.0/consuming-messages/assigning-partitions)
    - [ Consuming messages from specific offsets ](/docs/v3.0/consuming-messages/consuming-from-specific-offsets)
    - [ Consumer groups ](/docs/v3.0/consuming-messages/consumer-groups)
    - [ Partition Discovery and Dynamic Assignment ](/docs/v3.0/consuming-messages/partition-discovery)
    - [ Message handlers ](/docs/v3.0/consuming-messages/message-handlers)
    - [ Configuring consumer options ](/docs/v3.0/consuming-messages/configuring-consumer-options)
    - [ Handling failed messages ](/docs/v3.0/consuming-messages/handling-failed-messages)
    - [ Custom deserializers ](/docs/v3.0/consuming-messages/custom-deserializers)
    - [ Consuming messages ](/docs/v3.0/consuming-messages/consuming-messages)
    - [ Pausing partitions ](/docs/v3.0/consuming-messages/pausing-partitions)
    - [ Consumer classes ](/docs/v3.0/consuming-messages/class-structure)
    - [ Using consumers with Laravel Telescope ](/docs/v3.0/consuming-messages/laravel-telescope)
- Advanced usage
    --------------

    - [ Connections ](/docs/v3.0/advanced-usage/connections)
    - [ Replacing the default serializer/deserializer ](/docs/v3.0/advanced-usage/replacing-default-serializer)
    - [ Graceful shutdown ](/docs/v3.0/advanced-usage/graceful-shutdown)
    - [ Running consumers in production ](/docs/v3.0/advanced-usage/running-consumers-in-production)
    - [ SASL Authentication ](/docs/v3.0/advanced-usage/sasl-authentication)
    - [ Custom Committers ](/docs/v3.0/advanced-usage/custom-committers)
    - [ Manual Commit ](/docs/v3.0/advanced-usage/manual-commit)
    - [ Middlewares ](/docs/v3.0/advanced-usage/middlewares)
    - [ Stop consumer when there are no messages left ](/docs/v3.0/advanced-usage/stop-consumer-after-last-message)
    - [ Stop consumer on demand ](/docs/v3.0/advanced-usage/stopping-a-consumer)
    - [ Writing custom loggers ](/docs/v3.0/advanced-usage/custom-loggers)
    - [ Before and after callbacks ](/docs/v3.0/advanced-usage/before-callbacks)
    - [ Setting global configurations ](/docs/v3.0/advanced-usage/setting-global-configuration)
    - [ Sending multiple messages with the same producer ](/docs/v3.0/advanced-usage/sending-multiple-messages-with-the-same-producer)
    - [ Events ](/docs/v3.0/advanced-usage/events)
    - [ Consumer lag ](/docs/v3.0/advanced-usage/consumer-lag)
- Testing
    -------

    - [ Kafka fake ](/docs/v3.0/testing/fake)
    - [ Assert Published ](/docs/v3.0/testing/assert-published)
    - [ Assert published On ](/docs/v3.0/testing/assert-published-on)
    - [ Assert not published ](/docs/v3.0/testing/assert-not-published)
    - [ Assert nothing published ](/docs/v3.0/testing/assert-nothing-published)
    - [ Assert published times ](/docs/v3.0/testing/assert-published-times)
    - [ Assert published on times ](/docs/v3.0/testing/assert-published-on-times)
    - [ Mocking your kafka consumer ](/docs/v3.0/testing/mocking-your-kafka-consumer)

  Message handlers 
==================

Now that you have created your kafka consumer, you must create a handler for the messages it receives. A handler receives the consumed message and the consumer, and it can be a closure, an invokable class, or a class implementing the `Junges\Kafka\Contracts\Handler` interface. Use the `withHandler` method to specify your handler:

         ```
use Junges\Kafka\Contracts\Consumer;
use Junges\Kafka\Contracts\ConsumerMessage;

$consumer = \Junges\Kafka\Facades\Kafka::consumer(['orders'])
    ->withHandler(function (ConsumerMessage $message, Consumer $consumer) {
        // Handle your message here
    });
```

To keep a consumer and its configuration in a single class, see [ consumer classes ](class-structure).

  Sponsorship 

Support Laravel Kafka by sponsoring me!

Laravel Kafka is free and Open Source software, built to empower developers like you. Your support helps maintain and enhance the project. If you find it valuable, please consider sponsoring me on GitHub. Every contribution makes a difference and keeps the development going strong! Thank you!

 [   Become a Sponsor ](https://github.com/sponsors/mateusjunges) Want to hide this message? Sponsor at any tier of $10/month or more! 

[](#content-the-consumed-message "Permalink")The consumed message
-----------------------------------------------------------------

The `ConsumerMessage` contract gives you some handy methods to get the message properties:

- `getBody()`: the body of the message. With the default JSON deserializer, it is already decoded into an array.
- `getKey()`: the key of the message.
- `getHeaders()`: the headers of the message.
- `getTopicName()`: the topic the message was consumed from.
- `getPartition()`: the partition the message was consumed from.
- `getOffset()`: the offset of the message in its partition.
- `getTimestamp()`: the timestamp of the message, in milliseconds.
- `getMessageIdentifier()`: the id of the message. See [ message ids ](../producing-messages/configuring-message-payload#message-ids).
- `getAttempts()`: how many times the handler was called with this message, including the current call, when failed messages are [ retried ](handling-failed-messages).

[](#content-handler-classes "Permalink")Handler classes
-------------------------------------------------------

Handler classes implement the `Handler` interface:

         ```
use Junges\Kafka\Contracts\Consumer;
use Junges\Kafka\Contracts\ConsumerMessage;
use Junges\Kafka\Contracts\Handler;

class ProcessOrderHandler implements Handler
{
    public function __invoke(ConsumerMessage $message, Consumer $consumer): void
    {
        $order = $message->getBody();

        // Process the order
    }
}

$consumer = \Junges\Kafka\Facades\Kafka::consumer(['orders'])
    ->withHandler(new ProcessOrderHandler)
    ->build();

$consumer->consume();
```

[](#content-failures "Permalink")Failures
-----------------------------------------

When the handler throws an exception, the message is handled as failed: it is retried if the consumer [ retries failed messages ](handling-failed-messages#retrying-failed-messages), and then sent to the dead letter queue, skipped, or stops the consumer, depending on the configuration. Let exceptions propagate from your handler, since catching them without rethrowing makes the consumer move on as if the message was processed.

[](#content-committing-from-handlers "Permalink")Committing from handlers
-------------------------------------------------------------------------

The consumer passed to handlers can commit offsets itself, which is useful in [ manual commit ](../advanced-usage/manual-commit) mode:

         ```
$consumer = \Junges\Kafka\Facades\Kafka::consumer(['orders'])
    ->withManualCommit()
    ->withHandler(function (ConsumerMessage $message, Consumer $consumer) {
        processOrder($message->getBody());

        $consumer->commit($message);
    });
```

It can also stop the consumer, see [ stopping a consumer on demand ](../advanced-usage/stopping-a-consumer).

Previous

 [    Partition Discovery and Dynamic Assignment ](https://laravelkafka.com/docs/v3.0/consuming-messages/partition-discovery) 

Next

 [ Configuring consumer options    ](https://laravelkafka.com/docs/v3.0/consuming-messages/configuring-consumer-options) 

 Sponsors

 [ version="1.0" encoding="UTF-8"?       EasyCal ](https://easycal.app/) 

 [       Search  ⌘ K   ](https://typesense.org/)
