Skip to content

Feature request: validator class method decorator for JSON Schema validation #3608

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

Closed
1 of 2 tasks
dreamorosi opened this issue Feb 16, 2025 · 3 comments · Fixed by #3679
Closed
1 of 2 tasks

Feature request: validator class method decorator for JSON Schema validation #3608

dreamorosi opened this issue Feb 16, 2025 · 3 comments · Fixed by #3679
Assignees
Labels
completed This item is complete and has been merged/shipped feature-request This item refers to a feature request for an existing or new utility validation This item relates to the Validation Utility

Comments

@dreamorosi
Copy link
Contributor

dreamorosi commented Feb 16, 2025

Use case

To continue the implementation of the Validation utility started in #3607, we should implement a @validator decorator that can be used by TypeScript customers to wrap a class method and validate both inputs and outputs of the method against a set of JSON Schemas.

Solution/User Experience

The decorator will use the validate function implemented in #3607 under the hood, and as such it should accept similar parameters to that function, albeit with some changes to accommodate the fact that 1/ it's a decorator, and 2/ it can validate both input and outputs of the decorated method.

The decorator will take a single params object that has the following items:

  • an optional inboundSchema - this is the JSON Schema used to validate the incoming payload
  • an optional outboundSchema - this is the JSON Schema used to validate the response payload
  • an optional envelope parameter of type string (more on this later)
  • an optional formats optional parameter to pass custom formats
  • an optional externalRefs array of schemas that can be used to supply external references to the main schema
  • an optional ajv parameter that customers can use to provide their own instance - this is useful when wanting to use a different JSON Schema version/draft

Both inboundSchema and outboundSchema are optional, this is intentional because we want to allow customers to validate one, the other, or both. If none is provided, the decorator will be a no-op.

In terms of implementation, the validator decorator will have the overall flow:

  • if neither inboundSchema nor outboundSchema are provided, return and call the decorated method
  • if inboundSchema is present, call the validate function using the schema as schema and the first argument of the decorated method as payload, as well as all the other optional params to validate the incoming payload
  • call the decorated method using the result of the first validate call as first argument and store the response in a variable
  • if outboundSchema is present, call the validate function using the schema as schema and the response of the decorated method as payload, as well as all the other optional params except for envelope to validate it

Finally, since decorators cannot change the type of the parameters of the decorated function, there's no need for it to be a generic function nor an assertion function.

As part of the implementation the implementer should also write unit tests to cover 100% of the files, lines, branches of the code added as part of this issue. All the dependencies needed should already be present in the workspace, ideally the implementation should follow existing project conventions as much as possible. The decorator should be in its own file, i.e. packages/validation/src/decorator.ts.

When it comes to references, you can find an example of how this decorator would be used in the docs/utilities/validation.md file.

If instead you're unfamiliar with how to implement decorators, I've added an example below:

import type { Context, Handler } from 'aws-lambda';

export const validator = (
  params: ValidatorOptions
): HandlerMethodDecorator => {
  return (_target, _propertyKey, descriptor) => {
    // biome-ignore lint/style/noNonNullAssertion: The descriptor.value is the method this decorator decorates, it cannot be undefined.
    const original = descriptor.value!;

    // if no inbound nor outbound schemas are provided, return `descriptor` here

    descriptor.value = async function (
      this: Handler,
      event: unknown,
      context: Context,
      callback
    ) {
      // validate inbound schema here, if present
      const validatedEvent = '...';

      const response = original.call(this, validatedEvent, context, callback);

      // validate outbound schema here, if present
      return response;
    };

    return descriptor;
  };
};

Alternative solutions

N/A

Acknowledgment

Future readers

Please react with 👍 and your use case to help us understand customer demand.

@dreamorosi dreamorosi added feature-request This item refers to a feature request for an existing or new utility on-hold This item is on-hold and will be revisited in the future validation This item relates to the Validation Utility labels Feb 16, 2025
@dreamorosi dreamorosi added this to the Validation utility milestone Feb 16, 2025
@dreamorosi dreamorosi moved this from Triage to On hold in Powertools for AWS Lambda (TypeScript) Feb 16, 2025
@dreamorosi dreamorosi added help-wanted We would really appreciate some support from community for this one confirmed The scope is clear, ready for implementation and removed on-hold This item is on-hold and will be revisited in the future labels Feb 27, 2025
@dreamorosi dreamorosi moved this from On hold to Backlog in Powertools for AWS Lambda (TypeScript) Feb 27, 2025
@VatsalGoel3
Copy link
Contributor

@dreamorosi, I'll start with this issue, if it goes through early will take on the other issue as well.
Please assign this to me.

Copy link
Contributor

github-actions bot commented Mar 4, 2025

⚠️ COMMENT VISIBILITY WARNING ⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.

@github-actions github-actions bot added pending-release This item has been merged and will be released soon completed This item is complete and has been merged/shipped and removed help-wanted We would really appreciate some support from community for this one confirmed The scope is clear, ready for implementation pending-release This item has been merged and will be released soon labels Mar 4, 2025
@aws-powertools aws-powertools deleted a comment from github-actions bot Mar 7, 2025
@dreamorosi dreamorosi added pending-release This item has been merged and will be released soon and removed completed This item is complete and has been merged/shipped labels Mar 7, 2025
Copy link
Contributor

This is now released under v2.17.0 version!

@github-actions github-actions bot removed the pending-release This item has been merged and will be released soon label Mar 25, 2025
@github-actions github-actions bot added the completed This item is complete and has been merged/shipped label Mar 25, 2025
@dreamorosi dreamorosi moved this from Coming soon to Shipped in Powertools for AWS Lambda (TypeScript) Mar 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
completed This item is complete and has been merged/shipped feature-request This item refers to a feature request for an existing or new utility validation This item relates to the Validation Utility
Projects
2 participants