Search code examples
goswagger-uiswagger-2.0vercelgo-swagger

Why Swagger with Golang is not working in Vercel production?


I have a Golang project, deployed in vercel environment. Everything is working fine but swagger. Swagger implementation is working fine in dev environment but in the production same route doesn't work. I have used gin-swagger, swag, gin-gonic, vercel. Here is the vercel config file:

vercel.json:

{
    "$schema": "https://openapi.vercel.sh/vercel.json",
    "github": {
    "silent": true
    },
    "trailingSlash": false,
    "redirects": [
    {
        "source": "/",
        "destination": "/api",
        "permanent": false
    },
    {
        "source": "/api",
        "destination": "/api/ping",
        "permanent": false
    }
    ],
    "rewrites": [
    {
        "source": "/api/(.*)",
        "destination": "/api/index.go"
    }
    ]
}

Here is the index.go file:

package api

import (
    "net/http"

    _ "WerkenServer/docs"
    "WerkenServer/handler"

    "github.com/gin-gonic/gin"
    swaggerFiles "github.com/swaggo/files"
    ginSwagger "github.com/swaggo/gin-swagger"
)

var (
    app *gin.Engine
)

func registerRouter(r *gin.RouterGroup) {
    r.GET("/ping", handler.Ping)
    r.GET("/doc/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    ginSwagger.WrapHandler(swaggerFiles.Handler,
        ginSwagger.URL("https://werken-server.vercel.app/api/doc/doc.json"),
        ginSwagger.DefaultModelsExpandDepth(-1))
}

func init() {
    app = gin.New()

    app.NoRoute(handler.ErrRouter)
    r := app.Group("/api")
    registerRouter(r)
}

// Entrypoint
func Handler(w http.ResponseWriter, r *http.Request) {
    app.ServeHTTP(w, r)
}

Solution

  • I have talked with vercel team and they found an issue in their system. c.Request.RequestURI is returning sometimes empty. They ensured they will solve the issue, and provided me a workaround to unblock. Here is the workaround,

    func init() {
        app = gin.New()
        app.GET("/doc/*any", FixRequestUri)
    }
    
    func FixRequestUri(c *gin.Context) {
        if c.Request.RequestURI == "" {
            c.Request.RequestURI = c.Request.URL.Path
        }
    
        ginSwagger.WrapHandler(swaggerFiles.Handler)(c)
    }
    

    You can get the full workable example code here: Golang vercel example template