querystring directive
davidalpert opened this issue · 5 comments
would a querystring directive which extracts values from the request.URL.Query() values be of use?
I would be happy to draft a pull request...
something like:
type Pagination struct {
Page int `in:"form=page;query=page"`
// Decode from multiple keys in the same source, the former with higher priority
PerPage int `in:"form=per_page,page_size;query=page_size"`
}
I took a look at implementing one as a custom directive in my own project but it seems like it would share so much logic with the form
directive extractor that I thought it may be simpler to offer it in the box alongside the form
extractor.
A common use case might be an API which allows a short query value passed in a URL param in a GET request but a longer or more complex query value to be passed in the form body of a POST
in fact, after a bit of experimentation all it needs is:
// queryValueExtractor implements the "query" executor who extracts values from
// the querystring of an HTTP request.
func queryValueExtractor(ctx *DirectiveContext) error {
return extractFromKVS(ctx, ctx.Request.URL.Query(), false)
}
and
RegisterDirectiveExecutor("query", DirectiveExecutorFunc(queryValueExtractor), nil)
and then this test passes:
type SearchQuery struct {
Query string `in:"query=q;required"`
PageNumber int `in:"query=p"`
PageSize int `in:"query=page_size"`
}
func TestEngine(t *testing.T) {
Convey("Get with QueryString params", t, func() {
r, _ := http.NewRequest("GET", "/?q=doggy&p=2&page_size=5", nil)
expected := &SearchQuery{
Query: "doggy",
PageNumber: 2,
PageSize: 5,
}
core, err := New(SearchQuery{})
So(err, ShouldBeNil)
got, err := core.Decode(r)
So(err, ShouldBeNil)
So(got, ShouldResemble, expected)
})
}
I cannot do this from outside the library as extractFromKVS
is unexported.
I would be happy to provide these changes as a pull request, if this syntax is acceptable for inclusion into the core library.
query
directive is offered as PR #6
Sorry for the late response and thanks for the PR. However, does the query
directive work just like form
? The form
directive had already implemented the way of extracting parameters from the querystring. In my opinion, they are the same thing.
For example,
type SearchQuery struct {
Query string `in:"query=q;required"`
PageNumber int `in:"query=p"`
PageSize int `in:"query=page_size"`
}
you could just replace query
with form
. It should work.
Or did I miss something?
this is interesting.
it seems that you are correct; when I updated the tags in that unit test to use the form
directive in the QueryString test it passed.
I will go back to the project that I attempted to use this library in and try it again.
If I can make it work there as well I propose to:
- update the PR to use the
form
tag and - update the documentation to demonstrate using the
form
tag to parse querysting values.
#6 was merged; the PR contains some discussion about the nuance between the query
directive (which pulls only from the request.URL.Query()
collection) and the form
directive (which merges values, first from request.URL.Query()
then from request.Form
where form values will override query values when the keys match).