swagger-api / swagger-api/swagger-codegen

Support contract-first using Swagger spec pass-through

Open
#4,529 14 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Server: Java
Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

(Originally opened as swagger-core/#2075, moved here at @fehguy's suggestion.)

Our users have noticed a problem in the way their Java services, built from Swagger-codegen stubs as the starting point, provide Swagger-UI documentation at runtime. We'd like to get some perspective from the community, and see if there are known solutions or relevant discussions we may have missed.

Our solution provides a contract-first workflow for Swagger YAML, with an editing environment, real-time views, mocking, testing, and code gen.

Many of the Swagger-Codegen output templates take advantage of code-first Swagger integrations at runtime. The generated code includes annotations and project configurations (e.g. using swagger-core), so the running service dynamically generates Swagger and provides a Swagger-UI web page.

But we don't think this is an ideal solution, for a couple of reasons:

  • It entails an unnecessary "round trip" from the Swagger spec to annotated code at design time, and from code back to Swagger at runtime. Information can get lost or mangled in this round trip. Some of our users have had difficulty getting a correct and complete Swagger-UI at runtime.
  • It invites developers to edit the API descriptions directly in the generated code. This is expected for a code-first workflow. But with a contract-first workflow, we want all edits to be made in the Swagger source spec, and the code re-generated from this. Ideally, development teams will treat the Swagger spec as part of the source code, and code generation as part of the automated build.

So we don't want dynamic generation of the Swagger spec from code. However, these runtime Swagger integrations also perform some important functions that we don't want to lose:

  • They provide a web page with Swagger-UI pre-configured.
  • They serve this web page through a designated URL, usually /docs.
  • They also expose the dynamically assembled Swagger JSON and/or YAML through another URL.
  • They dynamically configure the Base URL in the generated Swagger, so it points to the running service instance. This is important, as it ensures that the "Try it out" sandbox feature works correctly, directing requests to the running instance, without any need for deployment-dependent pre-configuration of the Swagger spec.

Our users want to provide a Swagger-UI (or other documentation format) from their services. But they'd just like to use their original Swagger spec, not have it assembled dynamically at runtime. It seems reasonable to think that this should be an option, but we don't see a straightforward way to do this with the available components.

In particular:

  • Swagger-UI doesn't have a constructor param to override the base path for the "try it out" button; it uses the base path specified in the Swagger spec. If we want to dynamically set that to the base URL of the running service, we need to pre-process the Swagger spec before passing it into Swagger-UI.
  • Swagger-core doesn't seem to have an option to serve the Swagger-UI and Swagger spec pages using a static, pre-defined Swagger spec. AFAICT, it always assembles the Swagger spec from reflection, and uses this as the input to Swagger-UI.
  • Swagger-codegen doesn't seem to have any standard configuration options to serve a web page with Swagger-UI based on the original Swagger spec. The implementations are platform-specific, and AFAIK all of the Java stub generators rely on Swagger-core to serve the Swagger-UI page at runtime.

Of course our users can write their own code to serve a web page with Swagger-UI, configured to use their original Swagger spec, pre-processed to have the correct base URL. It's not terribly challenging, but it's not trivial. And everything in the Swagger component stack seems to be steering them towards dynamic Swagger.

This seems like a curious oversight. Swagger has matured from a pure code-first solution to the industry standard OpenAPI description language, with robust support for contract-first workflows. Are we missing something here?

We're experimenting with this, prototyping some possible solutions. We may consider releasing an open source component that solves this problem for Java (or JVM) services. But then we'd want to try to make Swagger-codegen (at least the Java stub generators) aware of this, and able to generate code that uses our component instead of Swagger-core.

I don't know if the maintainers of those generators would want to make a change like this. I'm sure they'd prefer it if Swagger-core and Swagger-UI had their own, native options to work with a pre-defined Swagger spec, and they could just re-tool their generators to support those options.

Thoughts?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the Java stub generators and the Swagger-core and Swagger-UI integration described in the issue; no specific files or tests are named. Compare the available runtime integrations with the requested contract-first flow. Done would provide a static original Swagger spec, Swagger-UI and spec endpoints, and a runtime-correct base URL.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, openapi
Domain
api, documentation
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.