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

setting $$strict=true for params should work with nested objects #314

Closed
ekellstrand opened this issue Aug 17, 2022 · 8 comments
Closed

Comments

@ekellstrand
Copy link

ekellstrand commented Aug 17, 2022

Consider the following action definition. Take note of:

  • "city" parameter in the action
  • "I_DONT_REMEMBER_HOW_TO_SPELL_CITY" parameter in the payload
createLocation: {
    auth: 'required',
    params: {
        $$strict: true  
        alias: { type: 'string' },
        address: {
            type: 'object',
            props: {
                address1: { type: 'string', optional: true },
                city: { type: 'string', optional: true },
            },
            optional: true,
        }
    }
    async handler(ctx: Context<Record<string, unknown>, ClientMeta>) {/* doSomethingLogical() */}
}

Now call this service with the following payload

{
  "alias": "InCoherent Developer's Palace",
  "address": {
    "address1": "42 Somewhere Path",
    "I_DONT_REMEMBER_HOW_TO_SPELL_CITY": "Why does this value get silently dropped and not stored in my database??  I set $$strict=true so I would get politely told to bugger off and go fix my typo",
  },
}

$$strict seems work great for top level params. (ie, If I added "I_DONT_REMEMBER_HOW_TO_SPELL_ALIAS" at the top level, right under "alias" in my payload, validation correctly rejects it). It's only when I define an object that I see this problem.

ps. Thx for your efforts. I really enjoy working with Moleculer!

Edit: Sorry, Let me give you the software version details..

OS                      : Windows 10
NodeJS                  : 16.15.0 
moleculer               : ^0.14.21
moleculer-web           : ^0.10.4
moleculer-decorators    : ^1.3.0
moleculer-http-client   : ^0.4.2
moleculer-io            : ^2.0.0

I tested with Chrome 104.0.5112.102 & Postman 9.28.2

@ColinFrick
Copy link

ColinFrick commented Aug 17, 2022

Does it work if you add strict: true to the address definition?
See https://github.com/icebob/fastest-validator#properties-10

@ekellstrand
Copy link
Author

@ColinFrick Yes!
Interesting...
Adding "$$strict:true" to the address definition did not work.
Adding "strict:true" to the address definition, with out the dollar signs, did work.

I'll have to check and see if I should be using "strict:true" everywhere now instead of "$$strict:true".

@ColinFrick
Copy link

@ekellstrand top level is $$strict. Otherwise you wouldn’t be able to add a parameter with the name strict.
See https://github.com/icebob/fastest-validator#strict-validation

@ekellstrand
Copy link
Author

OK, so that gets me going.
@ColinFrick

  • I'm guessing this might be due to JS internals, but do you know it doesn't stick with "$$strict" on nested schemas?
  • Do you know if there was a conscious decision to make $$strict not affect nested schemas?
  • I wonder if I'm the only one who made a bad assumption here. Maybe it because I'm only using fastest-validator in the context on Moleculer? I guess I'm asking if this issue is still a valid feature request (either for fastest-validator, or specifically for Moleculer), to make $$strict affect nested schemas, or if this issue should get rewritten as, "Please make the docs call this out so others don't trip over a bad assumption", or if this issue just gets closed as RTFM.

@ColinFrick
Copy link

$$strict is only evaluated for the root schema. As far as I can tell it is the same behavior as if you have nested objects, children don't inherit the strict property from their parent either.

If you always want strict: true for object validator you can set it by default:
https://github.com/icebob/fastest-validator#default-options
https://moleculer.services/docs/0.14/validating.html#Fastest-Validator (Example with options)

I only can tell you what's in the documentation, maybe @icebob can tell you more.

@ekellstrand
Copy link
Author

@ColinFrick Thank you for pointing me at the docs. The default values are new since I set this all up a few years back. I think docs are good and I'm going to close this out as "RTFM Success".

Related question: It looks like the default options handles any nested objects. Do you know if there is any config setting to handle the top level $$strict: true as a default for all actions? or is my existing Middleware function still the best bet for that? (I re-read both sets of docs but didn't see anything)

@icebob
Copy link
Member

icebob commented Aug 21, 2022

Hi, @ColinFrick's explanation is right, no inheritance in properties, every property is evaluated on the given level and not affect the nested levels.

If you would like to add strict: true for every object rule, set it as a default option as Colin mentioned. You can do it in broker options, like:

// moleculer.config.js

module.exports = {
    validator: {
        type: "Fastest",
        options: {
            useNewCustomCheckerFunction: true,
            defaults: {
                object: {
                    strict: true
                }
            }
        }
    }
};

@ekellstrand
Copy link
Author

Thanks! Closing this as RTFM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants