How do I use nested structs from query?
vamshiaruru32 opened this issue ยท 5 comments
I have a type like this:
type ListPagesInput struct {
CustomerID string `in:"path=customerID" validate:"required"`
PaginationParams PaginationParams `in:"query=pagination{}" validate:"required"`
}
type PaginationParams struct {
Cursor string `in:"query=cursor"`
SortOrder string `in:"query=sortOrder"`
Limit int32 `in:"query=limit"`
}
I am unable to figure out how to send it as part of query string. I tried making a request like this: http://localhost:8701/v1/customer/shop/pages?pagination={limit:1}, but the PaginationParams doesn't seem to be getting values from the query string (limit is always zero).
Any help is appreciated, thanks.
httpin doesn't support nested fields. The input struct should be flat, so the embedding can work, like this:
type ListPagesInput struct {
PaginationParams
CustomerID string `in:"path=customerID" validate:"required"`
}
type PaginationParams struct {
Cursor string `in:"query=cursor"`
SortOrder string `in:"query=sortOrder"`
Limit int32 `in:"query=limit"`
}
For the query, it can be:
/v1/customers/:customerID/shop/pages?limit=1&cursor=xxx
Thank you @ggicci , that is how I ended up doing it. Are there any plans to support nested params?
And thanks for the great library, it has saved me a lot of effort :)
Sorry, I won't accept the idea of supporting nested parameters. It just make things complicated. I will document this limitation in an obvious location.
Thank you for your appreciation, I am also very happy that this package helped you.
I reconsidered about the feature of supporting nested parameters today. It can be useful for cases like the following:
type Apperance struct {
Foreground string `in:"form=fg"`
Background string `in:"form=bg"`
Opacity int `in:"form=opacity"`
}
type RequestForm struct {
Light Appearance
Dark Appearance
}
In one request, we are going to submit a form that having multiple form data (i.e. Light
and Dark
) of a same data structure (i.e. Apperance
). And for the HTTP request form, it'd be better off distinguishing same name sub-fields under different fields by a "namespace". For example, for the fields of Light
, we can prefix with a "light"
. In the same way, for the fields of Dark
, we can prefix with a "dark"
. The form request now looks like:
POST /settings/appearances
light.fg=black&light.bg=white&light.opacity=10&dark.fg=white&dark.bg=black&dark.opacity=90
Currently, since the input struct needs to be flat, we can archive this by defining the Appearance
twice, like this:
type LightApperance struct {
Foreground string `in:"form=light.fg"`
Background string `in:"form=light.bg"`
Opacity int `in:"form=light.opacity"`
}
type DarkApperance struct {
Foreground string `in:"form=dark.fg"`
Background string `in:"form=dark.bg"`
Opacity int `in:"form=dark.opacity"`
}
type RequestForm struct {
LightApperance
DarkApperance
}
It looks simple, but to some extent not flexible. Here I propose to add a new directive called ns
(namespace), it can be applied to a field of a struct type to define the namespace of this field. The namespace will be visible to all its sub-fields. And how this namespace will be utilized is the business of the directives. Now, we can define the RequestForm
like this:
type RequestForm struct {
Light Appearance `in:"ns=light"`
Dark Appearnce `in:"ns=dark"`
}
And, for the form
directive, it should respect the namespace where the field resides.
I'll work on this ASAP. But it still can be subject to change.
Also updates #61
After consideration, the above idea I finally rejected. The reason is: never make the query and form data complicated, post JSON/XML body for complicated usecases instead.