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

Swagger Editor middleware #1415

Closed
yusukebe opened this issue Sep 6, 2023 · 11 comments
Closed

Swagger Editor middleware #1415

yusukebe opened this issue Sep 6, 2023 · 11 comments
Labels
enhancement New feature or request. middleware

Comments

@yusukebe
Copy link
Member

yusukebe commented Sep 6, 2023

What is the feature you are proposing?

Like this:

https://editor.swagger.io/

We may make it without depending external libraries, but I think it should be a 3rd party middleware.

@yusukebe yusukebe added the enhancement New feature or request. label Sep 6, 2023
@Manouchehri
Copy link
Contributor

Manouchehri commented Sep 6, 2023

For Stoplight Elements, the code we use looks like:

import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi'
import { logger } from 'hono/logger'

declare type Bindings = {
  ENVIRONMENT: "dev" | "production";
};

declare type Env = {
  Bindings: Bindings;
};

const ParamsSchema = z.object({
  id: z
    .string()
    .min(3)
    .openapi({
      param: {
        name: 'id',
        in: 'path',
      },
      example: '1212121',
    }),
})

const UserSchema = z
  .object({
    id: z.string().openapi({
      example: '123',
    }),
    name: z.string().openapi({
      example: 'John Doe',
    }),
    age: z.number().openapi({
      example: 42,
    }),
  })

const route = createRoute({
  method: 'get',
  path: '/users/{id}',
  request: {
    params: ParamsSchema,
  },
  responses: {
    200: {
      content: {
        'application/json': {
          schema: UserSchema,
        },
      },
      description: 'Retrieve the user',
    },
  },
})

const app = new OpenAPIHono<Env>()

app.use('*', logger())


app.openapi(route, (c) => {
  const { id } = c.req.valid('param')
  console.debug(c.env.ENVIRONMENT)
  return c.jsonT({
    id,
    age: 20,
    name: 'Ultra-man',
  })
})

app.doc('/openapi.json', {
  openapi: '3.0.0',
  info: {
    version: '1.0.0',
    title: 'My API'
  },
  tags: [
    {
      name: 'language',
      description: 'en'
    }
  ]
})

app.get('/docs/', (c) => {
  return c.html(`<!doctype html>
<html lang="en">
  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      <title>API Docs</title>
      <meta name="author" content="ai.moda">
      <meta name="title" content="API Docs" />
      <script async src="https://stoplight-elements.ai.moda/web-components.min.js"></script>
      <link rel="stylesheet" href="https://stoplight-elements.ai.moda/styles.min.css">
      </head>
    <body>

    <div style="height: 100vh;">
        <elements-api
            apiDescriptionUrl="/openapi.json"
            router="hash"
            layout="sidebar"
            tryItCredentialsPolicy="include"
            withCredentials="true"
        />
    </div>
  </body>
</html>
`, 200, {
  'Content-Security-Policy': "default-src 'none'; script-src https://stoplight-elements.ai.moda/web-components.min.js 'unsafe-eval'; style-src https://stoplight-elements.ai.moda/styles.min.css 'unsafe-inline'; connect-src 'self'"
})
})

export default app

@yusukebe
Copy link
Member Author

yusukebe commented Sep 8, 2023

Thanks @Manouchehri

Or, I think we can also make "swagger-ui" - @hono/swagger-ui middleware using swagger-ui-dist via CDN:

https://swagger.io/docs/open-source-tools/swagger-ui/usage/installation/

@yusukebe
Copy link
Member Author

yusukebe commented Sep 8, 2023

Is there anyone make it?

cc: @sor4chi

@sor4chi
Copy link
Contributor

sor4chi commented Sep 8, 2023

I think it is almost the same as the way with the stoplight element.
Here is an example using swagger-ui-dist!

import type { Context } from 'hono'

export function swaggerUI() {
  return async (c: Context) =>
    c.html(`
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Swagger UI</title>
    <script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.6.2/swagger-ui-bundle.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.6.2/swagger-ui.min.css" rel="stylesheet">
  </head>
  <body>
    <div id="swagger-ui"></div>
    <script>
      window.onload = function() {
        SwaggerUIBundle({
          url: '/openapi.json',
          dom_id: '#swagger-ui',
          presets: [
            SwaggerUIBundle.presets.apis,
            SwaggerUIBundle.SwaggerUIStandalonePreset
          ],
        })
      }
    </script>
  </body>
</html>
`)
}

@sor4chi
Copy link
Contributor

sor4chi commented Sep 8, 2023

I'm trying to see if I can't take advantage of being a thirdparty and pass the return value of createRoute directly to the swaggerUI Middleware option.

@Manouchehri
Copy link
Contributor

I also updated #1415 (comment) to include the correct and "best" CORS rule (that I know of right now) for Stoplight Elements. 😄

@rafaell-lycan
Copy link

@yusukebe @Manouchehri should this be an optional config on @hono/zod-openapi?

@yusukebe
Copy link
Member Author

yusukebe commented Oct 1, 2023

@rafaell-lycan

No. I think it should be a middleware independent of @hono/zod-openapi like honojs/middleware#168

@sor4chi
Copy link
Contributor

sor4chi commented Nov 8, 2023

I think we can close this issue by this Swagger UI Milldeware releases.

@yusukebe

@yusukebe
Copy link
Member Author

yusukebe commented Nov 8, 2023

Swagger UI Middleware is published, but Swagger UI is not Swagger Editor: https://github.com/swagger-api/swagger-editor

@sor4chi
Copy link
Contributor

sor4chi commented Nov 8, 2023

Opps, I see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request. middleware
Projects
None yet
Development

No branches or pull requests

4 participants