-
-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Response validation #7
Comments
Yes, we sure could add Ajv validation for output, but I would disable it by default. I've had output validation enabled using other libraries but found that it's not actually desireable to throw errors for API users because the API response doesn't conform to the spec. How would you like to use this feature in your tests? Do you have a proposal? |
We could use this feature during tests in order to centralize the source of truth on the OpenAPI spec, and free the user from writing the output validation logic related to the schema in his/her (all) unit tests. I was also thinking about having a way to keep output validation even in production for some operations, especially on the body, in order to ensure that security critical values that are not supposed to be disclosed, are not disclosed unintentionally because of a potential bug or else. This may only concern highly security constrained environments, but why not having a mechanism that support all scenarios. To this end, I was think about having an output validation handler in the What do you think about that ? Thanks for your input. |
If it's a handler, wouldn't it make sense to register it with In the constructor, we should instruct OpenAPIBackend whether to prepare Ajv validations for responses too. Right now there's https://github.com/anttiviljami/openapi-backend/blob/master/DOCS.md#parameter-optsvalidate for input validation. Perhaps Let's say we also add a new handler, say The validator (and OpenAPIBackend) will also get a new method similar to Would this work? I'm still unsure how this should be used in the test suite. |
About the handler I'm talking about, sorry if the term confused you, it is not a handler in To speak with your terms, So more something like
or
So this process only decides what to validate, then as you said comes a
I agree, and I think that's the only drawback of the predicate approach, because having the predicate function defined does not necessarily mean output validation has to be performed, for example in the case the predicate is Not sure what is the best approach, but I definitely think having a predicate to filter which output we want to validate or not, is a good thing, and doing it via a JS function is by far the simplest way. A flag gives too few control, and we certainly don't want to implement a rules engine (format, parser, runtime, unit tests, etc...) About the Let me know if what I say is still not clear, or if you don't like the predicate approach ^^ Thanks. |
I'm wondering if the predicate should be applied during runtime (to decide whether to use a pre-built schema to validate), or during initalization (to decide whether to build the schema for an operation in the first place). I'm leaning towards the first option. Then we could have a separate flag to instruct OpenAPI backend to skip the schema building for responses entirely. |
Do you mean applying the predicate to all operations at the initialization, and building a map of operations on which to apply the output validation ? Do you plan on implementing it, or do you want me to make a pull request ? |
Yes. That's current how the input validation works. We pre-compile the schemas during init and then use them during runtime. If no schema was built, there's no validation work to be done. I think the response validation should probably work that way too. However, right now there's no great way to disable the input validation for a single operation. All you can do is decide not to care about the validation result in the validationFail handler and pass the request on to the operation handler if you really need to. I think using predicate functions like this is a great idea for exactly that task! Let's add predicate function opts for both input and response validation so users can skip validation steps during runtime. The schemas should be still be compiled for each operation, I think. I'm currently working on some other minor changes related to input validation. I'll push a minor bump probably today. If it's ok to you, I'll do the initial version and have you review the feature? I just feel like things are still in flux related to validation and I don't want you to do unnecessary work while big API changes happen. :) |
Sure that perfectly makes sense you kick start the thing if you are performing other changes as well related with this. For output validation, originally I was thinking about applying the predicate for each request because we may want to prevent the response to reach the net also based on values in the body, but that starts to get a bit too hairy, and anyway kind of out of OpenAPI scope. Nonetheless, I was still thinking on building the validation function only once (per operation) at startup. So basically that would mean, instead of creating a map of validation functions for all operations, you could add to the map only the function for which the predicate said true, and then at runtime considering operations not in the map is not a mistake but means a validation skip. Looking forward to your update anyway, thanks for your time and your good work :) |
Closes #7 - Renamed OpenAPIRequestValidator => OpenAPIValidator - Added validator.validateResponse - Added validator.getRequestValidatorsForOperation - Added validator.getResponseValidatorForOperation - validator.validateRequest & validator.validateResponse now accept operationId as second parameter - OpenAPIBackend constructor opt validate can be a predicate function to allow for fine control of whether to validate per request / operation
Closes #7 - Renamed OpenAPIRequestValidator => OpenAPIValidator - Added validator.validateResponse - Added validator.getRequestValidatorsForOperation - Added validator.getResponseValidatorForOperation - validator.validateRequest & validator.validateResponse now accept operationId as second parameter - OpenAPIBackend constructor opt validate can be a predicate function to allow for fine control of whether to validate per request / operation
Hi @TanukiSharp & @ronkorving ! I've now implemented this feature (without docs) in this PR: #12 Wanna check it out? Couple of changes to my initial plan:
Here's an example of how I imagine you might use this: function postResponseHandler(c) {
const valid = api.validator.validateResponse(c.response, c.operation.operationId);
// alternatively,
const valid = c.responseValidator(c.response);
if (valid.errors) {
// return some error message here
return { err: 'validation fail', errors: valid.errors };
} else {
return c.response;
}
}
api.register({ postResponseHandler }); See the commit message for more info or ask me if something feels weird. |
Closes #7 - Renamed OpenAPIRequestValidator => OpenAPIValidator - Added validator.validateResponse - Added validator.getRequestValidatorsForOperation - Added validator.getResponseValidatorForOperation - validator.validateRequest & validator.validateResponse now accept operationId as second parameter - OpenAPIBackend constructor opt validate can be a predicate function to allow for fine control of whether to validate per request / operation
This feature is now live in |
Hi,
First of all, amazing library! This is exactly what I was looking for all this time, giving total control, yet offering very useful features for OpenAPI 3. Just needed to say that, this-is-great :)
I was wondering about HTTP response validation though. Do you think there is a reasonable approach to validate HTTP responses against the OpenAPI definition? Perhaps too much overhead in production, but would be very useful during development and while running a test suite.
Would love to hear your thoughts. Thanks!
The text was updated successfully, but these errors were encountered: