OpenAPI.NET icon indicating copy to clipboard operation
OpenAPI.NET copied to clipboard

Version 1.6.5 to 1.6.13 contains breaking change

Open JohannesBauer97 opened this issue 1 year ago • 3 comments

Describe the bug We're using this package to validate OpenAPI specification files by reading the files OpenApiStringReader.Read and checking if there are diagnostic errors. image

After updating from 1.6.5 to 1.6.13, a spec which was valid before, became invalid because of non-unique paths (see below the screenshot).

Diagnostic Error: RuleName: "PathMustBeUnique" Pointer: "#/paths//api/v1/{birdId}/children/{childNo}" Message: "The path signature '/api/v1/{}/children/{}' MUST be unique."

OpenApi File To Reproduce Just giving a screenshot here, if the full file is required I need to anonymize it first. Maybe for the discussion the screenshot is enough image

Expected behavior No breaking changes between patch versions.

What does the openapi spec say? Is this definition of non unique paths a error?

JohannesBauer97 avatar Feb 28 '24 12:02 JohannesBauer97

Technically, the new behavior is correct. From https://spec.openapis.org/oas/v3.0.3#paths-object

A relative path to an individual endpoint. The field name MUST begin with a forward slash (/). The path is appended (no relative URL resolution) to the expanded URL from the Server Object’s url field in order to construct the full URL. Path templating is allowed. When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts. Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical. In case of ambiguous matching, it’s up to the tooling to decide which one to use.

4.7.8.2 Path Templating Matching § Assuming the following paths, the concrete definition, /pets/mine, will be matched first if used:

  /pets/{petId}
  /pets/mine

The following paths are considered identical and invalid:

  /pets/{petId}
  /pets/{name}

The following may lead to ambiguous resolution:

  /{entity}/me
  /books/{id}

Due to templating behavior, those paths are indeed considered identical.

VisualBean avatar Mar 01 '24 07:03 VisualBean

Thanks for the reference, so it was all the time defined like this, and now it got fixed in the nuget.

JohannesBauer97 avatar Mar 02 '24 12:03 JohannesBauer97

@VisualBean the new behavior have one issue as I see it, it not taking the apiOperation into account with different template names. Should below not be allowed?

DELETE /pets/{petId} PUT /pets/{name}

rasmus-s avatar Mar 06 '24 09:03 rasmus-s

@VisualBean any ideas on that?

ryklen-tech avatar Feb 08 '25 23:02 ryklen-tech

@VisualBean the new behavior have one issue as I see it, it not taking the apiOperation into account with different template names. Should below not be allowed?

DELETE /pets/{petId} PUT /pets/{name}

The path (URI) does not care about HTTP Verbs as such, unfortunately.

Think of it this way; The Path (Uri) denotes which resource we are working with - and the Verb denotes the type of operation.

URI Templates deal specifically with the URI - so as /pets/{petId} and /pets/{name} are considered the same resource (from a templating point of view) the verb does not really matter. It is routed to the same place.

So the implementation is (for better or for worse) correct.

What you could be experiencing is that your specification has the paths separated where they shouldn't be.

From the Path Item documentation.

A relative path to an individual endpoint. The field name MUST begin with a forward slash (/).
The path is appended (no relative URL resolution) to the expanded URL from the [Server Object](https://spec.openapis.org/oas/v3.0.3.html#server-object)’s url field in order to construct the full URL. 
[Path templating](https://spec.openapis.org/oas/v3.0.3.html#path-templating) is allowed. 
When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts. 
Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical. 
In case of ambiguous matching, it’s up to the tooling to decide which one to use.

Key part here being Templated paths with the same hierarchy but different templated names MUST NOT exist.

Which means that

paths:
    /pets/{id}
        get:
            ...
    /pets/{name}
        put:
            ...

Is illegal, regardless of verbs.

VisualBean avatar Feb 10 '25 09:02 VisualBean

Thanks @VisualBean for providing much needed clarification here! Since there's no action to be taken, I'll go ahead and close this issue. Let us know if you have any additional comments or questions.

baywet avatar May 19 '25 19:05 baywet