Swagger integration

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Swagger integration

pmogren
Hi,

I'm excited about Ratpack - I haven't tried it yet, but intend to in the coming days, as I think it fills a real void. One thing that Ratpack lacks that my organization has found valuable is integration with Swagger. This post is intended to start a conversation about how best to pursue that  integration.

-Paul
Reply | Threaded
Open this post in threaded view
|

Re: Swagger integration

Luke Daley
Administrator
Hi Paul,

Could you elaborate on what you would want out of such integration?
Reply | Threaded
Open this post in threaded view
|

Re: Swagger integration

pmogren
A Swagger integration would generate and serve up documentation for REST API operations implemented by Ratpack handlers, including the ability to incorporate Swagger metadata into the documentation - with JAX-RS at least, metadata is typically added in-line via Swagger annotations such as @ApiOperation and @ApiResponses on the handler.

I also use swagger-codegen to generate API clients, but that is based on consumption of a running instance of the Swagger documentation, so I don't think Ratpack would have to do anything specific to support codegen.
Reply | Threaded
Open this post in threaded view
|

Re: Swagger integration

davidmc24
Ratpack can be used with Swagger right now in exactly the same way as any other framework that doesn't have special support; generate a static Swagger JSON file and serve it as an asset.

To your actual point, generating Swagger information based on the actual implementation (as done by swagger-jaxrs or other modules that scan classes for annotations) requires the capability to enumerate a-priori all possible implementations that could be used as part of handling a request.  This isn't currently compatible with Ratpack's request-handling approach, in which a pipeline is composed on-demand.

That being said, let's brainstorm some ways that we might be able to accomplish this.  We could introduce a concept of a Resource (or maybe even a higher-level object... a ResourceGroup?) that would be a Handler that served REST endpoints, providing some mechanism for adding them, routing to them (likely by way of an internal routing table), and enumerating them.  We could then have a SwaggerApiDeclarationHandler that pulled information from the Resource/ResourceGroup to serve up the appropriate JSON.

To be most consistent with the rest of the Ratpack style, I would probably expect the mechanism for registering endpoints to be largely similar to the current Chain API, perhaps with some tweaks to make it easier to accommodate frequent use of content negotiation and differentiation by HTTP method (some API design needed here).  If so, I'm not sure where we'd encode the API information used by Swagger.  The ApiOperation annotation, for example, expects to be applied to a method, but there likely wouldn't be a method that represents the "operation" in this model.

Alternatively, we could have a Swagger-specific module.  In it, we could have ResourceGroup/Resource classes that use methods to define the different "operations", and would be designed to play nicely with the expectations of Swagger's annotations.
Reply | Threaded
Open this post in threaded view
|

Re: Swagger integration

kyleboon
You could just skip using the annotations and instead extend the ratpack api to support Swagger.

Instead of

```
get('contacts')
```

You could have

```
swaggerGet('contacts', 'Lists all contacts')
```

Then in addition to adding a handler to the chain for regular HTTP handling, it could use the supplied meta data to generate the swagger json. This would not be a small amount of work though.
Reply | Threaded
Open this post in threaded view
|

Re: Swagger integration

davidmc24
The problem remains that using said approach to extend the API still wouldn't provide any way to gather the information needed for Swagger.  In your example, swaggerGet wouldn't ever be called unless the containing handler was invoked, and wouldn't have any awareness of what path it may have within the application (for example, if prefix had been used in the containing handlers).

I think that so far the best idea that's been proposed is to introduce some higher-order concept that creates the handlers used for the REST API, and can then be the place that "knows" about the different resource paths.

Maybe something like:

```
import ratpack.swagger.Swagger
import static ratpack.swagger.Swagger.api
import static ratpack.swagger.Swagger.pathInfo
import uber.*

handlers {
    prefix("api",
        api {
            apiInfo { it
                .title("Uber API")
                .description("Move your app forward with the Uber API")
                .version("1.0.0")
            }
            host("api.uber.com")
            basePath("/api")
            schemes("http", "https")
            consumes("application/json")
            produces("application/json")
            definitions(Product, PriceEstimate, Profile, Activity, Activities, Error)
            // ... and so on for parameters, responses, securityDefinitions, security, etc.
            get("products", pathInfo { it.summary("Product Types").description("...").parameter { ... }.tags("Products") }.response( ... ), {
                // handler body here
            })
            // ... more resource declarations go here
        }
    )
}
```
Reply | Threaded
Open this post in threaded view
|

Re: Swagger integration

davidmc24
I've created an issue on GitHub for further examination of this topic.

https://github.com/ratpack/ratpack/issues/603
Reply | Threaded
Open this post in threaded view
|

Re: Swagger integration

durbinjo593
Just curious -- has any progress or further thought been given to Swagger integration w/ Ratpack?