Skip to content

Commit c0b25ed

Browse files
kevinccbsgclaude
andcommitted
perf: reuse Ajv instance across validations instead of creating per call
Create the Ajv2020 instance once during init() and reuse it for all validateResponse/validateRequest calls. Eliminates repeated Ajv construction and addFormats() overhead — 14x speedup on a 67-mock suite (7.7s → 552ms). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6876b64 commit c0b25ed

1 file changed

Lines changed: 10 additions & 7 deletions

File tree

src/validator.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export class OpenAPIMockValidator {
1818
private spec: OpenAPISpec;
1919
private options: Required<ValidatorOptions>;
2020
private compiledPaths: CompiledPath[] | null = null;
21+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Ajv2020 lacks proper type exports
22+
private ajv: any = null;
2123
private initialized = false;
2224

2325
constructor(spec: OpenAPISpec, options?: ValidatorOptions) {
@@ -56,6 +58,12 @@ export class OpenAPIMockValidator {
5658
// Step 3: Compile path matchers
5759
this.compiledPaths = compilePaths(this.spec.paths);
5860

61+
// Step 4: Create reusable Ajv instance
62+
// @ts-expect-error -- ajv/dist/2020.js lacks proper type declarations
63+
this.ajv = new Ajv2020({ strict: false, allErrors: true });
64+
// @ts-expect-error -- ajv-formats type mismatch with Ajv2020
65+
addFormats(this.ajv);
66+
5967
this.initialized = true;
6068
}
6169

@@ -109,18 +117,13 @@ export class OpenAPIMockValidator {
109117
? this.addAdditionalPropertiesFalse(structuredClone(schema))
110118
: schema;
111119

112-
// @ts-expect-error -- ajv/dist/2020.js lacks proper type declarations
113-
const ajv = new Ajv2020({ strict: false, allErrors: true });
114-
// @ts-expect-error -- ajv-formats type mismatch with Ajv2020
115-
addFormats(ajv);
116-
117-
const valid = ajv.validate(schemaToValidate, payload);
120+
const valid = this.ajv!.validate(schemaToValidate, payload);
118121

119122
if (valid) {
120123
return { valid: true, errors: [], warnings: existingWarnings };
121124
}
122125

123-
const rawErrors: ValidationError[] = (ajv.errors || []).map((err: Record<string, unknown>) => {
126+
const rawErrors: ValidationError[] = (this.ajv!.errors || []).map((err: Record<string, unknown>) => {
124127
const params = err.params as Record<string, unknown> | undefined;
125128
const instancePath = (err.instancePath as string) || '';
126129
const dotPath = toDotPath(instancePath);

0 commit comments

Comments
 (0)