Hi there!
I was wondering if it is possible to have nested parameters in inputs. Currently my code uses the type json, but that basically means no validation is done on parameters that are not in the first JSON level. I am pretty sure I am not alone wondering how to do proper validation of parameters with a nested structure.
Thanks!
@Sytten Thanks for posting! We'll take a look as soon as possible.
In the mean time, there are a few ways you can help speed things along:
Please remember: never post in a public forum if you believe you've found a genuine security vulnerability. Instead, disclose it responsibly.
For help with questions about Sails, click here.
Hey @Sytten you can write a custom validation function for nested inputs. For example:
inputs: {
myCustomInput: {
type: 'json',
description: 'A user\'s email notification settings',
required: true,
custom: function (value) {
return (
_.isObject(value) &&
_.isBoolean(value.name) &&
_.isBoolean(value.age)
);
}
}
}
Someone on gitter hinted that sails uses rttc and they support nested verification, is that something that would be possible here. Honestly this solution of a custom validation is bad in all ways. People usually quite complex JSON payloads in production with multiple levels and it needs to be clear what the validation does.
True. Custom validation isn't the best option especially in cases where the JSON payload has a complex schema. However, I don't know of any other better way to do it.
Thanks @georgeben, the custom validation is definitely worth a try for nested inputs! 馃憤
@Sytten Have you tried this out?
I mean, it works and its not the first time I see the solution. Its just not a good one IMO for mainly three reasons:
I kept digging a bit in the sails code (which is very confusing due to the nesting of small dependencies). I found in the code of machine (on which action2 is based) that nesting is not supported natively:
https://github.com/node-machine/machine/blob/850e87de1200b3985c04dadbd3554eea3c6f8613/lib/private/normalize-argins.js#L150-L154
HOWEVER, you can see at this line https://github.com/node-machine/machine/blob/850e87de1200b3985c04dadbd3554eea3c6f8613/lib/private/normalize-argins.js#L237 that the machine passes the .type property to rttc. Turns out we can exploit that functionality and give it an object. This will tell rttc that it is a faceted dictionary and it will verify the nesting! the syntax is a bit different but its easy to read:
inputs: {
user: {
type: {
id: 'number',
},
},
}
@mikermcneil Do you have plans to actually support this usecase as a first class citizen like it is written in the comment? Just want to know before I start migrating my 300 routes :)
@Sytten oh wow thanks for sharing that @Sytten !! THats awesome!
The only problem I see is that is does not support optional nested fields, but I guess this is better than nothing...
The only problem I see is that is does not support optional nested fields, but I guess this is better than nothing...
This is why custom validation methods or individual parameters are still _possibly_ a better method (for now at least), even if they're more verbose and/or delicate/mysterious.
I had a tinker with the "faceted dictionary" style like above after the gitter conversation. Like you I quickly discovered you lose "optional" fields, but also the finer-grained control other 'fancy' validations give you with individual parameters (think isInteger or maxLength, etc). Ragequit at that stage, but commenting here to see if there's any more developments :wink:
The only problem I see is that is does not support optional nested fields, but I guess this is better than nothing...
True, but assuming sails used something like babel-node we would have had an option of nullish operator and optional chaining, and that would be a great feat for us
@Sytten Couldn't you use a JSON schema and validate the passed in JSON against that schema?You could easily do that using the custom function property.
Sure we could do that, then I would ask what is the point of using sails if anyway you have to use other frameworks to get basic stuff done? This is such a basic feature for any production ready system i just don't understand what the fuss is all about.
Another framework? You would be using a library to do the JSON validation. Also, using helpers, you could easily create a reusable function to test the JSON. In fact, I don't know of any framework that does JSON schema validation out of the box. I couldn't find it in AdonisJs, NestJs, Express, or even any of the frontend frameworks like Angular or Vue.
Seeing as how SailsJS is open-source, you could add the functionality yourself. 馃槃
This is why custom validation methods or individual parameters are still possibly a better method (for now at least), even if they're more verbose and/or delicate/mysterious.
@nahanil @georgeben @wojo1086 馃憤
The custom validation rule is what I would recommend.
I kept digging a bit in the sails code (which is very confusing due to the nesting of small dependencies). I found in the code of machine (on which action2 is based) that nesting is not supported natively:
https://github.com/node-machine/machine/blob/850e87de1200b3985c04dadbd3554eea3c6f8613/lib/private/normalize-argins.js#L150-L154HOWEVER, you can see at this line https://github.com/node-machine/machine/blob/850e87de1200b3985c04dadbd3554eea3c6f8613/lib/private/normalize-argins.js#L237 that the machine passes the
.typeproperty to rttc. Turns out we can exploit that functionality and give it an object. This will tell rttc that it is a faceted dictionary and it will verify the nesting! the syntax is a bit different but its easy to read:inputs: { user: { type: { id: 'number', }, }, }
Hey @Sytten do you have examples of inputs you made using this. I would love to play with it.
@Noitidart Sorry I dont have access to this code anymore and I am not working on the contract :S
The company decided to remove sails from their codebase.
Aw darn. Hope they come back soon to sails!
This shape is working great for me, i just don't know how to do optional keys. like i wanted "order" to be optional.
values: {
required: true,
type: [
{
id: 'number',
order: 'number',
},
],
},
Like I said earlier its not possible: https://github.com/balderdashy/sails/issues/6958#issuecomment-598512874
Most helpful comment
True. Custom validation isn't the best option especially in cases where the JSON payload has a complex schema. However, I don't know of any other better way to do it.