Skip to content

Commit

Permalink
Merge pull request #497 from psznm/master
Browse files Browse the repository at this point in the history
feat: Add lazyCompileValidationSchemas option
  • Loading branch information
jwalton authored Jun 27, 2024
2 parents f3c9884 + bed3940 commit 44fd964
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 3 deletions.
6 changes: 6 additions & 0 deletions docs/Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,9 @@ If set, then when encountering a validation error Exegesis will return
all errors found in the document instead of just the first error. This
causes Exegesis to spend more time on requests with errors in them, so
for performance reasons this is disabled by default.

## lazyCompileValidationSchemas

Response and request schemas are compiled by ajv to make validation faster. However compilation is slow
and can cause compilation of API to take long time. Enabling this will cause validation schemas
compilation to be executed when the validator is needed.
28 changes: 25 additions & 3 deletions src/oas3/Schema/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function doValidate(
schemaPtr: string,
parameterLocation: ParameterLocation,
parameterRequired: boolean,
ajvValidate: ValidateFunction,
getAjvValidate: () => ValidateFunction,
json: any
) {
const value = { value: json };
Expand All @@ -142,6 +142,7 @@ function doValidate(
}

if (!errors) {
const ajvValidate = getAjvValidate();
ajvValidate(value);
if (ajvValidate.errors) {
errors = ajvValidate.errors.map((err) => {
Expand All @@ -167,6 +168,23 @@ function doValidate(
return { errors, value: value.value };
}

function createValidateGetter(schema: any, ajv: Ajv, lazy: boolean): () => ValidateFunction {
if (lazy) {
let validate: ValidateFunction | null = null;
return function () {
if (!validate) {
validate = ajv.compile(schema);
}
return validate;
};
} else {
const validate = ajv.compile(schema);
return function () {
return validate;
};
}
}

function generateValidator(
schemaContext: Oas3CompileContext,
parameterLocation: ParameterLocation,
Expand Down Expand Up @@ -212,10 +230,14 @@ function generateValidator(
ajv.addFormat(key, customFormats[key]);
}

const validate = ajv.compile(schema);
const getValidate = createValidateGetter(
schema,
ajv,
schemaContext.options.lazyCompileValidationSchemas
);

return function (json: any) {
return doValidate(schemaPtr, parameterLocation, parameterRequired, validate, json);
return doValidate(schemaPtr, parameterLocation, parameterRequired, getValidate, json);
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface ExegesisCompiledOptions {
allErrors: boolean;
treatReturnedJsonAsPure: boolean;
strictValidation: boolean;
lazyCompileValidationSchemas: boolean;
}

// See the OAS 3.0 specification for full details about supported formats:
Expand Down Expand Up @@ -134,5 +135,6 @@ export function compileOptions(options: ExegesisOptions = {}): ExegesisCompiledO
allErrors: options.allErrors || false,
treatReturnedJsonAsPure: options.treatReturnedJsonAsPure || false,
strictValidation: options.strictValidation ?? false,
lazyCompileValidationSchemas: options.lazyCompileValidationSchemas ?? false,
};
}
7 changes: 7 additions & 0 deletions src/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,11 @@ export interface ExegesisOptions {
* If true, then this will put ajv into "strict mode" (see https://ajv.js.org/strict-mode.html).
*/
strictValidation?: boolean;

/**
* Response and request schemas are compiled by ajv to make validation faster. However compilation is slow
* and can cause compilation of API to take long time. Enabling this will cause validation schemas
* compilation to be executed when the validator is needed.
*/
lazyCompileValidationSchemas?: boolean;
}

0 comments on commit 44fd964

Please sign in to comment.