Comments (15)
Hey everyone! I had the same issue but looks like the version 2.0.1 fixes it removing the singleton (dce10a8#diff-44aa764656674984f26bf27a7bcd56f8c03ea4f6b1ee8b02c48bd7e6c6c8206fL172)
I upgraded and now it's under test.
from http-swagger.
Hi,
I am getting the same issue but using echo-swagger
echo.GET("/swagger/*", echoSwagger.WrapHandler)
echo.GET("/test/", h.Status, enforcer.Enforce)
echo.Start(":8080")
After more than 48 hours working, suddenly the app starts to drop 404 loading css, js that you mentioned.
Failed to load resource: the server responded with a status of 404 (Not Found)
swagger-ui-bundle.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)
swagger-ui-standalone-preset.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)
index.html:75 Uncaught ReferenceError: SwaggerUIBundle is not defined
at window.onload (index.html:75)
swagger-ui.css:1 Failed to load resource: the server responded with a status of 404 (Not Found)
If i restart app, it starts to work... but i dont know why it happens.
from http-swagger.
You can do it like this:
routes := httprouter.New()
routes.GET("/doc/:any", swaggerHandler)
func swaggerHandler(res http.ResponseWriter, req *http.Request, p httprouter.Params) {
httpSwagger.WrapHandler(res, req)
}
Do not forget import doc files:
import (
_ "example.project/docs"
)
from http-swagger.
@umurpza this is the solution I came up with, and it has been working fine. It's not ideal because I have to make a new handler internally for each request because of how httpSwagger.Handler
works, but it at least got me going.
import (
"fmt"
swagGroupA "path/to/swaggerdocs/a" // built targeting tag a
swagGroupB "path/to/swaggerdocs/b" // built targeting tag b
swagGroupC "path/to/swaggerdocs/c" // built targeting tag c
httpSwagger "github.com/swaggo/http-swagger"
"github.com/swaggo/swag"
"github.com/gin-gonic/gin"
)
var (
// config options for display: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/#display
swagUiConfig = httpSwagger.UIConfig(map[string]string{
// this map goes into the client-side as raw json, but apparently not using json.Marshal,
// so "true" -> true, `"model"` -> "model", etc...
"displayOperationId": "true",
"defaultModelRendering": `"model"`,
"filter": "true",
"showExtensions": "true",
"syntaxHighlight": `{"active":"true","theme":"obsidian"}`,
"tagSorter": `"alpha"`,
})
)
func setupSwaggerRoutes(r *gin.RouterGroup) {
r.GET("/swagger/a/*any", func(ctx *gin.Context) { swagSpecHandler(swagGroupA.SwaggerInfobridge, ctx) })
r.GET("/swagger/b/*any", func(ctx *gin.Context) { swagSpecHandler(swagGroupB.SwaggerInfohttp, ctx) })
r.GET("/swagger/c/*any", func(ctx *gin.Context) { swagSpecHandler(swagGroupC.SwaggerInfopos, ctx) })
}
func swagSpecHandler(spec *swag.Spec, ctx *gin.Context) {
instName := spec.InstanceName() //custom instances like /a, /b, etc...
// Cannot cache the handlers due to an issue I worked through while debugging the http-swagger code.
// They have a singleton in play under the hood, and their Handler only writes to that singleton in a `sync.Once`.
// See https://github.com/swaggo/http-swagger/issues/10#issuecomment-1358163317
// Once it is fixed, we can go back to caching the handler
spec.Host = "https://some-domain/api"
gin.WrapH(httpSwagger.Handler(
// note: have to have _both_ the InstanceName and the URL to the `doc.json` setup properly.
// See also: https://github.com/swaggo/http-swagger/blob/6ee8ad96a7f258e1531d470d9e220ee7beee7a16/swagger.go#L178
httpSwagger.InstanceName(instName),
httpSwagger.URL(fmt.Sprintf("/api/swagger/%s/doc.json", instName)),
httpSwagger.DocExpansion("none"),
swagUiConfig,
))(ctx)
}
from http-swagger.
I'm not able to reproduce your issue.
anyway you should try changing to
router.PathPrefix("/documentation").Handler(httpSwagger.WrapHandler)
If you got things working out, please , leave a comment about how you solved it and close the issue.
from http-swagger.
Got the same issue, I will update if resolved
from http-swagger.
my problem was that my code was stripping the prefix from r.URL.Path
, and http-swagger got the same prefix from r.RequestURI
(swagger.go:71), because it wasn't stripped. then in net/webdav.go:195 it looked for this prefix in r.URL.Path
which didn't exist and failed. I fixed it by not stripping the prefix in my code
from http-swagger.
@chiptus router.PathPrefix("/documentation/") doesn't strip the prefix. It actually instructs the router when it has a request to "/documentation" path to call the httpSwagger handler.
And yes, maybe the WrapHandler may require some adjustments if you want to use a custom route.
from http-swagger.
just added my solution for future knowledge. I'm actually using vanilla net/http without frameworks
from http-swagger.
Is there any solution for this problem?
I had the same issue, and couldn't fix it the same way as @chiptus.
from http-swagger.
any news on this issue ? It's happening the same to me.
from http-swagger.
I have the exact same issue (using julienschmidt/http-router).
Minimal code to reproduce
package main
import (
"fmt"
"log"
"net/http"
"github.com/julienschmidt/httprouter"
httpSwagger "github.com/swaggo/http-swagger"
)
func main() {
router := httprouter.New()
router.ServeFiles("/api/doc/static/*filepath", http.Dir("path/to/swagger/files"))
router.HandlerFunc(http.MethodGet, "/api/doc/index.html", swaggerHandler)
fmt.Println("Server on port 8080")
log.Fatal(http.ListenAndServe(":8080", router))
}
func swaggerHandler(w http.ResponseWriter, r *http.Request) {
swaggerFileUrl := "http://localhost:8080/api/doc/static/swagger.json"
handler := httpSwagger.Handler(httpSwagger.URL(swaggerFileUrl))
handler.ServeHTTP(w, r)
}
from http-swagger.
Hey @ubogdan I am able to reproduce this. With the most recent swag updates allowing to generate swag docs only for targeted --tags
, we split up our docs into separate directories and separate http endpoints. The wiring looks like this:
import (
// generated swag docs per tag targeted
swagBridge "pos-api/internal/api/swaggerdocs/bridge"
swagHttp "pos-api/internal/api/swaggerdocs/http"
swagPos "pos-api/internal/api/swaggerdocs/pos"
swagProvisioner "pos-api/internal/api/swaggerdocs/provisioner"
swagSolo "pos-api/internal/api/swaggerdocs/solo"
swagSupport "pos-api/internal/api/swaggerdocs/support"
swagTools "pos-api/internal/api/swaggerdocs/tools"
// http-swagger for handler func
httpSwagger "github.com/swaggo/http-swagger"
// ... other imports
)
var (
// config options for display: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/#display
swagUiConfig = httpSwagger.UIConfig(map[string]string{
"displayOperationId": "true",
"defaultModelRendering": `"model"`,
"filter": "true",
"showExtensions": "true",
"syntaxHighlight": `{"active":"true","theme":"obsidian"}`,
"tagSorter": `"alpha"`,
})
ginHandlers = map[string]gin.HandlerFunc{}
)
func setupSwaggerRoutes(r *gin.RouterGroup) {
r.GET("/swagger/bridge/*any", func(ctx *gin.Context) { swagSpecHandler(swagBridge.SwaggerInfobridge, ctx) })
r.GET("/swagger/http/*any", func(ctx *gin.Context) { swagSpecHandler(swagHttp.SwaggerInfohttp, ctx) })
r.GET("/swagger/pos/*any", func(ctx *gin.Context) { swagSpecHandler(swagPos.SwaggerInfopos, ctx) })
r.GET("/swagger/provisioner/*any", func(ctx *gin.Context) { swagSpecHandler(swagProvisioner.SwaggerInfoprovisioner, ctx) })
r.GET("/swagger/solo/*any", func(ctx *gin.Context) { swagSpecHandler(swagSolo.SwaggerInfosolo, ctx) })
r.GET("/swagger/support/*any", func(ctx *gin.Context) { swagSpecHandler(swagSupport.SwaggerInfosupport, ctx) })
r.GET("/swagger/tools/*any", func(ctx *gin.Context) { swagSpecHandler(swagTools.SwaggerInfotools, ctx) })
}
func swagSpecHandler(spec *swag.Spec, ctx *gin.Context) {
instName := spec.InstanceName() //custom instances like /bridge, /pos, etc...
if _, exists := ginHandlers[instName]; !exists {
cfg := middleware.HTTPRetrieveAPIConfig(ctx)
spec.Host = cfg.Host
ginHandlers[instName] = gin.WrapH(httpSwagger.Handler(
// note: have to have _both_ the InstanceName and the URL to the `doc.json` setup properly.
// See also: https://github.com/swaggo/http-swagger/blob/6ee8ad96a7f258e1531d470d9e220ee7beee7a16/swagger.go#L178
httpSwagger.InstanceName(instName),
httpSwagger.URL(fmt.Sprintf("/api/swagger/%s/doc.json", instName)),
httpSwagger.DocExpansion("none"),
swagUiConfig,
))
}
ginHandlers[instName](ctx)
}
The intent was to only create each handler once, for efficiency. However, the swaggerFiles
package seems to have a singleton in place. The swag-http
handler tries to set the Prefix
of that handler in a sync.Once
func:
handler := swaggerFiles.Handler
once.Do(func() {
handler.Prefix = matches[1]
})
However, if we try to have separate swag doc routes, this singleton poses a problem. As I switch through the routes in the browser, the first run of each endpoint always works. However, once the sync.Once
for each http-swagger
Handler
has run, there is no more setting of the swaggerFiles.Prefix
- so whatever the last-loaded Prefix
is seems to be the one used.
What I'm going to have to do is create the handler anew for each request, which seems terribly inefficient. I don't see another way around this though.
Maybe I'm missing something or there is a better way to structure this?
from http-swagger.
Hi,
I am getting the same issue but using echo-swagger
echo.GET("/swagger/*", echoSwagger.WrapHandler) echo.GET("/test/", h.Status, enforcer.Enforce) echo.Start(":8080")After more than 48 hours working, suddenly the app starts to drop 404 loading css, js that you mentioned.
Failed to load resource: the server responded with a status of 404 (Not Found) swagger-ui-bundle.js:1 Failed to load resource: the server responded with a status of 404 (Not Found) swagger-ui-standalone-preset.js:1 Failed to load resource: the server responded with a status of 404 (Not Found) index.html:75 Uncaught ReferenceError: SwaggerUIBundle is not defined at window.onload (index.html:75) swagger-ui.css:1 Failed to load resource: the server responded with a status of 404 (Not Found)
If i restart app, it starts to work... but i dont know why it happens.
Did you find a solution for this? I'm using Gin and having the same issue you described. After a certain amount of time, I get 404's on swagger files. Much less than 48 hours at times.
Errors:
Failed to load resource: the server responded with a status of 404 (Not Found)
swagger-ui-standalone-preset.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)
swagger-ui-bundle.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)
favicon-32x32.png:1 Failed to load resource: the server responded with a status of 404 (Not Found)
favicon-16x16.png:1 Failed to load resource: the server responded with a status of 404 (Not Found)
index.html:75 Uncaught ReferenceError: SwaggerUIBundle is not defined
at window.onload (index.html:75:14)
swagger-ui.css:1 Failed to load resource: the server responded with a status of 404 (Not Found)
from http-swagger.
@umurpza this is the solution I came up with, and it has been working fine. It's not ideal because I have to make a new handler internally for each request because of how
httpSwagger.Handler
works, but it at least got me going.import ( "fmt" swagGroupA "path/to/swaggerdocs/a" // built targeting tag a swagGroupB "path/to/swaggerdocs/b" // built targeting tag b swagGroupC "path/to/swaggerdocs/c" // built targeting tag c httpSwagger "github.com/swaggo/http-swagger" "github.com/swaggo/swag" "github.com/gin-gonic/gin" ) var ( // config options for display: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/#display swagUiConfig = httpSwagger.UIConfig(map[string]string{ // this map goes into the client-side as raw json, but apparently not using json.Marshal, // so "true" -> true, `"model"` -> "model", etc... "displayOperationId": "true", "defaultModelRendering": `"model"`, "filter": "true", "showExtensions": "true", "syntaxHighlight": `{"active":"true","theme":"obsidian"}`, "tagSorter": `"alpha"`, }) ) func setupSwaggerRoutes(r *gin.RouterGroup) { r.GET("/swagger/a/*any", func(ctx *gin.Context) { swagSpecHandler(swagGroupA.SwaggerInfobridge, ctx) }) r.GET("/swagger/b/*any", func(ctx *gin.Context) { swagSpecHandler(swagGroupB.SwaggerInfohttp, ctx) }) r.GET("/swagger/c/*any", func(ctx *gin.Context) { swagSpecHandler(swagGroupC.SwaggerInfopos, ctx) }) } func swagSpecHandler(spec *swag.Spec, ctx *gin.Context) { instName := spec.InstanceName() //custom instances like /a, /b, etc... // Cannot cache the handlers due to an issue I worked through while debugging the http-swagger code. // They have a singleton in play under the hood, and their Handler only writes to that singleton in a `sync.Once`. // See https://github.com/swaggo/http-swagger/issues/10#issuecomment-1358163317 // Once it is fixed, we can go back to caching the handler spec.Host = "https://some-domain/api" gin.WrapH(httpSwagger.Handler( // note: have to have _both_ the InstanceName and the URL to the `doc.json` setup properly. // See also: https://github.com/swaggo/http-swagger/blob/6ee8ad96a7f258e1531d470d9e220ee7beee7a16/swagger.go#L178 httpSwagger.InstanceName(instName), httpSwagger.URL(fmt.Sprintf("/api/swagger/%s/doc.json", instName)), httpSwagger.DocExpansion("none"), swagUiConfig, ))(ctx) }
This seems to be working for me. Thanks!
from http-swagger.
Related Issues (20)
- Generating Dynamic Routes? HOT 1
- Remove leading '$' from command snippets in README.md
- add defaultModelsExpandDepth to config
- Unkown LeftDelim and RightDelim in struct literal of type in generated docs/docs.go (linter error)
- swagger/index.html loads a default swagger/doc.json but not docs/swagger.json HOT 2
- Question: Is it possible not one docs dir? Not one Register HOT 3
- running chi example HOT 1
- Go 1.22 ServeMux documentation
- handle serve yaml like json HOT 1
- how to set bearer token HOT 1
- Upgrade go version to >=1.18
- Data race in `Handler`, modifies global from `swaggo/files` package but `sync.Once` protection is function scoped HOT 2
- placeholder for pull request
- Allow supporting multiple BeforeScript and AfterScript configs
- Allow adding external scripts to the index.html
- Blank page when accessing swagger HOT 6
- It is imposible to show different swagger instances HOT 1
- There is not option to change the layout
- Blank page on Go-chi example HOT 1
- r.RequestURI should be changed to r.URL.Path HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from http-swagger.