PluginsHooks
How to Choose
Use short decision rules to separate action, pipeline, guard, effect, resolve, and service
How to Choose
This page answers one question only:
- where should this capability actually live
Start with the shortest version
If you want to:
- explicitly invoke a named capability, use an
action - progressively transform a value, use
pipeline - block before the flow continues, use
guard - keep the main value unchanged and record or sync something, use
effect - get one final authoritative answer, use
resolve - own long-lived state, connections, or workers, use a
service
Common questions
"I want to add default fields to the input"
Use pipeline.
That is value transformation.
"I want to stop the request immediately if permission is missing"
Use guard.
That is a continuation decision.
"I want to write one audit log every time this happens"
Use effect.
That is a side effect.
"I want to know the user's final role"
Use resolve.
That is a unique-answer problem.
"I want an external caller to trigger a named command"
Use an action.
That is an explicit invocation entry point.
"I want a long-lived cache, connection pool, or background worker"
Use a service.
That is no longer just an extension point.
Common bad splits
using resolve for multi-plugin enrichment
That is usually wrong and should go back to pipeline.
using effect as a hidden reliable job queue
That is usually too heavy and should move into a service or fuller background system.
using guard while also rewriting values
That muddies the semantic role. Put the value rewrite back into pipeline.
One practical decomposition pattern
If one capability needs all of these:
- an explicit command entry
- runtime-chain extension
- long-lived state
then the clean split is often:
actionfor explicit invocationpipeline / guard / effect / resolvefor runtime-chain extensionservicefor long-lived state