Fiber: 馃 Is possible to Add or Remove an route on-the-fly?

Created on 19 Aug 2020  路  9Comments  路  Source: gofiber/fiber

Question description

I'm trying to create a dynamic router where user pass the httpMethod, router and handler ( prevealy defined ). So user will make a request

POST /route
{
"method": "POST",
"handler": "Ping",
"path": "/ping"
}

and a new /ping route will be added.

if user wants to change the route he do:

PUT /route
{
"method": "GET",
"handler": "Ping",
"path": "/ping"
}

or delete the route:

DELETE /route
{
"method": "POST",
"handler": "Ping",
"path": "/ping"
}

Code snippet
I've tried the following:

package main

import "github.com/gofiber/fiber"

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

    app.Get("/add", func(c *fiber.Ctx) {
        app.Get("/ping", Ping)
        m := make(map[string]string)
        m["message"] = "Ping Added!"
        c.JSON(m)
    })

    app.Listen("8080")
}

// Ping return a Pong message
func Ping(c *fiber.Ctx) {
    m := make(map[string]string)
    m["message"] = "Pong!"
    c.JSON(m)
}
馃 Question

Most helpful comment

It is not possible to overwrite the handler, like I mentioned in https://github.com/gofiber/fiber/issues/600#issuecomment-657924677:

I don't think a web framework should solve dynamic problems like this.

I think you should re-think your application logic, when I look at your example the same can be achieved doing the following ( proof of concept )

package main

import "github.com/gofiber/fiber"

var m = make(map[string]fiber.Handler)

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

    app.Post("/add", func(c *fiber.Ctx) {
        path := c.FormValue("path")
        message := c.FormValue("message")
        m[path] = func(c *fiber.Ctx) {
            c.JSON(fiber.Map{"Message": message})
        }
        c.JSON(m)
    })

    app.Get("*", func(c *fiber.Ctx) {
        h, exist := m[c.Path()]
        if !exist {
            c.SendStatus(fiber.StatusNotFound)
        } else {
            h(c) // execute handler
        }
    })

    app.Listen(":8080")
}

Since fiber has a complex router, it would be slower to remove/add routes on runtime.

All 9 comments

Thanks for opening your first issue here! 馃帀 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

Hey @mirusky I think your question is kind of duplicated with #600 馃槂

Oh thanks @kiyonlin I didn't find it before. I saw tried to implement but did not see usability in the real world ...

Instead of removing it is possible to overwrite the handler? Like Iris

P.S.: I put the same question in #600

Have you tested Iris's solution? I noticed it uses app.AddRouteUnsafe(). Will this UNSAFE manipulation crash the app?

It is not possible to overwrite the handler, like I mentioned in https://github.com/gofiber/fiber/issues/600#issuecomment-657924677:

I don't think a web framework should solve dynamic problems like this.

I think you should re-think your application logic, when I look at your example the same can be achieved doing the following ( proof of concept )

package main

import "github.com/gofiber/fiber"

var m = make(map[string]fiber.Handler)

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

    app.Post("/add", func(c *fiber.Ctx) {
        path := c.FormValue("path")
        message := c.FormValue("message")
        m[path] = func(c *fiber.Ctx) {
            c.JSON(fiber.Map{"Message": message})
        }
        c.JSON(m)
    })

    app.Get("*", func(c *fiber.Ctx) {
        h, exist := m[c.Path()]
        if !exist {
            c.SendStatus(fiber.StatusNotFound)
        } else {
            h(c) // execute handler
        }
    })

    app.Listen(":8080")
}

Since fiber has a complex router, it would be slower to remove/add routes on runtime.

@kiyonlin I'm currently testing, everything is going well ... But it's a new framework for me, so I spent time studying more than programming

@Fenny this solution looks good, I will do some tests maybe memory issues but expected ...

https://medium.com/@deckarep/the-new-kid-in-town-gos-sync-map-de24a6bf7c2c

You can use sync.Map or sync.Mutex to make it thread safe.

since the solution fits for you(@mirusky), I would close the issue

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GrigoriyMikhalkin picture GrigoriyMikhalkin  路  4Comments

mhf-ir picture mhf-ir  路  3Comments

ahan picture ahan  路  3Comments

renatojf picture renatojf  路  3Comments

Ivan-Feofanov picture Ivan-Feofanov  路  3Comments