-
Notifications
You must be signed in to change notification settings - Fork 442
feat(package): /p/demo/mux support query strings
#2594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
thinhnx-var
wants to merge
8
commits into
gnolang:master
from
VAR-META-Tech:dev-thinhnx/feat_mux_support_query_strings
Closed
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
af7d642
/p/demo/mux/ support query strings
thinhnx-var d622e8a
update testcases and naming
thinhnx-var f85fdc0
make fmt
thinhnx-var fca7043
support query strings, add testcases
thinhnx-var 29d1b9f
refact coding
thinhnx-var 1b42c68
refact var name
thinhnx-var 48a0eaa
just check pattern prefix
thinhnx-var 04c21a3
Merge branch 'master' into dev-thinhnx/feat_mux_support_query_strings
thinhnx-var File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| package mux | ||
|
|
||
| import "strings" | ||
|
|
||
| type QueryValues map[string][]string | ||
|
|
||
| /* | ||
| Query() returns a full map of key-listValue from request | ||
| to get a list of params by key, use: req.Query()["key"] | ||
| to get single param by key, use: req.Query().Get("key") | ||
| to get request path use GetPath() | ||
| */ | ||
|
|
||
| func (r *Request) QueryFull() (QueryValues, string) { | ||
| urlQueries := QueryValues{} | ||
| pathQuery := "" | ||
| // checking if there is query in r.Path | ||
| if strings.Contains(r.Path, "?") { | ||
| // get baseUrl and queryString | ||
| rParts := strings.SplitN(r.Path, "?", 2) | ||
| if len(rParts) == 1 { | ||
| // if this is not a `query string` query, then returns full path as queryPath | ||
| return urlQueries, rParts[0] | ||
| } | ||
| baseUrl := rParts[0] | ||
| queryString := rParts[1] | ||
|
|
||
| // find the target path | ||
| baseUrlParts := strings.Split(baseUrl, "/") | ||
| rTargetPath := baseUrlParts[len(baseUrlParts)-1] | ||
| pathQuery = rTargetPath | ||
|
|
||
| // process the queryString | ||
| // find the first param index | ||
| if strings.Contains(queryString, "=") { | ||
| for _, keyValue := range strings.Split(queryString, "&") { | ||
| parts := strings.SplitN(keyValue, "=", 2) | ||
| if len(parts) != 2 { | ||
| return urlQueries, rParts[0] | ||
| } | ||
| key, value := parts[0], parts[1] | ||
| urlQueries[key] = append(urlQueries[key], value) | ||
| } | ||
| } | ||
| } | ||
| return urlQueries, pathQuery | ||
| } | ||
|
|
||
| // get the query by key | ||
| // if there is more than one query, returns the very first param | ||
| func (qs QueryValues) Get(key string) string { | ||
| listMatching, ok := qs[key] | ||
| if ok { | ||
| return listMatching[0] | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| func (r *Request) Query() QueryValues { | ||
| uQuery, _ := r.QueryFull() | ||
| return uQuery | ||
| } | ||
|
|
||
| func (r *Request) GetQueryPath() string { | ||
| _, pQuery := r.QueryFull() | ||
| return pQuery | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| package mux | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestQuery_Get(t *testing.T) { | ||
| cases := []struct { | ||
| name string | ||
| reqPath string | ||
| key string | ||
| expectedOutput string | ||
| }{ | ||
| // get by key | ||
| {"Get_query_key", "api/v1/?name=testname&age=12", "name", "testname"}, | ||
| {"Get_query_repeat", "api/v1/user?name=name1&name=name2&name=name3", "name", "name1"}, | ||
| {"Get_query_with_pre_path", "api/v1/unprocesspath?user=thinhnx&age=12", "user", "thinhnx"}, | ||
| {"Get_query_empty", "api/v1/?name=testname&age=12", "loc", ""}, | ||
| {"Get_query_with_slash", "api/v1/?name=testname&endpoint=testdomain.com/v1/with/slash/", "endpoint", "testdomain.com/v1/with/slash/"}, | ||
| {"Get_query_with_extra_slash", "api/v1/unprocesspath?user=thinhnx&age=12&addr=12/34/NewYork//", "addr", "12/34/NewYork//"}, | ||
| } | ||
|
|
||
| for _, tt := range cases { | ||
| name := fmt.Sprintf("%s-%s", tt.name, tt.reqPath) | ||
| t.Run(name, func(t *testing.T) { | ||
| req := &Request{ | ||
| HandlerPath: "", | ||
| Path: tt.reqPath, | ||
| } | ||
| output := req.Query().Get(tt.key) | ||
| if output != tt.expectedOutput { | ||
| t.Errorf("Expected %q, but got %q", tt.expectedOutput, output) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| func TestQuery_QueryList(t *testing.T) { | ||
| cases := []struct { | ||
| name string | ||
| reqPath string | ||
| key string | ||
| expectedOutput []string | ||
| }{ | ||
| // get all queries | ||
| {"Get_name_list", "api/v1/user?name=name0&age=12&name=name1&age=30", "name", []string{"name0", "name1"}}, | ||
| {"Get_age_list", "api/v1/user?name=name0&age=12&name=name1&age=30", "age", []string{"12", "30"}}, | ||
| {"Get_loc_list", "api/v1/user?name=name0&age=12&name=name1&age=30&loc=HN", "loc", []string{"HN"}}, | ||
| {"Get_empty_list", "api/v1/user?name=name0&age=12&name=name1&age=30&loc=HN", "addr", []string{}}, | ||
| } | ||
|
|
||
| for _, tt := range cases { | ||
| name := fmt.Sprintf("%s-%s", tt.name, tt.reqPath) | ||
| t.Run(name, func(t *testing.T) { | ||
| req := &Request{ | ||
| HandlerPath: "", | ||
| Path: tt.reqPath, | ||
| } | ||
| // simple check for length of expected and output list | ||
| output := req.Query()[tt.key] | ||
| if len(output) != len(tt.expectedOutput) { | ||
| t.Errorf("Expected %q, but got %q", tt.expectedOutput, output) | ||
| } | ||
| // check the corresponding elements | ||
| listOutput := req.Query()[tt.key] | ||
| for i, ttExpt := range tt.expectedOutput { | ||
| if ttExpt != listOutput[i] { | ||
| t.Errorf("Expected %q, but got %q", ttExpt, listOutput[i]) | ||
| } | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| func TestQuery_GetPath(t *testing.T) { | ||
| cases := []struct { | ||
| name string | ||
| reqPath string | ||
| expectedOutput string | ||
| }{ | ||
| // get all queries | ||
| {"Get_user", "api/v1/user?name=name1&name=name2&name=name3", "user"}, | ||
| {"Get_empty_path", "api/v1/?user=thinhnx&age=12&addr=12/34/NewYork", ""}, | ||
| } | ||
|
|
||
| for _, tt := range cases { | ||
| name := fmt.Sprintf("%s-%s", tt.name, tt.reqPath) | ||
| t.Run(name, func(t *testing.T) { | ||
| req := &Request{ | ||
| HandlerPath: "", | ||
| Path: tt.reqPath, | ||
| } | ||
| // check the corresponding elements | ||
| outputGP := req.GetQueryPath() | ||
| if tt.expectedOutput != outputGP { | ||
| t.Errorf("Expected %q, but got %q", tt.expectedOutput, outputGP) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.