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

Add service to provide granular control over generated resources (like guards) #2847

Open
1 task done
davidschuette opened this issue Feb 19, 2024 · 1 comment
Open
1 task done
Labels

Comments

@davidschuette
Copy link

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

I want to integrate swagger files more tightly in my application. One case is to use custom authentication (guards) to restrict access to the generated resources. This would be possible with a dedicated SwaggerService. This service would provide access to all resources (like html file, openapi spec), but can be used more granular.

Example:

@Controller()
export class SomeController {
  constructor(private readonly swaggerService: SwaggerService) {}

  @Get()
  @UseGuards(CustomGuard)
  getHtmlFile() {
    return this.swaggerService.getHtml();
  }

 ....
}

Describe the solution you'd like

Create an injectable service like SwaggerService that can be used to get a readable stream / buffer of each generated resources by the swagger module.
Provide an option to disable automatic registration of routes for swagger resources when instantiating the SwaggerModule.

Maybe more features I did not think of.

Drawbacks:

  • increased complexity

Teachability, documentation, adoption, migration strategy

No response

What is the motivation / use case for changing the behavior?

  • Use existing authentication & authorization instead of using something like express-basic-auth (as discussed here auth protect for swagger access url #244)
  • Process files further before exposing them to an endpoint
@kurt-west
Copy link
Contributor

After you've create the document with SwaggerModule.createDocument() it can be consumed like any other OpenAPI spec document. The elegance of SwaggerModule.setup() is it configures the static asset server and creates the endpoints for you. The downside is that they are public endpoints; not sure if you can directly pass a spec object to the swagger-ui, the examples show loading it from a url.

I find ReDoc easier to navigate and customize, it's also dead simple to serve, pull it from their CDN and pass in the stringified spec document.

Quick POC to replicate SwaggerModule.setup(), from here it's fairly simple to move this to a service.

/** The typical swagger stuff here... */

const html = `<!DOCTYPE html>
<html>
  <head>
    <title>[[title]]</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet" />
    <style>
      body {
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="redoc-container"></div>
    <script nonce='' src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"> </script>
    <script>
    Redoc.init(
      [[openApiSpec]],
      {},
      document.getElementById("redoc-container")
    );
    </script>
  </body>
</html>`;

app.use('/open-api', (request: Request, response: Response) => {
  response.type('html');
  response.send(
    html.replace('[[title]]', 'OpenApi').replace('[[openApiSpec]]', JSON.stringify(document)),
  );
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants