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

Present OpenAPI additionalProperties field #1162

Closed
wants to merge 8 commits into from
Closed

Present OpenAPI additionalProperties field #1162

wants to merge 8 commits into from

Conversation

DMRobertson
Copy link
Contributor

@DMRobertson DMRobertson commented Jul 4, 2022

When looking at the "Authentication Data" type used in e.g. the account
deactivation endpoint

https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3accountdeactivate

it was not clear to me that clients and servers should expect additional
fields in this structure (the semantics of which are implied by the
type of the authentication, or that of the previously established
session.)

In the OpenAPI spec, We occasionally mark some ojects as allowing
arbitrary additional properties (additionalProperties: true, or
additionalProperties: { description: "..."}). In other places we are
more strict and provide a schema that additional properties must satisfy.
In this PR we aim to make the first kind of additional
properties (non-strict) more visible in the rendered spec.

See https://pr1162--matrix-spec-previews.netlify.app/client-server-api/#post_matrixclientv3accountdeactivate

image

Preview: https://pr1162--matrix-spec-previews.netlify.app

David Robertson added 2 commits July 4, 2022 21:24
When looking at the "Authentication Data" type used in e.g. the account
deactivation endpoint

    https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3accountdeactivate

it was not clear to me that clients and servers should expect additional
fields in this structure (the semantics of which are implied by the
`type` of the authentication, or that of the previously established
`session`.)

In the OpenAPI spec, We occasionally mark some ojects as allowing
arbitrary additional properties (`additionalProperties: true`, or
`additionalProperties: { description: "..."}`). In other places we are
more strict and provide a schema that additional properties must satisfy.
In this PR we aim to make the first kind of additional
properties (non-strict) more visible in the rendered spec.
@DMRobertson DMRobertson marked this pull request as ready for review July 4, 2022 20:39
@DMRobertson DMRobertson requested a review from a team as a code owner July 4, 2022 20:39
Copy link
Member

@turt2live turt2live left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally this seems fine, though there seems to be a bit of confusion around what clients are able to send (which is anything it feels like - servers don't have to listen though)

{{ else if (not $additionalProperties) -}}
{{/* At present we don't have any schema with additionalProperties: false.
But if we ever do, let's support it. */}}
May **not** have additional properties.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything is extensible in Matrix unless otherwise noted, so this is a bit misleading.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow---what do you find misleading?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole sentence :D

Additional properties are always allowed, even if not advertised by the spec. The server just isn't required to do anything with them (unless it's dealing with signatures)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. Then perhaps this can be changed so that

  • we don't do anything if additionalProperties: true
  • we raise a build-time error if additionalProperties: false
  • Rather than "May have additional properties:" in the generated HTML, we write "Notes on additional properties:".

How does that sound?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems reasonable, assuming additionalProperties can be assigned a boolean (I don't think it can?)

Copy link
Contributor Author

@DMRobertson DMRobertson Jul 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://swagger.io/specification/#schema-object

The following properties are taken from the JSON Schema definition but their definitions were adjusted to the OpenAPI Specification.

  • additionalProperties - Value can be boolean or object. Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. Consistent with JSON Schema, additionalProperties defaults to true.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And for completeness: the original JSON schema additionalProperties are defined here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3398cf0 is an attempt at this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@turt2live, @DMRobertson: I'm not sure I'm following the discussion here. Can I just check that everyone is clear what we're discussing?

The question is around the correct behaviour if we encounter an object schema where additionalProperties is explictly set to false (as opposed to leaving it unset, which is equivalent to setting it to true).

Earlier drafts of JSON Schema give a clear definition of what that means:

If "additionalProperties" is false, validation succeeds only if the instance is an object and all properties on the instance were covered by "properties" and/or "patternProperties".

In other words: this is explicitly about trying to define an object which may not be extended.

I don't entirely object to the decision to emit an error message, if we think it's somehow un-matrixy to try to define an object that isn't allowed any additional properties. I'd just like to be sure that we made that decision with good information.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually have that case (exactly one, unless I missed some weirdly formatted), and it's in m.receipt events: . additionalProperties: false is used next to patternProperties to forbid anything that does not follow the pattern. Which is quite valid and smart, in my opinion. There's a big question however on what the homeserver is supposed to do with this boundary. I would treat it as a "MUST ignore" of sorts, whereas omitting additionalProperties entirely would correspond to "MAY ignore". Does it make sense?

@DMRobertson DMRobertson marked this pull request as draft July 14, 2022 19:07
David Robertson added 2 commits July 21, 2022 16:12
Ignore `true` values for additionalProperties. Error on `false` values.
I think this looks better, but what do I know?
@DMRobertson DMRobertson requested a review from turt2live July 21, 2022 15:15
@DMRobertson DMRobertson marked this pull request as ready for review July 21, 2022 15:15
@DMRobertson
Copy link
Contributor Author

Oh. Looks like I have a merge to resolve.

@DMRobertson DMRobertson requested review from richvdh and removed request for turt2live November 22, 2022 18:45
Otherwise, it should be an OpenAPI schema object. Include the description
of that schema object, if it exists. */}}
{{ if (and (ne $additionalProperties nil) (ne $additionalProperties true)) }}
{{ if (and (reflect.IsMap $additionalProperties)) -}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant and here.

Comment on lines +116 to +117
{{ if (and (ne $additionalProperties nil) (ne $additionalProperties true)) }}
{{ if (and (reflect.IsMap $additionalProperties)) -}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we restructure these if statements to reduce the nesting?

 {{ if (or (eq $additionalProperties nil) (eq $additionalProperties true)) }}
     {{/* do nothing */}}
  {{ else if (reflect.IsMap $additionalProperties) -}}
     ...
  {{ else if (not $additionalProperties) -}}
    ... 
  {{ end }}

or something.

{{/* TODO: should we handle the case where additional properties are
permitted, but must follow an explicit schema? */}}
{{ else if (not $additionalProperties) -}}
{{ errorf "Unexpected additionalProperties=false for %s" $title }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's unclear to me that we should be raising an error in this case. Isn't it legitimate to specify that a given object may not have additional properties, even if that is currently unused?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷 There's some context here: #1162 (comment) ; I don't have any strong opinions here.

@richvdh
Copy link
Member

richvdh commented Oct 3, 2023

@DMRobertson are you still interested in pursuing this? Anything we can do to unblock you?

@DMRobertson
Copy link
Contributor Author

It'd be nice to do this at some point, but I don't think I'm going to find the time. Let's close this off for now.

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

Successfully merging this pull request may close these issues.

4 participants