Extension Authoring
NOTE
This documentation is coming soon. In the meantime, please refer to the existing extensions in the codebase for examples of how to create your own extensions.
Overview
Graffle's extension system allows you to extend the client with custom functionality. Extensions can hook into various parts of the request/response lifecycle and add new methods to the client.
Examples
For now, you can look at these built-in extensions as examples:
Basic Pattern
Extensions typically follow this pattern:
import { type Extension } from 'graffle'
export const MyExtension = () => {
return Extension.create({
name: 'MyExtension',
// Extension implementation
})
}
Parameterized vs Non-Parameterized Extensions
Extensions can be parameterized (accept configuration) or non-parameterized (no configuration needed). This design choice affects how users consume your extension.
Non-Parameterized Extensions
Extensions without configuration can be exported directly as extension data objects. Users reference them without calling:
import { Extension } from 'graffle'
export const MyExtension = Extension.create({
name: 'MyExtension',
// No configuration needed
})
// Usage - no function call needed
client.use(MyExtension)
Examples:
TransportHttp
- No base configuration requiredTransportMemory
- No configuration neededThrows
- Simple behavior toggle
Parameterized Extensions
Extensions that accept configuration should be wrapped in a factory function. Users must call the extension to use it:
import { Extension } from 'graffle'
export const MyExtension = (config?: { option?: string }) => {
return Extension.create({
name: 'MyExtension',
// Use config in your implementation
})
}
// Usage - must call to provide config (even if config is optional)
client.use(MyExtension({ option: 'value' }))
client.use(MyExtension()) // Still must call even with no args
Examples:
DocumentBuilder()
- Accepts domains configurationSchemaErrors()
- Accepts error handling optionsIntrospection()
- May accept introspection optionsOpenTelemetry()
- Accepts telemetry configuration
Choosing the Right Pattern
Use Non-Parameterized when:
- Extension has zero configuration options
- Behavior is purely additive without customization
- You want the simplest possible API
Use Parameterized when:
- Extension accepts any configuration (even if optional)
- You may add configuration options in the future
- Behavior can be customized
Important: Once you ship a non-parameterized extension, you cannot easily add configuration later without breaking changes. When in doubt, use a parameterized pattern with optional config.
More detailed documentation will be available soon.