Callbacks
An Atom can cross from Atom-side back into the host application in two ways:
$this->app()->method(...)is synchronous reverse RPC into a method defined in an Atom’sMethodsclass.$this->dispatch(Job::class, [...])hands anAtomJobto the host’s queue bridge.
Configure the channel
Section titled “Configure the channel”For these callbacks to work, you must configure a shared secret and a callback URL. Each lives in a specific place:
environments.<name>.callback_urlinatoms.jsondeclares the committed default callback URL for a deploy target. The entry is optional, and an empty or absent one does not mean callbacks are unavailable — it only means the file supplies nothing, leaving the three nearer sources below to answer.ATOMS_CALLBACK_URLin.env.atoms.<environment>besideatoms.jsonsupplies the same value without editing anything committed — the file is gitignored, and read only for the target you named.ATOMS_CALLBACK_URLin the environment the command was started with — a CI job variable, say — outranks both.--callback-url, ondeployanddev, outranks all three.
The variable the selected Worker receives is also called ATOMS_CALLBACK_URL.
It is not a secret; the CLI forwards whichever of the four sources answered
first (see Callback URL below), and prints which one that was.
Callbacks are unavailable only when no source supplies a URL.
ATOMS_SHARED_SECRETis configured on both sides: as a secret on the Worker, and in your application’s.env(or equivalent). See Secrets and authentication for setting it.
Every callback POST is signed with a key derived from that secret, and your adapter verifies the signature before your Methods class or job runs. See the adapter contract for what a host must provide.
Callback URL
Section titled “Callback URL”Declare the URL on the environment it belongs to, beside its worker_name:
{ "environments": { "production": { "worker_name": "my-app", "callback_url": "https://example.com/atoms/callback" }, "staging": { "worker_name": "my-app-staging", "callback_url": "${STAGING_CALLBACK_URL}" } }}The whole value may be a ${ENV_VAR} reference, resolved against the same
environment sources as everything else and against nothing else. A literal
empty or whitespace-only string declares nothing here — as it does from the
flag and from ATOMS_CALLBACK_URL, which normalise the same way, so a blank
value never wins over a real one from a further source. The Worker requires
HTTPS, except for HTTP loopback URLs used in local development, such as
http://127.0.0.1:8000/atoms/callback.
The file entry is the committed default, not the last word. Both deploy
and dev resolve the callback URL in one order:
--callback-url, available ondeployanddevalike.ATOMS_CALLBACK_URLin the environment the command was started with — a CI job variable, or a value your shell exported.ATOMS_CALLBACK_URLin.env.atoms.<env>besideatoms.json— where a developer tunnel or a local port belongs, since the file is gitignored and read only for the target you named.- The selected environment’s
callback_urlinatoms.json.
The nearer source wins, silently. Nothing is compared, and no combination of
sources is an error. With no source at all, deploy warns and forwards no
callback variable. Because the winner is silent, deploy and dev print which
source supplied the URL before they use it.
The atoms.json entry is read only when steps 1 to 3 supplied nothing — so
nothing in it can fail a command that a nearer source already answered. That
holds for a malformed entry too: a value containing ${ that is not a
whole-value reference, such as "https://${HOST}/callback", is
ATOMS-E070 only when the file wins, and is
never inspected when a nearer source supplied a value.
When the file does win, a well-formed reference to a variable that is unset or
empty is ATOMS-E070 on deploy; atoms dev
treats it as no callback and warns, because the variable may belong to CI. That
is the only way the two commands differ here.
The callback URL is for reverse calls from the Worker. Configure the
application’s ATOMS_ENDPOINT separately with the Worker URL used for normal
Atom RPC. ATOMS_ENVIRONMENT may label the application environment in logs;
it does not select an atoms.json environment.
Synchronous app()
Section titled “Synchronous app()”$this->app()->method(...) calls into the Atom’s Methods class and waits for the response; the Atom is blocked for the whole round trip. Do not call it inside $this->db()->transaction().
Asynchronous dispatch()
Section titled “Asynchronous dispatch()”dispatch() hands a job to your application’s queue and returns immediately. See Jobs for writing one and the delivery guarantees.
Callback request and response size limits are configurable via Workers environment variables.