Gin: Using static with root handler

Created on 24 May 2015  路  10Comments  路  Source: gin-gonic/gin

rtr.Static("/static", "./static")
rtr.GET("/:slug", handlePost)
panic: wildcard route ':slug' conflicts with existing children in path '/:slug'

Any way to solve that? I could prefix /:slug with /post/:slug but I don't want to do that. I'd like /static/ to serve static files and handlePost to handle everything else.

Most helpful comment

@romeovs engine.Static is designed for paths like /static, not a root path combined with other handlers.

you should use static middleware, see its example 馃槂
https://github.com/gin-contrib/static#canonical-example

r.Use(static.Serve("/", static.LocalFile("/tmp", false)))

All 10 comments

I ended up handling it by removing rtr.GET("/:slug", handlePost) and doing the following

rtr.NoRoute(handleDefault)
//...
func handleDefault(ctx *gin.Context) {
    if ctx.Request.URL.Path == "/" {
        handleRoot(ctx)
        return
    }
    if !handlePost(ctx) {
        ctx.String(http.StatusNotFound, "404 Not Found")
    }
}

@brettof86 yeah, it sucks.
Serving for /static or using NoRoute() are possible workarounds.

Once Gin 1.0 golden master is ready, I will try to implement a more flexible router. But there are not plans for complex matching (like gorilla). Gin's new routers has to be as fast as the current one.

We can't just iterate over a list of regex patterns ;)

Understandable. I doubt it's this simple but perhaps it could loop non-generic paths first then follow with generic routes.聽

鈥斅燬ent from Mailbox

On Wed, May 27, 2015 at 8:14 PM, Manu Mtz.-Almeida
[email protected] wrote:

@brettof86 yeah, it sucks.
Serving for /static or using NoRoute() are possible workarounds.
Once Gin 1.0 golden master is ready, I will try to implement a more flexible router. But there is not plan for complex matching (like gorilla). Gin's new routers has to be as fast as the current one.

We can't just iterate over a list of regex patterns ;)

Reply to this email directly or view it on GitHub:
https://github.com/gin-gonic/gin/issues/301#issuecomment-106130050

@brettof86 yeah, anyway I need to recreate the router, httpRouter is pretty much unintelligible, very difficult to maintain...

In the meantime, I have been improving the performance of 404 handling:
https://github.com/gin-gonic/gin/commit/835f66fdc9ce24a3074055b3b801a7f8e101993f
https://github.com/gin-gonic/gin/commit/b7a15d3554756a6ee82e09fc0e1ae78bbaa270ef

benchmark            old ns/op     new ns/op     delta
Benchmark404         737           237           -67.84%
Benchmark404Many     2330          390           -83.26%

benchmark            old allocs     new allocs     delta
Benchmark404         3              0              -100.00%
Benchmark404Many     10             0              -100.00%

benchmark            old bytes     new bytes     delta
Benchmark404         115           68            -40.87%
Benchmark404Many     235           68            -71.06%

Are there any updates on this?

@romeovs engine.Static is designed for paths like /static, not a root path combined with other handlers.

you should use static middleware, see its example 馃槂
https://github.com/gin-contrib/static#canonical-example

r.Use(static.Serve("/", static.LocalFile("/tmp", false)))

Nothing new after 2 years? Still no straightforward way to do root handler?

@Tom29 I agree. I'm struggling to do such a basic thing, maybe I'll switch back to httprouter...

@romeovs engine.Static is designed for paths like /static, not a root path combined with other handlers.

you should use static middleware, see its example
https://github.com/gin-contrib/static#canonical-example

r.Use(static.Serve("/", static.LocalFile("/tmp", false)))

Still not working...

My code:

```golang
func startServer(conf config.ServConfig) error {
app := gin.Default()
app.Use(sentrygin.New(sentrygin.Options{
Repanic: false,
WaitForDelivery: false,
Timeout: 5 * time.Second,
}))
app.LoadHTMLGlob("templates/*.tmpl")
app.POST("/api/upload", content_tools.UserUploadParse)
app.DELETE("/api/admin", content_tools.DeleteSnip)
app.Use(static.Serve("/", static.LocalFile("/static", false)))
app.GET("/:shortId", content_tools.ShowSnip)
err := endless.ListenAndServe(conf.Network.Listen, app)
return err
}

I just think you need let the static router have a higher priority than dynamic ones when path is /, it might be simple to implement.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ccaza picture ccaza  路  3Comments

rawoke083 picture rawoke083  路  3Comments

kekemuyu picture kekemuyu  路  3Comments

CodingPapi picture CodingPapi  路  3Comments

frederikhors picture frederikhors  路  3Comments