honojs / hono

Web framework built on Web Standards
https://hono.dev
MIT License
20.61k stars 601 forks source link

OpenAPI and SwaggerUI support #717

Closed jylin closed 11 months ago

jylin commented 1 year ago

Is it a possibility to add support for OpenAPI and be able to use the Swagger UI?

yusukebe commented 1 year ago

Hi @jylin

We do not have a specific plan at this time, but I think we can do it. We could refer to "itty-router-openapi".

SwatDoge commented 1 year ago

I'd like to bump this suggestion. Elysiajs has support for swagger now and its great <3

yusukebe commented 1 year ago

Yes, I'd like to get started after a while of releasing v3.

Or someone could implement it...

verokarhu commented 1 year ago

Would this be contract-first or code-first?

transitive-bullshit commented 1 year ago

Would this be contract-first or code-first?

Code-first and auto-generating openapi schema from that code

Manouchehri commented 1 year ago

Mentioned in Discord as well, but this library will likely be helpful. https://github.com/asteasolutions/zod-to-openapi

amina-tekab commented 1 year ago

What's new in this issue?

masterbater commented 1 year ago

@yusukebe is this on the making?

yusukebe commented 1 year ago

@amina-tekab @masterbater

Yeah, I'm making one of the implementations for OpenAPI. That is using the zod-to-openapi, and it will exntend Hono class. After creating the POC, I'll make the project in the middleware repo.

Note, it's one of the ways. So, anyone can create other OpenAPI implementations.

masterbater commented 1 year ago

@amina-tekab @masterbater

Yeah, I'm making one of the implementations for OpenAPI. That is using the zod-to-openapi, and it will exntend Hono class. After creating the POC, I'll make the project in the middleware repo.

Note, it's one of the ways. So, anyone can create other OpenAPI implementations.

Thanks keep up the good work, discovered this and now Im using it more than expressjs

yusukebe commented 1 year ago

Hi everyone!

I've released Zod OpenAPI Hono:

https://github.com/honojs/middleware/tree/main/packages/zod-openapi

It's not fully documented, but you can try it!

masterbater commented 1 year ago

Hi everyone!

I've released Zod OpenAPI Hono:

https://github.com/honojs/middleware/tree/main/packages/zod-openapi

It's not fully documented, but you can try it!

Is it possible not writing a path, like it is based on the defined routes, we just need to write zod schema? Nestjs, elysiajs, ts-rest and trpc-openapi has some cool auto detect all endpoints and methods and generate also the body, query and params. Just writing the dto or zod schema. Could implementing this affect the compat of runtime environments.

yusukebe commented 1 year ago

@masterbater

Hmm. Have you ever tried it? I think the Zod OpenAPI Hono has same feature with other framework/libraries.

masterbater commented 1 year ago

@masterbater

Hmm. Have you ever tried it? I think the Zod OpenAPI Hono has same feature with other framework/libraries.

I havent tried it yet but read the docs, I was thinking if it would be possible to do it like this? Just one helper to generate everything.

const app = new Hono();

app.get("*", prettyJSON());

app.route("/teachers", teacherController);

const openApiDocument = generateOpenApi(app, {
  info: {
    title: 'Posts API',
    version: '1.0.0',
  },
});
masterbater commented 1 year ago

@masterbater

Hmm. Have you ever tried it? I think the Zod OpenAPI Hono has same feature with other framework/libraries.

I got it so this is a real hono server?

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

const app = new OpenAPIHono() //this is a real server not just a document builder?
const route = createRoute({
  method: 'get',
  path: '/users/:id',
  request: {
    params: ParamsSchema,
  },
  responses: {
    200: {
      content: {
        'application/json': {
          schema: UserSchema,
        },
      },
      description: 'Get the user',
    },
  },
})
app.openapi(route, (c) => {
  const { id } = c.req.valid('param')
  return c.jsonT({
    id,
    age: 20,
    name: 'Ultra-man',
  })
})

// OpenAPI document will be served on /doc
app.doc('/doc', {
  openapi: '3.0.0',
  info: {
    version: '1.0.0',
    title: 'My API',
  },
})
yusukebe commented 1 year ago

@masterbater

I got it so this is a real hono server?

Yes. As same as Hono. You can do:

export default app
hectorAguero commented 1 year ago

I think this limitation is really big, how I suppose to structure a real project? putting all the routes in the main file?

An instance of Zod OpenAPI Hono cannot be used as a "subApp" in conjunction with rootApp.route('/api', subApp)

yusukebe commented 1 year ago

Hi @hectorAguero,

You're absolutely right; it's a significant feature. However, for now, you can make use of the app.mount() method:

const app = new Hono()

app.use('*', cors())
app.mount('/api', api.fetch)

export default app

Could you give this a try and let me know your thoughts?

hectorAguero commented 1 year ago

@yusukebe I tried now, I coudn't get the '/doc' to work when I use mount more than once

I tried with the updated readme implementation, but in that case between 'users/doc' and 'posts/doc', only the first one retrieve me the json

// localhost:3000/doc return a 404 Not Found
app.mount("/users", usersApi.fetch);
app.mount("/posts", postsApi.fetch);

Btw I also tried mounting like this, but mount only work the first time, I guess because it was the same path

// Need to set the full path inside each api
app.mount("/api", usersApi.fetch); 
app.mount("/api", postsApi.fetch); // this didn't got mounted

posts/index.ts basePath('/posts') not working

// const postsApi = new OpenAPIHono().basePath('/posts');
const postsApi = new OpenAPIHono();
...
export default postsApi;

I would like to see an example using the https://jsonplaceholder.typicode.com/ or similar

yusukebe commented 1 year ago

@hectorAguero

The documentation is not accessible via /doc, but rather through /users/doc or /posts/doc.

Also, you shouldn't structure your code like this:

app.mount("/api", usersApi.fetch); 
app.mount("/api", postsApi.fetch);

Instead, use the following:

app.mount("/api/users", usersApi.fetch); 
app.mount("/api/posts", postsApi.fetch);
hectorAguero commented 1 year ago

The documentation is not accessible via /doc, but rather through /users/doc or /posts/doc.

So I found my problem, it was the paramsSchema that I set for the requests params in the routes /users/:id and /posts/id.

And because "doc" wasn't parsable number, zod return an error, I move the usersApi.get('/doc' right after I declare const usersApi = new OpenAPIHono(); and it got fixed.

sor4chi commented 1 year ago

Hono released Third party support for Swagger UI just yesterday. OpenAPI is already supported as well. In other words, support for both is now complete within Hono.

yusukebe commented 11 months ago

As @sor4chi mentioned, Hono now supports both OpenAPI and SwaggerUI. So, I'll close this issue.