Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cloudevents Laravel Package

juststeveking/cloudevents

A Laravel/PHP package for working with CloudEvents, the CNCF specification for describing event data consistently across services. Create standardized event objects and integrate them into event-driven Laravel applications and service-to-service workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

This is the initial 0.0.1 release of juststeveking/cloudevents, a PHP implementation of the CNCF CloudEvents specification with Laravel-friendly ergonomics. Treat this as a pre-1.0 preview: the value objects and public API can change without a major version bump, so pin the exact version ("juststeveking/cloudevents": "0.0.1") in composer.json while you evaluate.

Minimal steps:

  1. Install with composer require juststeveking/cloudevents. If a service provider/config is registered via laravel-package-tools, run php artisan vendor:publish --tag="cloudevents-config" and inspect the published config for defaults (source, spec version, serializer options).
  2. Read src/ first, not just the README. In a 0.0.1 there is usually one central value object (a CloudEvent type) plus serializer/transformer classes. Skim the constructor signature — required fields per the spec are id, source, specversion, and type; subject, time, datacontenttype, and data are optional.
  3. Open the test suite (tests/) — this is the most reliable documentation of intended usage at this stage, since the changelog is an empty commit link.
  4. First real use case: model an outgoing domain event. Build a CloudEvent in a listener or job, serialize it to structured JSON, and push it to a queue, webhook, or broker. That single path exercises most of the package surface and tells you quickly whether the API fits your codebase.

Implementation Patterns

Build events at the boundary, not in your domain. Keep your domain events plain Laravel events and map them to CloudEvents in a dedicated listener or a small CloudEventFactory of your own. This insulates you from API churn in a 0.0.1 package and keeps the CNCF envelope out of your business logic.

final class CloudEventFactory
{
    public static function fromOrderPlaced(OrderPlaced $event): CloudEvent
    {
        return new CloudEvent(
            id: (string) Str::uuid(),
            source: '/orders',
            type: 'com.example.order.placed',
            specVersion: '1.0',
            subject: (string) $event->order->id,
            time: now(),
            data: $event->order->toArray(),
        );
    }
}

Prefer structured content mode for internal traffic. Structured mode (the whole envelope as one JSON body) is easier to log, replay, and debug than binary mode. Reserve binary mode (ce-* headers with the payload as body) for the specific brokers or HTTP receivers that demand it — and note that binary mode is only spec-compliant over HTTP, so don't hand-roll it for AMQP unless the package or broker client does it for you.

Wire serialization through Laravel's queue. A clean pattern is a SendCloudEvent job that accepts the value object, serializes it in handle(), and posts it with Http::withHeaders(...). Serialize inside the job rather than in the constructor so retries and failed() hooks see the same envelope, and so you avoid serializing objects into the queue payload.

Use extensions for tenant/correlation data. CloudEvents extensions (lowercase alphanumeric attribute names) are the sanctioned place for tenantid, correlationid, and traceparent. Avoid stuffing these into data — consumers filtering on envelope attributes can't see them there. If the package exposes an extensions array or a withExtension() style method, standardize on it early.

Test against the JSON shape, not the classes. Assert on the serialized envelope, since that is your actual contract with consumers:

$payload = CloudEventFactory::fromOrderPlaced($event)->toArray();

$this->assertSame('1.0', $payload['specversion']);
$this->assertSame('/orders', $payload['source']);
$this->assertArrayHasKey('id', $payload);

This keeps your tests valid even if the package renames methods.

Integration tip: one adapter, one place. If you consume CloudEvents too (webhook receiver, queue consumer), write a single controller/middleware that hydrates an incoming envelope and rejects anything missing required attributes. Don't scatter json_decode + array access across controllers.

Gotchas and Tips

  • Version pinning is the main gotcha. At 0.0.1 there is no stability guarantee and the changelog entry is literally just a link to the commit list. Pin exactly, and re-read the diff before every bump.
  • Validate required attributes yourself. A value object may accept a null or empty id/source/type if the constructor lacks guards. Add an explicit validation step (or a failing test) so malformed events never reach a broker. Per spec, id + source must be unique per event — generate a UUID or ULID per emission, never reuse one across retries of different events.
  • time must be RFC3339. If you pass a Carbon instance, confirm what gets emitted (toRfc3339String(), not toDateTimeString()). Timezone offsets and microseconds are the usual source of consumer-side parse failures.
  • Content type matters. Set datacontenttype to application/json when data is an array/object; omit it (or use application/octet-stream) for raw strings. Consumers deciding how to decode the payload rely on this field, not on sniffing.
  • Don't double-encode. A frequent bug is passing json_encode($data) as data, which then gets encoded again by the structured serializer, producing a JSON string instead of an object. Pass the PHP array and let the package encode it.
  • Naming rules for extensions. Attribute names must be lowercase alphanumeric; no hyphens, underscores, or camelCase. correlation-id will be rejected by strict consumers.
  • Debugging: dump the serialized envelope (->toArray() / ->toJson()) rather than the object graph. Most issues are attribute naming, missing specversion, or a nested-encoding mistake, all visible in the JSON. If the package ships a config-driven default source or specversion, verify the resolved config isn't overriding the value you passed explicitly.
  • Extension points to watch for: if a CloudEventSerializer-style contract or a CloudEvent interface exists, bind your own implementation in a service provider rather than forking. That is the cheapest way to survive API changes — implement against the interface, not the concrete class, in your own application code.
  • Avoid adopting it for inbound binary-mode parsing yet. Hand-rolled header parsing is where early CloudEvents libraries tend to have the most gaps (case-insensitive headers, quoted values, ce- prefix handling). If you must consume binary mode, wrap it with tests for those cases before trusting it in production.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package