davidebianchi / gswagger

Generate an openapi spec dynamically based on the types used to handle request and response
https://pkg.go.dev/github.com/davidebianchi/gswagger
MIT License
30 stars 8 forks source link

How to use with Fiber #133

Closed gaby closed 9 months ago

gaby commented 1 year ago

Hello @davidebianchi , I'm trying to use this with Fiber but the example is not very clear. Assuming my Fiber main is as follow:

func main() {
  app := fiber.New()

  api := app.Group("/api", middleware) // /api

  v1 := api.Group("/v1", middleware)   // /api/v1
  v1.Get("/list", handler)             // /api/v1/list
  v1.Get("/user", handler)             // /api/v1/user

  v2 := api.Group("/v2", middleware)   // /api/v2
  v2.Get("/list", handler)             // /api/v2/list
  v2.Get("/user", handler)             // /api/v2/user

  log.Fatal(app.Listen(":3000"))
}

How do you add gswagger support?

fredmaggiowski commented 1 year ago

Hi, this code block should be enough:

import (
    oasFiber "github.com/davidebianchi/gswagger/support/fiber"
)

...

func main() {
    app := fiber.New()
    // app definition

    oasRouter, err := swagger.NewRouter(oasFiber.NewRouter(app), swagger.Options{
        Context: context.Background(),
        Openapi: &openapi3.T{
            Info: &openapi3.Info{
                Title:   "my-service",
                Version: "the version",
            },
        },
        JSONDocumentationPath: "/swagger/json",
        YAMLDocumentationPath: "/swagger/yaml",
    })

    if err = oasRouter.GenerateAndExposeOpenapi(); err != nil {
        return nil, err
    }
}

Does it make sens to you?

gaby commented 1 year ago

@fredmaggiowski Thanks, I will give it a try today and report back.

gaby commented 9 months ago

@fredmaggiowski I have the following, but have no idea how to access the content generated by gswagger.

package main

import (
    "context"
    swagger "github.com/davidebianchi/gswagger"
    oasFiber "github.com/davidebianchi/gswagger/support/fiber"
    "github.com/gofiber/fiber/v2"
    "github.com/getkin/kin-openapi/openapi3"
)

func main() {
    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("GET request")
    })

    app.Post("/", func(c *fiber.Ctx) error {
        return c.SendString("POST request")
    })
    oasRouter, _ := swagger.NewRouter(oasFiber.NewRouter(app), swagger.Options{
        Context: context.Background(),
        Openapi: &openapi3.T{
            Info: &openapi3.Info{
                Title:   "my-service",
                Version: "the version",
            },
        },
        JSONDocumentationPath: "/swagger/json",
        YAMLDocumentationPath: "/swagger/yaml",
    })

    oasRouter.GenerateAndExposeOpenapi()
    app.Listen(":3000")
}

On which path is the OpenAPI exposed to? /swagger, /openapi both return nothing.

gaby commented 9 months ago

Found it /swagger/json, mine returns empty though.

image

davidebianchi commented 9 months ago

Hi @gaby! Yes, the path is that.

You should create the routes after the setup of gswagger router, as in this test setup: https://github.com/davidebianchi/gswagger/blob/main/support/fiber/integration_test.go#L120-L139

The base usage is with the AddRoute method.

gaby commented 9 months ago

@davidebianchi Thanks, got it to work with:

package main

import (
    "context"
    "net/http"

    swagger "github.com/davidebianchi/gswagger"
    oasFiber "github.com/davidebianchi/gswagger/support/fiber"
    "github.com/getkin/kin-openapi/openapi3"
    "github.com/gofiber/fiber/v2"
)

func main() {
    app := fiber.New(fiber.Config{
        EnablePrintRoutes: true,
    })

    router, _ := swagger.NewRouter(oasFiber.NewRouter(app), swagger.Options{
        Context: context.Background(),
        Openapi: &openapi3.T{
            Info: &openapi3.Info{
                Title:   "my-service",
                Version: "the version",
            },
        },
        JSONDocumentationPath: "/swagger/json",
        YAMLDocumentationPath: "/swagger/yaml",
    })

    _, _ = router.AddRawRoute(http.MethodGet, "/hello", okHandler, swagger.Operation{})

    router.GenerateAndExposeOpenapi()

    app.Listen(":3000")
}

func okHandler(c *fiber.Ctx) error {
    c.Status(http.StatusOK)
    return c.SendString("OK")
}

Makes me wonder if there's a way to simplify this, as to not have to use router.AddRawRoute(). We do have the GetRoutes() method which I think could be used to simplify this?

https://docs.gofiber.io/api/app#getroutes

Edit: It doesn't return the handler, I think that's a problem.

davidebianchi commented 9 months ago

Yes, if the handler is not returned it could be a problem. Also, inside the last params of the AddRawRoute and AddRoute methods there are the logic to set in the api documentation the json schema of the request and the response, which would not be possible using the GetRoutes method.

gaby commented 9 months ago

I'm going to close this since the examples above proof that gswagger can be used with Fiber. Thanks for your help! 💪