swaggest / rest

Web services with OpenAPI and JSON Schema done quick in Go
https://pkg.go.dev/github.com/swaggest/rest
MIT License
362 stars 17 forks source link

Feature Request: Specification Extensions through IOInteractor #74

Closed Fasopus closed 2 years ago

Fasopus commented 2 years ago

I've been prototyping a project using this rest framework, but we've noticed that there's no support for OpenAPI specification extensions. These extensions allow service owners to add additional fields to the OpenAPI spec, provided that they are prefixed by x- (for example x-internal) and are quite useful when integrating an OpenAPI spec with other platforms and tools.

https://swagger.io/specification/#specification-extensions

In my use case, I have some automation that we want to use with my generated openapi spec file, however this automation relies on the existence of some specification extensions. Would it be possible to extend the IOInteractor with basic support for extensions?

vearutop commented 2 years ago

Individual operations can have additional OpenAPI annotations outside of use case interactor definition.

Here is an example of annotation: https://github.com/swaggest/rest/blob/v0.2.27/_examples/advanced/router.go#L83-L90

It can be updated to have specification extensions like this:

// Annotations can be used to alter documentation of operation identified by method and path.
s.OpenAPICollector.Annotate(http.MethodPost, "/validation", func(op *openapi3.Operation) error {
    if op.Description != nil {
        *op.Description = *op.Description + " Custom annotation."
    }

    // Adding vendor extension to OpenAPI schema.
    op.WithMapOfAnythingItem("x-foo", "bar")

    return nil
})

Would this work for you?

Also raw generated spec is available as s.OpenAPI and can be manually updated with extensions after all use cases are mounted.

Extending IOInteractor seems less preferable since it is transport agnostic and also spec (OpenAPI) agnostic.

If we go for extending IOIteractor, that may look like Annotations map[string]interface{} that would be mapped into OpenAPI extensions for rest and to something else for other transports/specs (AsyncAPI, JSON-RPC, ...).

Fasopus commented 2 years ago

Thanks for the quick response!

Using WithMapOfAnythingItem as an operation annotation works perfectly for my use case here. No need for any changes to IOInteractor!