feat: plugin contract e2e, qualify --changed, production observe, regressions
This commit is contained in:
+36
-15
@@ -162,30 +162,19 @@ export default {
|
||||
## Programmatic Runtime Activation
|
||||
|
||||
The CLI only validates configuration. To activate runtime observation, register
|
||||
APOPHIS with observe options in your application:
|
||||
APOPHIS with observe options in your application before routes are registered.
|
||||
Observe remains active in production because it is non-blocking; blocking
|
||||
runtime validation still stays disabled in production.
|
||||
|
||||
```typescript
|
||||
import Fastify from 'fastify'
|
||||
import apophisPlugin from '@apophis/fastify'
|
||||
import type { ObserveSink, ObserveEvent } from '@apophis/fastify'
|
||||
|
||||
const app = Fastify({ logger: true })
|
||||
|
||||
// Register APOPHIS with observe enabled.
|
||||
// This emits non-blocking contract pass/violation/error events
|
||||
// for every covered request, gated by sampling.
|
||||
await app.register(apophisPlugin, {
|
||||
runtime: 'warn',
|
||||
observe: {
|
||||
enabled: true,
|
||||
sampling: 0.1, // observe 10% of requests
|
||||
sinks: [metricsSink],
|
||||
},
|
||||
})
|
||||
|
||||
// Implement the ObserveSink interface.
|
||||
// Capture events to your preferred observability backend.
|
||||
import type { ObserveSink, ObserveEvent } from '@apophis/fastify'
|
||||
|
||||
const metricsSink: ObserveSink = {
|
||||
emit(event: ObserveEvent) {
|
||||
// Emit a counter for each contract evaluation
|
||||
@@ -205,11 +194,43 @@ const metricsSink: ObserveSink = {
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Register APOPHIS with observe enabled.
|
||||
// This emits non-blocking contract pass/violation/error events
|
||||
// for every covered request, gated by sampling.
|
||||
await app.register(apophisPlugin, {
|
||||
runtime: process.env.NODE_ENV === 'test' ? 'error' : 'off',
|
||||
observe: {
|
||||
enabled: true,
|
||||
sampling: 0.1, // observe 10% of requests
|
||||
sinks: [metricsSink],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
For new services, `createFastify()` wires discovery and APOPHIS before your
|
||||
routes, which avoids the most common ordering mistake:
|
||||
|
||||
```typescript
|
||||
import { createFastify } from '@apophis/fastify'
|
||||
|
||||
const app = await createFastify({
|
||||
logger: true,
|
||||
apophis: {
|
||||
runtime: process.env.NODE_ENV === 'test' ? 'error' : 'off',
|
||||
observe: {
|
||||
enabled: true,
|
||||
sampling: 0.1,
|
||||
sinks: [metricsSink],
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Key constraints:
|
||||
- Sink `emit()` can be sync or async (returns `void | Promise<void>`).
|
||||
- Sink rejections and thrown errors are silently caught — they never affect the route response or status code.
|
||||
- In production, observe hooks still run when `observe.enabled` and `observe.sinks` are configured; blocking runtime validation does not.
|
||||
- Sampling is applied per-formula evaluation via `Math.random() < sampling`.
|
||||
At `sampling: 1` every formula is emitted. At `sampling: 0` nothing is emitted.
|
||||
- Only routes with APOPHIS annotations (`x-ensures`, `x-requires`) produce events.
|
||||
|
||||
Reference in New Issue
Block a user