Skip to content
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

ajv best practice with koa #142

Closed
ghost opened this issue Mar 14, 2016 · 6 comments
Closed

ajv best practice with koa #142

ghost opened this issue Mar 14, 2016 · 6 comments
Labels

Comments

@ghost
Copy link

ghost commented Mar 14, 2016

i wonder how i should proceed to use ajv in koa.

I made some test and it seems that :
all compile call share the same error object for the same shema and same ajv instance.
all getContext call share the same error object for the same shema and same ajv instance.

Should i use the same ajv instance for all request ?
Should i instanciate ajv for each request ? What about perf ?
Should i instanciate ajv each time i need to use it ? What about perf ?

I tried to find examples of ajv and koa working together to be sure to proceed well but found nothing on google.

@epoberezkin
Copy link
Member

all compile call share the same error object for the same shema and same ajv instance.

Not sure I understand... Compile doesn't return errors, it throws exceptions if the schema is not valid. In most cases it can be tested in some build process so shouldn't happen at run time.

all getContext call share the same error object for the same shema and same ajv instance.

What is getContext?

If validation is synchronous then the errors are assigned to errors property of the validation function. It is a new array every time, you just have to copy it to some var if you plan to use it in some async context.

I see no reason to instantiate ajv every time. You have to precompile all schemas once (or compile them when they are first used if there are many of them) and reuse validation functions.

@ghost
Copy link
Author

ghost commented Mar 14, 2016

Maybe i don't understand how async works.

If 2 http request share the same instance of ajv
if each use of "ajv.getSchema(String key)" return a "validate" function with a shared property "errors"
So there is a risk that "validate.errors" give me an error object for an other request

Am i wrong ?

@epoberezkin
Copy link
Member

errors are not shared. Every time it's a new array instance, although you are right, they are assigned to the same property. If you are not using them immediately all you have to do is to assign this array to some local variable immediately after validation, otherwise they may indeed get overwritten:

var validate = ajv.getSchema(ref);
var valid = validate(data);
if (!valid) {
  var errors = validate.errors;
  // ...
}

In many cases you don't even need to reassign errors (if you are using these errors immediately, e.g. sending in the response). That's safe because javascript is single threaded and while your code is executing nothing else can be executed.

Please see the note in the end of Getting started and #65.

@ghost
Copy link
Author

ghost commented Mar 14, 2016

thanks a lot for answer !

That's the first time i use github (and git too) so i don't know if i can start it, but a short example with koa and other framework would be usefull for noob to fastly see how to use it.

@xfg
Copy link

xfg commented Apr 22, 2016

I see no reason to instantiate ajv every time.

@epoberezkin what if need a custom keyword of the same name, but with a different validation function for different schemas? For example the model in MVC architecture may have its specific validation functions with the same name as in the other model. Does it make sense in this case use the new instance of ajv per request or ajv has another solution?

@epoberezkin
Copy link
Member

epoberezkin commented Apr 22, 2016

There are obviously use cases when you need to use multiple instances. I don't really see why you may want to have the same keyword defined differently every time, although if you must you can always have a wrapper function that would be calling different function based on some external condition.

So while creating new instance every time is a possible option, you would be destroying the benefit of compiling schema once and using it multiple times

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 participants