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

Query string does not honor required/not required #5034

Closed
thomastoye opened this issue Jun 11, 2018 · 18 comments · Fixed by #9793
Closed

Query string does not honor required/not required #5034

thomastoye opened this issue Jun 11, 2018 · 18 comments · Fixed by #9793

Comments

@thomastoye
Copy link

This is a Bug Report

Description

  • What went wrong?

I created a query string parameter set to true, which marks it as required. However, nothing happens when it's not passed.

  • What did you expect should have happened?

I expect to see an error when the parameter is missing.

  • What was the config you used?

See below for serverless.yml.

  • What stacktrace or error message from your provider did you see?

None. Expected to see an error when query string parameter is missing.


I want my request to have a certain query string parameter. I saw the following here:

To pass optional and required parameters to your functions, so you can use them in API Gateway tests and SDK generation, marking them as true will make them required, false will make them optional.

However, when marking a query string as true does not seem to make it required. When using the following code (clean start from serverless create --template aws-nodejs-typescript), all requests pass to the hello path, even if the query string is not set.

serverless.yml:

service:
  name: example-test

plugins:
  - serverless-webpack
  - serverless-offline

provider:
  name: aws
  runtime: nodejs6.10

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          method: get
          path: hello
          request:
            parameters:
              querystrings:
                url: true

Similar or dependent issues:

Additional Data

  • Serverless Framework Version you're using: 1.27.3
  • Operating System: Ubuntu 18.04 LTS
  • Stack Trace: N/A
  • Provider Error messages: N/A
@ctindel
Copy link
Contributor

ctindel commented Feb 20, 2019

I think this is related to the fact that there's no way right now to enable the request validator for body/query params right?

#3464

@Rigellute
Copy link

Also seeing this behaviour

Framework Core: 1.60.5
Plugin: 3.2.7
SDK: 2.2.1
Components Core: 1.1.1
Components CLI: 1.4.0

@akleiber
Copy link

akleiber commented Feb 4, 2020

Querystring parameters are marked as required, but the missing part is the RequestValidator.

Bildschirmfoto 2020-02-04 um 08 55 24

@akleiber
Copy link

akleiber commented Feb 4, 2020

If you set params as required via serverless syntax you then can just also activate the validator for parameters like so

Resources:
  ParameterRequestValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: ParameterRequestValidator
      RestApiId:
        Ref: ApiGatewayRestApi
      ValidateRequestBody: false
      ValidateRequestParameters: true

  ApiGatewayMethodNameOfYourApiLookItUpInYourTemplate:
    Properties:
      RequestValidatorId:
        Ref: ParameterRequestValidator

@Rigellute
Copy link

@akleiber thank you 🙏

@Pitasi
Copy link

Pitasi commented May 6, 2020

I'm struggling with this too.

What's "ApiGatewayMethodNameOfYourApiLookItUpInYourTemplate" you're referring to, @akleiber?
I tried a bunch of different combinations with no luck :)

cc @Rigellute maybe you can answer too

@Pitasi
Copy link

Pitasi commented May 6, 2020

Oookay I got it!
It should be: ApiGatewayMethodFooGet, where foo is my handler name and get is the HTTP method I'm handling.

@yash-awsops
Copy link

Here is the working template:

In serverless.yml add this

   plugins:
       - serverless-reqvalidator-plugin
   functions:
       events:
          -http:
            path: hello
            method: get
            reqValidatorName: ParameterRequestValidator
    resources:

     Resources:
         ParameterRequestValidator:
            Type: AWS::ApiGateway::RequestValidator
            Properties:
                   Name: ParameterRequestValidator
                   RestApiId:
                         Ref: ApiGatewayRestApi
                   ValidateRequestBody: false
                   ValidateRequestParameters: true

@shadowdogg
Copy link

Oookay I got it!
It should be: ApiGatewayMethodFooGet, where foo is my handler name and get is the HTTP method I'm handling.

Don't suppose you could be a bit more specific for people like me please.

This is what I got from your description:

  list:
    # Defines an HTTP API endpoint that calls the main function in list.js
    # - path: url path is /deals
    # - method: GET request
    handler: list.main
    events:
      - http:
          path: deals
          method: get
          cors: true
          authorizer: aws_iam
          request:
            parameters:
              querystrings:
                country: true
                type: true
                categoryId: true
                yearMonth: true
                batchLimit: true
    Properties:
      RequestValidatorId:
        Ref: ParameterRequestValidator

@Pitasi
Copy link

Pitasi commented Nov 2, 2020

@shadowdogg iirc you just need to add this at the bottom of your serverless.yml:

Resources:
  ParameterRequestValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: ParameterRequestValidator
      RestApiId:
        Ref: ApiGatewayRestApi
      ValidateRequestBody: false
      ValidateRequestParameters: true

  ApiGatewayMethodListGet:
    Properties:
      RequestValidatorId:
        Ref: ParameterRequestValidator

(note how I used ApiGatewayMethodListGet since your handlest it's called list and the method is get)

@shadowdogg
Copy link

shadowdogg commented Nov 2, 2020

@shadowdogg iirc you just need to add this at the bottom of your serverless.yml:

Resources:
  ParameterRequestValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: ParameterRequestValidator
      RestApiId:
        Ref: ApiGatewayRestApi
      ValidateRequestBody: false
      ValidateRequestParameters: true

  ApiGatewayMethodListGet:
    Properties:
      RequestValidatorId:
        Ref: ParameterRequestValidator

(note how I used ApiGatewayMethodListGet since your handlest it's called list and the method is get)

@Pitasi Yeah, still doesn't work for me

The CloudFormation template is invalid: Template format error: [/Resources/ApiGatewayMethodListGet] Every Resources object must contain a Type member.

@shadowdogg
Copy link

For those of you failing to see this, like I also did.

This is what you need to do in plain english.

Turn

ApiGatewayMethodNameOfYourApiLookItUpInYourTemplate

to

APIGatewayMethod<1><2>

API Gateway

In my case, it was APIGatewayDealsGet

The thing I was looking at was my handler name in serverless

   list:
    # Defines an HTTP API endpoint that calls the main function in list.js
    # - path: url path is /deals
    # - method: GET request
    handler: list.main
    events:
      - http:
          path: deals
          method: get
          cors: true
          authorizer: aws_iam
          request:
            parameters:
              querystrings:
                country: true
                type: true

Alternatively, if this does not work, check the s3 bucket, mine was called xxxxxxx-ap-serverlessdeploymentbuck-1epdp60eqveqr and go to serverless > yyyyyyyyyyy > aaaa >
timestamp > compiled-cloudformation-template.json

And look for the name of your method in there, example mine was:

	"ApiGatewayMethodDealsGet": {
		"Type": "AWS::ApiGateway::Method",
		"Properties": {
			"HttpMethod": "GET",
			"RequestParameters": {

@shwetajoshi601
Copy link

Is there any update on this? I am facing the same issue.

@shadowdogg
Copy link

Is there any update on this? I am facing the same issue.

I literally gave a full explaination right above your comment

@mamapi
Copy link

mamapi commented Dec 11, 2020

@akleiber what type should be used for that resource?
Now I'm getting "The CloudFormation template is invalid: Template format error .... Every Resources object must contain a Type member."

I'm reffering to

   ApiGatewayMethodListGet:
      Properties:
          RequestValidatorId:
             Ref: ParameterRequestValidator

@thebrianbug
Copy link

thebrianbug commented Feb 12, 2021

This did not solve my issue unfortunately :(

#5034 (comment)

I've deployed this successfully and referenced the ApiGatewayMethod..., but my lambda is still being hit even if a required query string parameter is being omitted.

@flexjames
Copy link

If you set params as required via serverless syntax you then can just also activate the validator for parameters like so

Resources:
  ParameterRequestValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: ParameterRequestValidator
      RestApiId:
        Ref: ApiGatewayRestApi
      ValidateRequestBody: false
      ValidateRequestParameters: true

  ApiGatewayMethodNameOfYourApiLookItUpInYourTemplate:
    Properties:
      RequestValidatorId:
        Ref: ParameterRequestValidator

Thanks this worked. Quick question though, does this method work for path parameters? Also, if I have a nested route, how would that work? So if my route is admin/someRoute, what would the ApiGatewayMethod look like? I tried ApiGatewayMethodAdminSomerouteGet and it didn't work?

@Shahid1993
Copy link

If you set params as required via serverless syntax you then can just also activate the validator for parameters like so

Resources:
  ParameterRequestValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: ParameterRequestValidator
      RestApiId:
        Ref: ApiGatewayRestApi
      ValidateRequestBody: false
      ValidateRequestParameters: true

  ApiGatewayMethodNameOfYourApiLookItUpInYourTemplate:
    Properties:
      RequestValidatorId:
        Ref: ParameterRequestValidator

Thanks this worked. Quick question though, does this method work for path parameters? Also, if I have a nested route, how would that work? So if my route is admin/someRoute, what would the ApiGatewayMethod look like? I tried ApiGatewayMethodAdminSomerouteGet and it didn't work?

This doesn't work for path parameters.

To get the APIGatewayMethod name for your nested route, you can look in the compiled-cloudformation-template.json file inside your serverless deployment bucket.

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

Successfully merging a pull request may close this issue.