0

I am working on a project using the fiber/v2 router, for a request mocking service. Now parameters passed via request body and query parameters are not an issue and handled easily. But here lies the problem with path parameters: Let's say we have a basic endpoint like http://host.org:port/, I will denote this by "be". Now for a URL like

be/invoke/param1/param2

where the user sending request has the option to send just param1 or param1 and param2 both, parsing looks like a difficult task. There can be many types of cases and it is definitely hard to generalize in my opinion. It would be great if people could help with this case and then we maybe can generalize the problem.

Of course we need not look on cases like:

be/invoke/param1/details/param2

This becomes much harder :P

P.S. We are strictly trying to solve this problem in fiber because porting the entire thing to gin is not feasible, thanks.

I referred the Gin framework because they implement both Query and Path parameter parsing. But I was not very clear on how they were doing it and didn't find example for more dynamic use cases.

Edit 1: Thanks for the comment Cerise, the question is directed more towards detection of a passed parameter (The phrasing makes it look more generic :P ). Is there a way to detect a passed unnamed parameter? Or do I need to take the pattern of request while adding the service in my repository of service mocks?

Edit 2: I think an example will make this more clear:

I can get all the queyParams like

qParams := c.Queries()

Where c is of type *fiber.Ctx and Queries() returns a map of query and query value pairs.

I want to do something similar for path parameters such that:

pathParams := Parameters(c)

where Parameters() will return me all the path params(since c.Params() by definition requires the key I need to pick the value of)

7
  • 1
    Does Fiber's path parameter feature solve your problem? If not, then edit the question to explain what's missing. Commented Jul 4 at 15:13
  • 1
    Why you are not using docs.gofiber.io/api/ctx#allparams
    – Christoph
    Commented Jul 4 at 19:41
  • As I said before, it is not tough if the pattern is known, can this be achieved for an unknown pattern, if you don't know what is the key name. again I specify the request only as "be/invoke/" and any params thereafter need to be parsed without the knowledge of the key. Commented Jul 5 at 7:04
  • @Christoph I see how the wild card case handles this but it doesn't split the parameters. Commented Jul 5 at 7:11
  • split it by your own ;)
    – Christoph
    Commented Jul 5 at 8:38

1 Answer 1

0

Maybe this helps, i would do it this way. Since you shold know which params you expect you could determine if the next param a value that you need or not.

http://127.0.0.1:3000/be/invoke/param1/details/param2/param3/param3details?foo=x&bar=test

package main

import (
    "fmt"
    "strings"

    "github.com/gofiber/fiber/v2"
)

type ParamIndex int
type PathParams map[ParamIndex]string

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

    app.Use("/invoke/*", func(c *fiber.Ctx) error {
        path := strings.TrimPrefix(c.Path(), "/invoke/")
        parts := strings.Split(path, "/")
        pathParams := make(PathParams)

        for i, part := range parts {
            pathParams[ParamIndex(i)] = part
        }

        c.Locals("pathParams", pathParams)
        c.Locals("queryParams", c.Queries())
        return c.Next()
    })

    app.Get("/invoke/*", func(c *fiber.Ctx) error {
        pathParams := c.Locals("pathParams").(PathParams)
        queryParams := c.Locals("queryParams").(map[string]string)

        fmt.Println(pathParams)
        fmt.Println(queryParams)
        return nil
    })

    app.Listen(":3000")
}

output:

map[0:param1 1:details 2:param2 3:param3 4:param3details]
map[bar:test foo:x]

Not the answer you're looking for? Browse other questions tagged or ask your own question.