redocly-cli icon indicating copy to clipboard operation
redocly-cli copied to clipboard

Add parent keys pattern to assertions context

Open adamaltman opened this issue 2 years ago • 15 comments

Is your feature request related to a problem? Please describe.

The context object allows for targeting exact keys. However, sometimes you need more flexibility and can't determine the exact preset parent key names. An example would be a path with a template parameter (it has { and } characters in it).

Describe the solution you'd like

Context object (current)

Property Type Description
type string REQUIRED. One of the OpenAPI node types.
matchParentKeys [string] The list of parent object key names to evaluate with respect to the subject.
excludeParentKeys [string] The list of parent object key names to not evaluate with respect to the subject.

Context object (desired)

Property Type Description
type string REQUIRED. One of the OpenAPI node types.
includeParentKeys [string] The list of the exact parent object key names to evaluate with respect to the subject.
excludeParentKeys [string] The list of the exact parent object key names to not evaluate with respect to the subject.
matchParentKeys string A pattern that will evaluate against the parent keys.

Notice that we rename matchParentKeys to includeParentKeys and we use matchParentKeys keys for the new assertion context condition.

There is some discussion if the includeParentKeys should be mutually exclusive with matchParentKeys and excludeParentKeys. (I don't care either way.)

Describe alternatives you've considered

One alternative considered was removing the exact parent keys and have a pattern only. This makes it more difficult to read and write the exact key use cases.

Additional context

Attempting to limit context to paths with path template variables.

adamaltman avatar May 26 '22 11:05 adamaltman

BTW, why do we call them parent keys? As far as I understand, it is more about current ones, isn't it? In this case, the assertion will apply to the key of the Operation, not to a key of its parent PathItem:

         context:
            - type: Operation
              matchParentKeys:
                - get

tatomyr avatar May 26 '22 13:05 tatomyr

It's not a property of Operation from what I see but a property that contains the Operation as its value. Operation has these properties like tags, summary:

https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#fixed-fields-8

It's a property of the Path Item object:

https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#path-item-object

adamaltman avatar May 27 '22 01:05 adamaltman

Exactly. But I was looking for the key of an Operation Object, not its property. And I found this naming extremely confusing. However, this may be only my perception though.

tatomyr avatar May 27 '22 08:05 tatomyr

Is there another name you would suggest? @RomanHotsiy any opinion?

adamaltman avatar Jul 18 '22 21:07 adamaltman

the key of an Operation Object, not its property

I interpret it as "the key of the operation object in the parent"

key and property while having slight semantic differences are the same in this context: essentially we're validating json, and there is no difference between key and property in JSON.

I agree it's a little bit confusing. I don't have better ideas yet.

RomanHotsiy avatar Jul 18 '22 21:07 RomanHotsiy

I have a proposal. Remove key from the names:

Context object (desired)

Property Type Description
type string REQUIRED. One of the OpenAPI node types.
includeParents [string] The list of the exact parent key for this item to evaluate with respect to the subject.
excludeParents [string] The list of the exact parent key for this item to not evaluate with respect to the subject.
matchParents string A pattern that will evaluate against the parent key for this item.

adamaltman avatar Jul 20 '22 12:07 adamaltman

Without key, parents would be even more confusing 😄

One more thing. We can evaluate the parent key for an object, but we cannot evaluate its properties themselves. Imagine we have to check only those Parameters of type: string that are in: query (sorry for the ugly example). Do we maybe want to introduce the ability to introspect the context objects further?

tatomyr avatar Jul 21 '22 10:07 tatomyr

That's a good question. I think that example is actually a practical one as well. 👍

By the naming, did you mean property would be more clear?

Context object (desired)

Property Type Description
type string REQUIRED. One of the OpenAPI node types.
includeParentProperties [string] The list of the exact parent property for this item to evaluate with respect to the subject.
excludeParentProperties [string] The list of the exact parent property for this item to not evaluate with respect to the subject.
matchParentProperties string A pattern that will evaluate against the parent property for this item.

adamaltman avatar Jul 25 '22 20:07 adamaltman

I think what we are referring to is a property. The property has its key and value. So from what the doc says, it should be propertyKey.

tatomyr avatar Jul 26 '22 10:07 tatomyr

Let's check:

{
  "car": {
     "color": "red",
     "year": "2020"
   }
   "house": {
       "color": "gray"
   }
}
type: Color
propertyKey: car
Property Type Description
type string REQUIRED. One of the OpenAPI node types.
includePropertyKeys [string] The list of the exact property key of this item to evaluate with respect to the subject.
excludePropertyKeys [string] The list of the exact property key of this item to not evaluate with respect to the subject.
matchPropertyKeys string A pattern that will evaluate against the property key of this item.

adamaltman avatar Aug 04 '22 12:08 adamaltman

Screenshot 2022-08-04 at 15 00 24 If you mean each rectangled property to be of type `Color` then it sounds just right.

tatomyr avatar Aug 04 '22 13:08 tatomyr

I get easily confused and may think it's about property of the Color type itself:

{
  "car": {
     "color": "red",
     "year": "2020"
   }
   "house": {
      "color": "gray"
      "car": {
         ...
       }
   }
}

Which car this matches?

RomanHotsiy avatar Aug 04 '22 13:08 RomanHotsiy

Ok, I get it this way.

We are looking for a property of type Color. In the example above there are two properties of this type and their keys are car and house. That's it.

This part

{
      "color": "gray"
      "car": {
         ...
       }
}

is the value of a property.

What may be misleading here is the plural form of includePropertyKeys &c. It sounds like there could be several keys in the property itself, whilst by definition a property could possibly have only one key. Thus I would prefer singular form instead (like includePropertyKey).

tatomyr avatar Aug 04 '22 13:08 tatomyr

But the idea is it can take a list of keys:

includePropertyKeys:
  - car
  - house

adamaltman avatar Aug 04 '22 15:08 adamaltman

Yeah, and this is the point of confusion for me 🙂. But what we're looking for is a key, not keys. What about includePropertyKeyNames?

tatomyr avatar Aug 04 '22 17:08 tatomyr

Do you think we need a brainstorming session on the naming? I believe we need to decide on this before the release.

tatomyr avatar Aug 19 '22 14:08 tatomyr

Yet another idea.

Maybe we can refer to a parent key as to name? Something like includeNames, excludeNames, matchName/namePattern?

If under a node type we mean an object, name keyword sounds neutral to me and has low chances of being mixed with keys from inside the object.

tatomyr avatar Aug 23 '22 09:08 tatomyr

I think we've resolved what to do here as mentioned in #857 -- I'm not sure this won't be covered by #781 so I think it may be safe to close this issue and make sure it is incorporated into #781 .

adamaltman avatar Sep 21 '22 21:09 adamaltman