PHPackages                             atoms/symfony - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. atoms/symfony

ActiveSymfony-bundle

atoms/symfony
=============

Symfony bundle for Atoms: AtomsClient, the inbound callback stack, PSR-17/18 resolution, a Messenger queue bridge, and console wrappers around the atoms binary.

0.1.0(yesterday)00MITPHPPHP ^8.3

Since Aug 14Pushed todayCompare

[ Source](https://github.com/AtomsPHP/symfony)[ Packagist](https://packagist.org/packages/atoms/symfony)[ Docs](https://atomsphp.dev)[ RSS](/packages/atoms-symfony/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (10)Versions (2)Used By (0)

atoms/symfony
=============

[](#atomssymfony)

The supported Symfony bundle for Atoms wires `Atoms\Client\AtomsClient`, the inbound callback stack (Ed25519 verification, Methods dispatch, AtomJob reconstruction), a Messenger-backed queue bridge, and thin console wrappers around the `atoms` binary — all on top of `atoms/client` alone. `atoms/client` is deliberately framework-free (integration-plan §5.3), so this bundle depends on `atoms/client` and Symfony components only; it never needs `Atoms\Laravel\*` or `Illuminate\*` (`tests/LayeringTest.php` is the mechanical check, and `docs/conventions.md` the rule it enforces).

Install
-------

[](#install)

`config/bundles.php`:

```
return [
    // ...
    Atoms\Symfony\AtomsBundle::class => ['all' => true],
];
```

`config/packages/atoms.yaml`:

```
atoms:
    environment: '%env(APP_ENV)%'
    endpoint: https://atoms.your-subdomain.workers.dev   # your own deployed Worker
    api_key: '%env(ATOMS_API_KEY)%'                      # null when the Worker's ATOMS_APP_KEY is unset
    timeout: 10.0
    max_attempts: 3
    platform_public_key: '%env(ATOMS_PLATFORM_PUBLIC_KEY)%'
    callback_path: /atoms/callback
    callback_timestamp_window: 300   # seconds of clock skew a callback's timestamp may deviate before rejection
    http_client: null                # service id, or null to auto-detect / fall back to Guzzle
    psr17_factory: null              # service id, or null to fall back to Guzzle (no auto-detection — see "What's wired")
    methods_classes:
        - App\Atoms\GameRoom\Methods   # only needed for #[MethodsFor] overrides
```

Mount the callback route
------------------------

[](#mount-the-callback-route)

Import the `atoms` resource type from your own routing, e.g. `config/routes/atoms.yaml`:

```
atoms:
    resource: .
    type: atoms
```

There is no vendor path to import — `Atoms\Symfony\Routing\AtomsRouteLoader`is registered as a `routing.loader`-tagged service and resolves the `atoms`type itself. It always mounts at the bundle's current `atoms.callback_path`, so reconfiguring that value moves the route with it; nothing else needs to change.

What's wired
------------

[](#whats-wired)

- `Atoms\Client\AtomsClient` — the RPC stub-proxy client, service id `atoms.client` (public; the `AtomsClient::class` service itself is private).
- The callback stack — `Ed25519Verifier`, `InMemoryNonceStore`, `MethodsResolver`, `CallbackKernel` — plus `Atoms\Symfony\Controller\CallbackController`, which converts Symfony `Request`/`Response` to/from PSR-7 by hand against the plain `ServerRequestFactoryInterface`/`StreamFactoryInterface` (no `psr/http-message-bridge` dependency); routed automatically as described above.
- A PSR-17 factory (`ServerRequestFactoryInterface` + `StreamFactoryInterface`
    - `ResponseFactoryInterface` in one — `GuzzleHttp\Psr7\HttpFactory` and `Nyholm\Psr7\Factory\Psr17Factory` both qualify) resolved, in order: the service id in `psr17_factory`, else a bundled `GuzzleHttp\Psr7\HttpFactory`(clear exception if `guzzlehttp/psr7` isn't installed). No auto-detection: PSR-17 spans several factory interfaces, so the bundle never guesses which app service should serve all of them — name it explicitly in `psr17_factory` or accept Guzzle. Backs `CallbackKernel`, `CallbackController` and `AtomsClient` alike. Resolved in a compiler pass so bundle registration order never matters.
- A PSR-18 client resolved, in order: the service id in `atoms.http_client`, else an app-defined `Psr\Http\Client\ClientInterface` service, else a `GuzzleHttp\Client` (clear exception if `guzzlehttp/guzzle` isn't installed). Resolved in a compiler pass so bundle registration order never matters.
- `Atoms\Client\Callback\QueueBridge`: `Atoms\Symfony\Messenger\MessengerQueueBridge`when `symfony/messenger` is installed and the app has a message bus service, wrapping dispatched `AtomJob`s as `AtomJobMessage` (normalized, JSON-safe constructor args only) and handling them back via `AtomJobHandler`; otherwise `Atoms\Client\Callback\NullQueueBridge`, which throws a clear "configure a QueueBridge" exception on first use.
- Methods resolution: every `methods_classes` entry is registered on the `MethodsResolver` by name (for `#[MethodsFor]` overrides) *and* as an autowired service, collected into a `Symfony\Component\DependencyInjection\ServiceLocator`that `CallbackKernel` consults first — so a listed Methods class can itself take app services as constructor dependencies. Anything not listed is instantiated with `new $class()`.
- A logger: `CallbackKernel` takes the app's `logger` service if one exists (Monolog via FrameworkBundle, or anything else bound to that id) and `null`otherwise — never a hard dependency on `psr/log`'s presence being wired up.
- `atoms:deploy`, `atoms:rollback`, `atoms:list` — thin console wrappers that shell out to the real `atoms` binary (discovered via `vendor/bin/atoms`, then `$PATH`, then `packages/cli/bin/atoms`); registered only when `symfony/console` is present.

Supplying your own
------------------

[](#supplying-your-own)

Every auto-detected collaborator has an explicit override point:

- **HTTP client** — set `http_client` to a service id, or just register your own `Psr\Http\Client\ClientInterface` service and leave it null.
- **PSR-17 factory** — set `psr17_factory` to a service id implementing `ServerRequestFactoryInterface`, `StreamFactoryInterface` and `ResponseFactoryInterface`.
- **Queue bridge** — install `symfony/messenger` and register a message bus, or bind your own `Atoms\Client\Callback\QueueBridge` implementation to that service id directly.
- **Nonce store** — the bundle wires `Atoms\Client\Callback\InMemoryNonceStore`(process-local, not shared across workers); alias `Atoms\Client\Callback\NonceStore` to your own implementation (e.g. Redis-backed) for a multi-process deployment.
- **Methods classes** — list them under `methods_classes` to get container resolution (and `#[MethodsFor]` support); anything else resolves by naming convention with `new $class()`.
- **Logger** — register any service under the id `logger` (FrameworkBundle does this for you when Monolog is installed).

Not yet supported
-----------------

[](#not-yet-supported)

Methods classes resolve from the container only when listed under `methods_classes`; anything not listed there is instantiated with `new $class()` rather than autowired, even if the class itself would otherwise be autowirable.

Development and support
-----------------------

[](#development-and-support)

This package is developed in the [Atoms monorepo](https://github.com/AtomsPHP/atoms). Its standalone repository is a read-only distribution mirror; report issues and send pull requests to the monorepo. Full documentation is at [docs.atomsphp.dev](https://docs.atomsphp.dev). Licensed under the [MIT License](LICENSE).

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 Bus Factor1

Top contributor holds 85.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2709404?v=4)[Daniel Abernathy](/maintainers/dabernathy89)[@dabernathy89](https://github.com/dabernathy89)

---

Top Contributors

[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (6 commits)")[![dabernathy89](https://avatars.githubusercontent.com/u/2709404?v=4)](https://github.com/dabernathy89 "dabernathy89 (1 commits)")

---

Tags

symfonyatoms

### Embed Badge

![Health badge](/badges/atoms-symfony/health.svg)

```
[![Health](https://phpackages.com/badges/atoms-symfony/health.svg)](https://phpackages.com/packages/atoms-symfony)
```

###  Alternatives

[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

86337.5k](/packages/flow-php-flow)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.8M668](/packages/shopware-core)[shopware/platform

The Shopware e-commerce core

3.4k1.5M3](/packages/shopware-platform)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6943.5M448](/packages/drupal-core-recommended)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[symfony/framework-bundle

Provides a tight integration between Symfony components and the Symfony full-stack framework

3.6k257.3M12.3k](/packages/symfony-framework-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
