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

[OAS 3.1.0] PathItem supports references in the Components object. #437

Closed
4 tasks done
jmini opened this issue Jul 2, 2020 · 6 comments · Fixed by #629
Closed
4 tasks done

[OAS 3.1.0] PathItem supports references in the Components object. #437

jmini opened this issue Jul 2, 2020 · 6 comments · Fixed by #629
Assignees
Labels
OAS 3.1.0 All issues related to OpenAPI version 3.1.0 support

Comments

@jmini
Copy link
Contributor

jmini commented Jul 2, 2020

In order to support OpenAPI 3.1.0 (see #333) we need the PathItem to support $ref.

Components Object now has a new entry pathItems, to allow for reusable Path Item Objects to be defined within a valid OpenAPI document.

Reference: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#componentsObject

Example (to be verified):

openapi: 3.1.0
info:
  title: Example specification
  version: "1.0"
servers:
- url: http://localhost:8080/
paths:
  /foo:
    $ref: "#/components/pathItems/StandardStatus"
  /bar:
    $ref: "#/components/pathItems/StandardStatus"
components:
  pathItems:
    StandardStatus:
      get:
        parameters:
        - name: extended
          in: query
          schema:
            type: boolean
        responses:
          200:
            description: OK

To be added:

  • The model interface PathItem.java is now extending Reference.
  • The model interface Components.java: must manage path items.
  • Model TCK tests for new fields
  • Model TCK test that ref can be set alongside other fields in PathItem
@jmini jmini added the OAS 3.1.0 All issues related to OpenAPI version 3.1.0 support label Jul 2, 2020
@MikeEdgar MikeEdgar added this to the MP OpenAPI 4.0 milestone Jan 16, 2024
@Azquelt
Copy link
Member

Azquelt commented May 10, 2024

I noticed that @CallbackOperation and the proposed @Webhook represent a map entry where the value is a PathItem, so these annotations could have a ref property added.

Added this to the list in the main comment.

@Azquelt
Copy link
Member

Azquelt commented May 10, 2024

Thought about this again and I'm less sure. The mapping from annotations to model objects isn't straightforward.

  • @Callback represents one entry in the map inside the Callback object (a pair of callbackUrlExpression and CallbackOperation[])
  • @CallbackOperation represents one entry in the map inside the PathItem object (a pair of method and Operation)
  • @Webhook represents one entry in the webhooks map, inside the OpenAPI object (a pair of name and CallbackOperation[])

I guess @CallbackOperation[] is the part that maps well onto a PathItem object and since that's an array rather than an object, it can't have a ref property.

You could argue that @Callback could have a ref to a PathItem, but it already has a ref property used to reference a Callback. It could have a new property used to reference a PathItem.

I think a new @Webhook annotation could have a ref.

That would leave us with:

Referencing a callback:

@Path("/myOp")
@Callback(name = "myCallback", ref = "#/components/callbacks/myCallback")
public String myOp() { ... }

Referencing a pathItem from a callback:

@Path("/myOp")
@Callback(name = "myCallback", callbackUrlExpression = "/foobar", pathItemRef = "#/components/pathItems/myPathItem")
public String myOp() { ... }

Referencing a pathItem from a webhook:

@OpenAPIDefinition(webhooks = {
    @Webhook(name = "myWebhook", ref = "#/components/pathItems/myPathItem")
})

@Azquelt
Copy link
Member

Azquelt commented May 13, 2024

Second complication: not only is a reference to a Path Item permitted in a Callback, a Webhook and in Components.pathItems, but Path Item itself has a $ref field which can be used alongside any other fields (unlike $ref in a reference object).

There are a few OpenAPI issues related to this:

In the current 3.1 dev branch, using $ref alongside other fields is deprecated but still allowed, so I guess we should allow this, at least in the model API. I've added this to the list in the first comment.

@Azquelt
Copy link
Member

Azquelt commented May 28, 2024

Thinking again about annotations, we still need to decide whether we want annotations for Path Items under /components. At the moment, we don't have a @PathItem annotation, we create path items and operations based on the REST resource methods in the application (which can have additional information added with @Operation).

This decision would also impact #583 (webhooks) since in the model, the webhooks field just maps names to path items. I see a couple of options:

  1. We could not provide a way to declare path items under components

    We would then just have an annotation for webhooks that might look like this:

    @OpenAPIDefinition(
            webhooks = @Webhook(
                    name = "foo",
                    operations = {
                        @CallbackOperation(
                                method = "put",
                                description = "create operation",
                                ...
                        ),
                        @CallbackOperation(
                                method = "delete",
                                description = "delete operation",
                                ...
                        )
                    }
            )
    )

    Callbacks and webhooks are conceptually quite similar so I think it makes sense to re-use the @CallbackOperation annotation here.

  2. We could provide a new @PathItem annotation

    We would also need to create a new annotation (or enhance an existing one) for operations under @PathItem.

    • @Operation is meant to be used on resource method alongside other annotations and is missing most fields which exist in the model.
    • @CallbackOperation is named specifically for callbacks and is missing fields which don't make as much sense in a callback but may be needed when declaring a path item which could be reused under /paths (id, deprecated, tags, callbacks, servers).

    In this case, we could also use the @PathItem annotation to define webhooks.

    Webhooks and path items then might be declared like this:

    @OpenAPIDefinition(
            webhooks = @PathItem(
                    name = "foo",
                    operations = {
                        @PathItemOperation(
                                method = "put",
                                description = "create operation",
                                ...
                        ),
                        @PathItemOperation(
                                method = "delete",
                                description = "delete operation",
                                ...
                        )
                    }
            ),
            components = @Components(
                    pathItems = @PathItem(
                            name = "bar",
                            operations = @PathItemOperation(...),
                            parameters = @Parameter(
                                    name = "id",
                                    in = PATH,
                                    ...
                            )
                    )
            )
    )

    These path items could then be referenced like this:

    webhooks = @PathItem(
            name = "myWebhook",
            ref = "#/components/pathItems/bar", // or just ref = "bar"
            operations = @PathItemOperation( ... )
    )
    callbacks = @Callback(
            name = "myCallback",
            callbackUrlExpression = "/my/callback/path",
            pathItemRef = "bar", // or ref = "#/components/pathItems/bar",
            operations = ...
    )

    Note that @Callback already has a ref parameter to reference a Callback declared as a component to reference a whole callback which could have multiple callback url expressions. When using pathItemRef, callbackUrlExpression must also be provided.

    We could also potentially allow paths to be defined under the @OpenAPIDefinition annotation, which is another location we could reference a Path Item declared elsewhere.

    @OpenAPIDefinition(
            paths = @PathItem(
                    name = "/my/app/path",
                    ref = "#/components/pathItems/bar",
                    operations = ...
            )
    )

    Note that everywhere we reference a Path Item, we can have both a reference and add additional operations since that's what's allowed in the OpenAPI model.

@Azquelt
Copy link
Member

Azquelt commented Jun 5, 2024

We decided at the meeting yesterday that we should push ahead with creating @PathItem and @PathItemOperation, but not add OpenAPIDefinition.paths().

@Azquelt
Copy link
Member

Azquelt commented Jun 5, 2024

Work required:

  • API
    • Create @PathItem
    • Create @PathItemOperation
    • Create @OpenAPIDefinition.webhooks()
    • Create @Callback.pathItemRef()
  • Tests
    • Define a Path Item under Components
    • Define Operations under a Path Item, test out all parameters
    • Define a webhook
    • Reference a Path Item from a webhook
    • Reference a Path Item from a callback
    • Reference a Path Item from another Path Item under Components

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OAS 3.1.0 All issues related to OpenAPI version 3.1.0 support
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants