gurento/kafka-producer-filament

Filament UI package for the producer side of gurento/kafka-consumer.

Maintainers

Package info

github.com/fglend/kafka-producer-filament

pkg:composer/gurento/kafka-producer-filament

Transparency log

Statistics

Installs: 6

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-07-20 08:22 UTC

This package is auto-updated.

Last update: 2026-07-20 08:24:19 UTC


README

Latest Version on Packagist Total Downloads License

A Filament admin panel for the producer side of gurento/kafka-consumer — manage producer topic configs, compose and send Kafka messages, and monitor send health without leaving your admin panel.

Consuming too? The consumer-side UI lives in a separate companion package: gurento/kafka-consumer-filament. Install both if you need both directions — they share the same gurento/kafka-consumer backend but register independent Filament resources, so you can install either one alone.

Features

  • Producer topic management — key field, default headers, and an optional payload schema that drives the send composer
  • Dynamic schema from a model — pick a Source Model and auto-fill the payload schema and detected relationships from it, instead of hand-typing field names
  • Raw JSON payload template — a free-form textarea for the exact message template, editable directly and auto-filled once a model is picked
  • Send Message — compose and publish a message straight from the panel, with live JSON validation
  • Live monitoring — auto-polling table with produced/failed counters, failure rate, health badges
  • Produce logs — per-message log viewer with payload/header inspection and per-log retry
  • One-click operations — retry failed sends and reset counters from the UI
  • Fully customizable — navigation label, icon, group, badge, slug, labels, and polling are all configurable via a fluent plugin API

Requirements

Dependency Version
PHP 8.2+
Laravel 11 / 12 / 13
Filament 4.x / 5.x
gurento/kafka-consumer ^1.0

Installation

1. Install the packages

This plugin is the UI layer for the producer side of gurento/kafka-consumer, which does the actual sending. Install both:

composer require gurento/kafka-consumer gurento/kafka-producer-filament

2. Set up gurento/kafka-consumer

Publish the config and migrations, then migrate:

php artisan vendor:publish --tag=kafka-consumer-config
php artisan vendor:publish --tag=kafka-consumer-migrations
php artisan migrate

This publishes migrations for both sides of gurento/kafka-consumer. The tables this package's UI manages:

  • kafka_producer_topics — producer topic config, counters, and health metadata (what this plugin manages)
  • kafka_produce_logs — per-message send logs (what the logs viewer reads)

(kafka_topics / kafka_consume_logs are the consumer-side tables — relevant only if you also install gurento/kafka-consumer-filament or consume messages directly.)

Review config/kafka-consumer.php for producer defaults (producer.max_send_attempts, producer.send_backoff_seconds). The producer ships with a plug-and-play engine based on mateusjunges/laravel-kafka — make sure the rdkafka PHP extension is installed and your broker settings are configured in the host app's config/kafka.php.

Add your Kafka connection settings to .env:

KAFKA_BROKERS=localhost:9092
KAFKA_DEBUG=false
  • KAFKA_BROKERS — comma-separated broker list (host:port)
  • KAFKA_DEBUG — set to true to enable verbose librdkafka debug output while troubleshooting

3. Register the plugin

In your Filament panel provider:

use Gurento\KafkaProducerFilament\Filament\Plugins\KafkaProducerPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            KafkaProducerPlugin::make(),
        ]);
}

That's it — a Kafka Producers resource appears in your panel's navigation.

4. Send a message

Create a producer topic mapping in the UI, then either click Send Message on the record, or send from the CLI:

php artisan gurento:kafka-produce --topic=APP.LIVE.orders --payload='{"uuid":"ord-001","status":"paid"}'

See the gurento/kafka-consumer README for full command options (--topic, --payload, --key, --retry-failed, --retry-limit), events, and custom engines.

Customization

Every presentation element is dynamic. Configure it fluently on the plugin — each setter accepts a plain value or a Closure:

KafkaProducerPlugin::make()
    ->navigationLabel('Event Publishers')          // sidebar title
    ->navigationIcon('heroicon-o-megaphone')      // hero icon (string or BackedEnum)
    ->navigationGroup('Integrations')
    ->navigationSort(6)
    ->navigationBadge()                           // badge showing pending retries
    ->modelLabel('Publisher')
    ->pluralModelLabel('Publishers')
    ->slug('event-publishers')                    // URL: /admin/event-publishers
    ->tablePollInterval('30s'),                   // null disables auto-refresh

Available options

Method Type Default Description
navigationLabel() string|Closure Kafka Producers Sidebar navigation title
navigationIcon() string|BackedEnum|Closure heroicon-o-arrow-up-on-square Navigation icon
navigationGroup() string|UnitEnum|Closure System Navigation group
navigationSort() int|Closure Filament default Sort order within the group
navigationBadge() bool|Closure false Show pending-retry count as a badge
modelLabel() / pluralModelLabel() string|Closure kafka producer topic(s) Record labels used across pages
slug() string|Closure kafka-producer-topics Resource URL slug
tablePollInterval() string|null|Closure 10s Table auto-refresh interval; null disables
modelOptions() array|Closure app/Models scan Options for the Source Model dropdown

All options are optional — KafkaProducerPlugin::make() alone keeps the defaults above.

Creating a Producer Topic & Sending Messages

Producer Topic Configuration

Field Description
Kafka Topic The topic name to publish to (e.g. APP.LIVE.orders), unique per row
Source Model Optional. An Eloquent model (searchable dropdown, scanned from app/Models — override via modelOptions()) used purely to auto-fill the schema and relations below; it has no runtime effect on sending
Key Field Payload field used as the Kafka message key when no explicit key is given at send time
Active Toggle whether the topic accepts sends
Retry settings Max send attempts and retry backoff (seconds) — per topic, falling back to config when unset

Dynamic Schema & Relations from a Model

Pick a Source Model, then click Auto-fill from Model (or just pick the model — it auto-fills automatically the first time, as long as the schema/relations sections are still empty):

  • Payload Schema is populated from the model's database table columns, with types inferred from the column's DB type (integer/decimal/boolean/json map to the matching schema type, everything else defaults to string). Timestamp columns (created_at, updated_at, deleted_at) are skipped.
  • Relations is populated by reflecting over the model's own public, zero-argument methods and keeping the ones that return an Eloquent relationship (belongsTo, hasMany, belongsToMany, morphMany, etc.) — capturing the relationship name, its type, and the related model class.

Both sections remain fully editable afterward — add, remove, or hand-edit any row. Auto-fill only fires automatically the first time (when Payload Schema, Relations, and the raw Payload Template below are all still empty), so picking a different model later won't silently overwrite edits you've made; use the Auto-fill from Model button to force a re-sync.

This is a schema-authoring convenience, not a live data binding. Selecting a Source Model does not change how sending works — the Send Message composer still expects you to fill in (or paste) the actual JSON payload; the model only feeds the field-name/relation-name template so operators aren't guessing at spellings. Relation names appear in the send template as an empty array ("items": []) for you to fill in.

Payload Template (Raw JSON)

Alongside the structured Payload Schema/Relations repeaters, every producer topic has a raw JSON textarea — full freedom to hand-write or paste the exact template you want, no repeater rows required. When you pick a Source Model (or click Auto-fill from Model), this textarea is populated with a pretty-printed JSON object built from the detected columns and relations, ready to edit directly.

This raw template — when set — is what actually pre-fills the Send Message composer's payload field, taking priority over building one from the Payload Schema/Relations repeaters. Leave it blank and the composer falls back to generating a template from those repeaters instead, so existing topics created before this field existed keep working unchanged.

Relation detection only sees methods declared directly on the model class itself (not inherited from traits or a base model class), and — since it works by invoking each candidate method — assumes those methods are safe to call with no side effects, which is true for standard Eloquent relationship definitions.

Default Headers

A repeater of name → value pairs merged into every message sent to the topic — useful for a constant source or content-type header without repeating it on every send.

Payload Schema (optional)

A repeater of {name, type, required} field definitions. It doesn't validate the payload — it exists purely to pre-fill the Send Message composer with a JSON template matching your expected shape, so operators don't have to remember the field names by heart.

Sending a Message

Open a producer topic and click Send Message:

  1. Optionally enter a Message Key — leave it blank to auto-resolve from the payload using the topic's key field.
  2. Edit the Payload (JSON) textarea — pre-filled from the payload schema if one is defined.
  3. Confirm. The message publishes to the broker immediately; the result (sent or failed) is logged and shown as a notification.

Given a topic with key field uuid and payload

{ "uuid": "ord-001", "status": "paid" }

the message key resolves to ord-001 automatically if you don't type one.

Typical Workflow

  1. Open Kafka Producers in your panel.
  2. Create a producer topic: topic name, key field, optional default headers and payload schema.
  3. Click Send Message on the record (or send from the CLI/programmatically).
  4. Monitor counters, health, and logs in the resource (the table auto-refreshes).
  5. Retry failed sends from the row action or the produce-logs relation manager when needed.

What It Registers

  • KafkaProducerTopicResource — list, create, view, and edit pages
  • ProduceLogsRelationManager — read-only send-log browser with payload/header inspection and per-log retry
  • Row/header actions: Send Message, Retry Failed, Reset Counters

At-Least-Once Semantics

If a broker acknowledgment is lost after the message was actually received, retrying a "failed" send can produce a duplicate. Design downstream consumers to be idempotent (e.g. upsert by a stable key) when replaying producer retries — see the core package's README for details.

Security & Access

This package ships UI classes only — it does not impose authorization. Define policies/permissions in your host app to control who can:

  • edit producer topic configs
  • send messages
  • inspect payload and error logs

Troubleshooting

Resource not visible — ensure the plugin is registered on the panel you're viewing, then run php artisan optimize:clear.

Class not found — confirm both packages are installed and run composer dump-autoload.

Customizations not applying — plugin options are read at runtime from the current panel; make sure you configure them on the same KafkaProducerPlugin::make() instance passed to ->plugins([...]).

Message shows "Invalid payload" on send — the payload textarea must be valid JSON (an object, not a bare string or array); check for trailing commas or unescaped quotes.

Changelog

See CHANGELOG.md for release history.

License

The MIT License (MIT). See LICENSE for details.