gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.

Home Page:https://gin-gonic.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Binding for URL Params

miketonks opened this issue · comments

Is there a way to validate URL params?

e.g.

r.GET("/:foo/*bar", myFunc)

How can I validate foo and bar?

It would be nice if c.Bind() method could fall back (query params, form params, url params) - maybe introducing a 'url' tag:

type MyParams struct {
    Foo string `url:"foo"`
    Bar string `url:"bar`
    Download bool `form:"dl"`
}

I'm wondering this too ?

@miketonks that's an interesting feature, however the bind validator would need the fingerprint of the path, or just try to un marshall the c.Params(...) into an struct. need to think about it...

We can get these value using c.Param("foo") and c.Param("bar"), but I don't understand we need to validate what? The type of value which got by c.Param("foo"), right?

Will it be implemented? I'm interest it too

@javierprovecho do you happen to have any updates on this one?

@Szasza can you describe the issue requirement? thanks!

@thinkerou thank you for the ultra-quick response, it is much appreciated.

Use case: having an URL path like /books/:id, where ID is let's say an UUID. I would like to be able to use struct-based binding using tags to validate the URL path parameter id.

Problem: Currently the above is not possible in a straightforward way, because:

  • the bind and shouldBind functions only exist for query parameters, and request bodies, but not for URL path parameter
  • using the context there is no way to mutate the request query or body, which would enable to put the URL params into the request query/body and use the existing binding functions

One workaround I can think of from the top of my head is creating a new http.Request, copying the URL path parameter names and values into the new request's query parameters, and running bindWith using that, but it is extra code in each handler which could be simplified.

I hope the above helps.

wip demo: #1612

or just try to un marshall the c.Params(...) into an struct

Not un marshall it into struct, but traverse it and mapForm its element.

@thinkerou thank you for the quick WIP demo, it works perfectly fine with valid values.

I am unsure if the error handling is considered as finalised in the changeset, but if I set uuid as the binding's value, and send an invalid uuid as the path parameter value, it yields an unhandled panic.

Thank you again.

@Szasza you are welcome!
uuid likes xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, and uri is /rest/n/:uuid, now visit /rest/n/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx will trigger binding, but how should check it? because input uuid is a string. thanks!

@thinkerou I think there is a misunderstanding here, please allow me to clarify it.

When I bind let's say the query parameters of a request, there are two tags that I use for the request struct's fields:

  • form:"id" - it binds the id query param to the struct field
  • binding:"uuid" - this is a pass-through to validator.v8, the value is validated against the uuid validation rule.

Is it possible to have the same pass-through for the binding tag in case of an uri:"id" binding as well and return a proper validation message instead of a panic? This would be useful since the router does not support regexp-based URI parameter matching.

I hope the above helps, please let me know if further clarification is needed, and thank you again.

@Szasza thanks!
Now #1612 have supported bind uri params, please help me review, thanks everybody!

@thinkerou my pleasure, thank you for the quick implementation, it is much appreciated 😄

Why not support the type of params specified in URL? like

router.GET("/post/<int:post_id>", Handler)

@axiaoxin IMO, that is too complex.

Thanks for adding this feature, it looks great.

If anyone is interested we solved the problem another way, which can be used on top of / alongside gin validation.

See: https://github.com/miketonks/swag-validator

#1612 merged!

Thanks! This is great. Why not add BindUri and MustBindUri too?

When there will be a new release? This feature is useful and I don't want to fork to the latest commit.

Thanks! This is great. Why not add BindUri and MustBindUri too?

@dszakallas I will add it. thanks!

When there will be a new release? This feature is useful and I don't want to fork to the latest commit.

@halink0803 1.4 version on February 28, 2019, and publish release need to @javierprovecho help.

@dszakallas #1694 add BindUri.

@thinkerou Thank you for quick response, I think we will fork latest commit by then.

please there problem deal? I too like use it

@cappuccino5 what's mean?

please how bind uri to map

Btw, should Uri be all uppercase?

If I want a model to be bound to both form and uri parameters, do I need to call several Bind methods? Calling ShouldBind() doesn't seem to bind uri parameters.

commented

@asbjornu Maybe you need to try ShouldBindWith()

this doc has some more info !