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

ruleset: AWS Gateway #475

Closed
18 tasks
philsturgeon opened this issue Aug 22, 2019 · 8 comments
Closed
18 tasks

ruleset: AWS Gateway #475

philsturgeon opened this issue Aug 22, 2019 · 8 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@philsturgeon
Copy link
Contributor

philsturgeon commented Aug 22, 2019

AWS Gateway says it supports OpenAPI, but it's only a subset, with some extra validation rules and other non-standard stuff. We should extend the core rulesets to support AWS-flavoured OpenAPI, to help our users navigate this tricky situation.

The following rules are taken from AWS Gateway Known Issues.

  • Path segments can only contain alphanumeric characters, hyphens, periods, commas, and curly braces. Path parameters must be separate path segments. For example, "resource/{path_parameter_name}" is valid; "resource{path_parameter_name}" is not.

  • Model names can only contain alphanumeric characters.

  • For input parameters, only the following attributes are supported: name, in, required, type, description. Other attributes are ignored.

  • The securitySchemes type, if used, must be apiKey. However, OAuth 2 and HTTP Basic authentication are supported via Lambda authorizers; the OpenAPI configuration is achieved via vendor extensions.

  • The deprecated field is is not supported and is dropped in exported APIs.

  • API Gateway models are defined using JSON schema draft 4, instead of the JSON schema used by OpenAPI.

  • The additionalProperties and anyOf keywords are not supported in Models.

  • The discriminator keyword is not supported in any schema object.

  • The example keyword is not supported.

  • exclusiveMinimum is not supported by API Gateway.

  • The maxItems and minItems tags are not included in simple request validation. To work around this, update the model after import before doing validation.

  • oneOf is not supported by API Gateway.

  • The readOnly field is not supported.

  • Response definitions of the "500": {"$ref": "#/responses/UnexpectedError"} form is not supported in the OpenAPI document root. To work around this, replace the reference by the inline schema.

  • Numbers of the Int32 or Int64 type are not supported. An example is shown as follows:

    "elementId": {
        "description": "Working Element Id",
        "format": "int32",
        "type": "number"
    }
  • Decimal number format type ("format": "decimal") is not supported in a schema definition.

  • In method responses, schema definition must be of an object type and cannot be of primitive types. For example, "schema": {"type": "string"} is not supported. However, you can work around this using the following object type:

     "schema": {
         "$ref": "#/definitions/StringResponse"
     }

     "definitions": {
        "StringResponse": {
          "type": "string"
        }
      }
  • API Gateway doesn't use root level security defined in the OpenAPI specification. Hence security needs to be defined at an operation level to be appropriately applied.

Our friends over at SwaggerHub have noticed other problems not on this list.

OAS2

  • Form parameters (in: formData) are not supported and are ignored.

OAS3

  • Cookie parameters (in: cookie) are not supported and are ignored.

  • Response code ranges (4XX) are not supported. Use specific response codes instead.

  • TRACE operation definitions are not supported.

@philsturgeon
Copy link
Contributor Author

philsturgeon commented Aug 22, 2019

The most troubling part is this very subtle line:

API Gateway models are defined using JSON schema draft 4, instead of the JSON schema used by OpenAPI.

OpenAPI v2 Schema Objects are a subset/superset/sideset of JSON Schema Draft 4, so they're asking that people write invalid OpenAPI by using valid JSON Schema instead. You can have valid OpenAPI or valid JSON Schema but you can't have both.

OpenAPI v3 Schema Objects are also a subset/superset/sideset but JSON Schema draft 5 based, which luckily is basically the same thing. The said, OpenAPI v3.0 added nullable: true but AWS Gateway are expecting type: ['string', 'null'], which is invalid OpenAPI.

I'm not sure how we're gonna implement this specific rule.

Stuff like this is why I'm trying so hard to get OpenAPI v3.1 up to be a JSON Schema draft 8 vocabulary, so that valid JSON Schema is valid OpenAPI, but until then we get to play this headache out over and over in 100 places. 🙇‍♂️

@luzfcb
Copy link

luzfcb commented Oct 8, 2019

Hello, first, thanks for this project.

I use API Gateway and now need to validate an openapi3.json/yaml file before uploading it to AWS API Gateway.

Spectral currently returns an error when using the {proxy+} resource.
{proxy+} looks like it's something AWS API Gateway specific

https://docs.aws.amazon.com/en_pv/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-http.html

This is the minimum file to reproduce the problem:

openapi3.json

{
  "openapi": "3.0.0",
  "info": {
    "description": "My API",
    "version": "0",
    "title": "My API",
    "contact": {
      "email": "[email protected]"
    }
  },
  "paths": {
    "/foobar/{proxy+}": {
      "x-amazon-apigateway-any-method": {
        "produces": [
          "application/json",
          "text/html",
          "text/css",
          "text/javascript",
          "image/*",
          "font/*",
          "application/font-woff2",
          "application/font-woff",
          "application/xhtml+xml"
        ],
        "parameters": [
          {
            "name": "proxy",
            "in": "path",
            "type": "string",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ]
      }
    }
  }
}
luzfcb@fabio:~/projects/foobar-apigateway$ spectral lint openapi3.json
OpenAPI 3.x detected

/Users/luzfcb/projects/foobar-apigateway/openapi3.json
  1:1   warning  api-servers  OpenAPI `servers` must be present and non-empty array.
 26:11    error  path-params  Path parameter "**proxy**" must have a `required` that is set to `true`.

To fix, mark this parameter as required.
 26:11    error  path-params  Parameter "**proxy**" is not used in the path "**/passthrough/{proxy+}**".

Unused parameters are not allowed.

To fix, remove this parameter.

✖ 3 problems (2 errors, 1 warning, 0 infos)

Question:

With the current implementation (v4.2.0), it's possible to create or override a rule to spectral not raise an error? If yes, can you provide me an example of how the rule will look like?

ps: As I did not find a Spectral plugin for pre-commit, I just created it for my use. https://github.com/luzfcb/mirrors-stoplight-spectral

@P0lip
Copy link
Contributor

P0lip commented Oct 8, 2019

Hello @luzfcb, it's very nice to see you here!

With the current implementation (v4.2.0), it's possible to create or override a rule to spectral not raise an error? If yes, can you provide me with an example of how the rule will look like?

Yes, it's possible to disable a rule or change its severity.
There are two ways to do it.

The preferred way is creating a custom ruleset and disabling a rule. In your case, the ruleset could look as follows

{
  "extends": "spectral:oas",
  "rules": {
    "path-params": "off"
  }
}

If you place the ruleset in the current working directory and name it .spectral.json or .spectral.yaml, it will be automatically picked up by Spectral.
If you'd like to move the ruleset somewhere or simply rename it, that's absolutely fine too. You just need to specify the path to the ruleset, as follows spectral lint openapi3.json -r path-to-my-ruleset

The other less recommended way is utilizing the skip-rule CLI flag, i.e. spectral lint openapi3.json --skip-rule path-params

Let me know if it did the trick.

ps: As I did not find a Spectral plugin for pre-commit, I just created it for my use. https://github.com/luzfcb/mirrors-stoplight-spectral

Sweet!

@luzfcb
Copy link

luzfcb commented Oct 9, 2019

@P0lip Thanks for the quick response.

After some investigation, I think I am getting an error because of this regex: https://github.com/stoplightio/spectral/blob/v4.2.0/src/rulesets/oas/functions/oasPathParam.ts#L3

In a new OAS API Gateway flavor, maybe the regex can be replaced by something like:

(\{[a-zA-Z0-9_-]+\}|(\{([a-zA-Z0-9_-]*)proxy\+\}$))+

Okay, this regex is not perfect: https://regex101.com/r/4pUDTz/2/

Question: It's possible to use custom-functions and inherit from oasPathParam.ts and only replace the regex?

@P0lip
Copy link
Contributor

P0lip commented Oct 9, 2019

@luzfcb
I'm afraid to say that in order to replace the regex, you'd need to copy the entire function.

@philsturgeon philsturgeon added the help wanted Extra attention is needed label Dec 31, 2020
@P0lip P0lip added the enhancement New feature or request label May 11, 2021
@andylockran
Copy link

I've been bothering @philsturgeon about this on twitter :p - but just found this bug so figured I'd put it here too:
https://github.com/andylockran/spectral-aws-apigateway-ruleset hope it's helpful. I'm not wholly confident that I've nailed it - but it's at least a good starter for contributions.

@philsturgeon
Copy link
Contributor Author

@andylockran thank you! Did you see #1615? It might solve some of the problems you've had writing more advanced rulesets.

@philsturgeon
Copy link
Contributor Author

This will be coming out soon but not as part of spectral itself. Keep an eye on https://github.com/stoplightio/spectral-rulesets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants