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

OpenAPI: linting rule for checking if parameter is defined within the path template #3546

Closed
char0n opened this issue Dec 18, 2023 · 3 comments

Comments

@char0n
Copy link
Member

char0n commented Dec 18, 2023

Originally defined as Rule 2 in #3517

We want a linting rule that validates that user did not forget to define template expressions for all the appropriate Parameter Objects.

This linting rule is going to be attached to Parameter Object and not to path-template meta class so that the Parameter Objects gets highlighted in red if linting rule fails.

This is going to be a bit tricky as Parameter Object first needs to establish if it has been defined for Path Item Object or Operation Object that is attached to Path Item Object via http-verb.

Next it needs to check if it location is within path or query.

Next is needs to check if the path template attached to it's Path Item Object contains the template expression matching Parameter.name.

@char0n
Copy link
Member Author

char0n commented Jan 4, 2024

All right, so our first order of business if to determine if the Parameter Object we're looking at is somehow related to Path Item Object that is attached inside the Paths Object. Let's focus on that first, and after we have this established we'll focus on looking at Operation Object parameters.

Path Item Object parameters

We're specifically talking about PathItem.parameters.

1. Determining Path Item relationship

We first need to determine if Parameter Object is part of PathItem.parameters. That is achieved by looking at Parameter Object parent and checking if the parent is ArrayElement with meta class of path-item-parameters.

Predicate will look like this:

const isInPathItemElement = isArrayElement(paramerElement.parent) && includesClasses(['path-item-parameters'], parameterElement.parent)
const pathItemElement = parameterElement.parent.parent.parent

Tip

We can avoid step 1. and all the following steps by immediately looking into Parameter.in values and checking if it's path.

2. Determining if Path Item is part of path templating

To determine if the found Path Item Object (the one we found in previous step) is part of path templating, we have to look at it's meta field called path. If Path Item Object has this meta field and the meta field is of StringElement type, that we've determined that Parameter Object is part of path templating.

Predicate will look like this:

const isPathItemPartOfPathTemplating = isStringElement(pathItemElement.meta.get('path');
const pathTemplate = toValue(pathItemElement.meta.get('path'));

3. Determining if Parameter Object is matched with path templating

This is a bit tricky. We'll have to use openapi-path-templating to parse the path template into the AST:

This path template /pets/{petId} will parse into following AST:

          ['path-template', '/pets/{petId}'],
          ['path', '/pets/{petId}'],
          ['slash', '/'],
          ['path-literal', 'pets'],
          ['slash', '/'],
          ['template-expression', '{petId}'],
          ['template-expression-param-name', 'petId'],

If the Parameter.in === path - we'll have to look for template-expression-param-name with value of Parameter.name inside the AST.


Only after we have the above implementation, it makes sense to focus on Operation.parameters...

@char0n
Copy link
Member Author

char0n commented Jan 4, 2024

Operation Object parameters

We're specifically talking about Operation.parameters.

1. Determining Operation Object relationship

We first need to determine if Parameter Object is part of Operation.parameters. That is achieved by looking at Parameter Object parent and checking if the parent is ArrayElement with meta class of operation-parameters.

Predicate will look like this:

const isInOperationElement = isArrayElement(paramerElement.parent) && includesClasses(['operation-parameters'], parameterElement.parent)
const pathItemElement = parameterElement.parent.parent.parent.parent.parent // needs to be verified by you

We're already have isInPathItemElement in our apilintOpenAPIParameterInPathTemplate lint function. Depending on isInOperationElement or isInPathItemElement value we'll be accessing the pathItemElement variable differently.

Tip

We can avoid step 1. and all the following steps by immediately looking into Parameter.in values and checking if it's path.

2. Determining if Path Item is part of path templating

To determine if the found Path Item Object (the one we found in previous step) is part of path templating, we have to look at it's meta field called path. If Path Item Object has this meta field and the meta field is of StringElement type, that we've determined that Parameter Object is part of path templating.

Predicate will look like this:

const isPathItemPartOfPathTemplating = isStringElement(pathItemElement.meta.get('path');
const pathTemplate = toValue(pathItemElement.meta.get('path'));

3. Determining if Parameter Object is matched with path templating

This is a bit tricky. We'll have to use openapi-path-templating to parse the path template into the AST:

This path template /pets/{petId} will parse into following AST:

          ['path-template', '/pets/{petId}'],
          ['path', '/pets/{petId}'],
          ['slash', '/'],
          ['path-literal', 'pets'],
          ['slash', '/'],
          ['template-expression', '{petId}'],
          ['template-expression-param-name', 'petId'],

If the Parameter.in === path - we'll have to look for template-expression-param-name with value of Parameter.name inside the AST.


@char0n
Copy link
Member Author

char0n commented Jan 4, 2024

Closed by #3629

@char0n char0n closed this as completed Jan 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants