Plugins
Plugin composition patterns
Ordering, performance considerations, and patterns for composing multiple plugins.
Ordering
- Plugins run in the order they are provided to
usefulkey(..., { plugins })
. - Early
beforeVerify
hooks can short-circuit later work by returning{ reject: true, reason }
.
Performance considerations
- Each plugin may perform store reads independently. This can lead to multiple reads per verification.
- Mitigations:
- Keep the plugin set minimal for your use case.
- Prefer low-latency stores in production (Redis/SQL near the app).
- Consider caching common reads in your own layer.
Example composition
const uk = usefulkey({}, { plugins: [
ratelimit({ default: { kind: 'fixed', limit: 100, duration: '1m' } }),
ipAccessControlStatic({ allow: ['127.0.0.1'] }),
permissionsScopesPlugin({ metadataKey: 'scopes' }),
usageLimitsPerKeyPlugin(),
]});
Recommendations:
- Put cheap, high-signal blockers first (IP deny, enable/disable) to short-circuit fast.
- Follow with policy checks (scopes), then usage counters that may update state.
Request-scoped context (roadmap)
- Future versions may expose a shared, per-request context to reduce duplicate reads across plugins.