Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3a77375

Browse files
authored
feat(coderd/httpapi): add QueryParamParser.JSONStringMap (#16578)
This PR provides a convenience function for parsing a`map[string]string` from a query parameter.Context:#16558 (comment)
1 parenta17cf03 commit3a77375

File tree

4 files changed

+84
-24
lines changed

4 files changed

+84
-24
lines changed

‎coderd/httpapi/queryparams.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package httpapi
22

33
import (
44
"database/sql"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"net/url"
@@ -257,6 +258,23 @@ func (p *QueryParamParser) Strings(vals url.Values, def []string, queryParam str
257258
})
258259
}
259260

261+
func (p*QueryParamParser)JSONStringMap(vals url.Values,defmap[string]string,queryParamstring)map[string]string {
262+
v,err:=parseQueryParam(p,vals,func(vstring) (map[string]string,error) {
263+
varmmap[string]string
264+
iferr:=json.NewDecoder(strings.NewReader(v)).Decode(&m);err!=nil {
265+
returnnil,err
266+
}
267+
returnm,nil
268+
},def,queryParam)
269+
iferr!=nil {
270+
p.Errors=append(p.Errors, codersdk.ValidationError{
271+
Field:queryParam,
272+
Detail:fmt.Sprintf("Query param %q must be a valid JSON object: %s",queryParam,err.Error()),
273+
})
274+
}
275+
returnv
276+
}
277+
260278
// ValidEnum represents an enum that can be parsed and validated.
261279
typeValidEnuminterface {
262280
// Add more types as needed (avoid importing large dependency trees).

‎coderd/httpapi/queryparams_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,70 @@ func TestParseQueryParams(t *testing.T) {
473473
testQueryParams(t,expParams,parser,parser.UUIDs)
474474
})
475475

476+
t.Run("JSONStringMap",func(t*testing.T) {
477+
t.Parallel()
478+
479+
expParams:= []queryParamTestCase[map[string]string]{
480+
{
481+
QueryParam:"valid_map",
482+
Value:`{"key1": "value1", "key2": "value2"}`,
483+
Expected:map[string]string{
484+
"key1":"value1",
485+
"key2":"value2",
486+
},
487+
},
488+
{
489+
QueryParam:"empty",
490+
Value:"{}",
491+
Default:map[string]string{},
492+
Expected:map[string]string{},
493+
},
494+
{
495+
QueryParam:"no_value",
496+
NoSet:true,
497+
Default:map[string]string{},
498+
Expected:map[string]string{},
499+
},
500+
{
501+
QueryParam:"default",
502+
NoSet:true,
503+
Default:map[string]string{"key":"value"},
504+
Expected:map[string]string{"key":"value"},
505+
},
506+
{
507+
QueryParam:"null",
508+
Value:"null",
509+
Expected:map[string]string(nil),
510+
},
511+
{
512+
QueryParam:"undefined",
513+
Value:"undefined",
514+
Expected:map[string]string(nil),
515+
},
516+
{
517+
QueryParam:"invalid_map",
518+
Value:`{"key1": "value1", "key2": "value2"`,// missing closing brace
519+
Expected:map[string]string(nil),
520+
Default:map[string]string{},
521+
ExpectedErrorContains:`Query param "invalid_map" must be a valid JSON object: unexpected EOF`,
522+
},
523+
{
524+
QueryParam:"incorrect_type",
525+
Value:`{"key1": 1, "key2": true}`,
526+
Expected:map[string]string(nil),
527+
ExpectedErrorContains:`Query param "incorrect_type" must be a valid JSON object: json: cannot unmarshal number into Go value of type string`,
528+
},
529+
{
530+
QueryParam:"multiple_keys",
531+
Values: []string{`{"key1": "value1"}`,`{"key2": "value2"}`},
532+
Expected:map[string]string(nil),
533+
ExpectedErrorContains:`Query param "multiple_keys" provided more than once, found 2 times.`,
534+
},
535+
}
536+
parser:=httpapi.NewQueryParamParser()
537+
testQueryParams(t,expParams,parser,parser.JSONStringMap)
538+
})
539+
476540
t.Run("Required",func(t*testing.T) {
477541
t.Parallel()
478542

‎coderd/provisionerdaemons.go

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
4444
p:=httpapi.NewQueryParamParser()
4545
limit:=p.PositiveInt32(qp,50,"limit")
4646
ids:=p.UUIDs(qp,nil,"ids")
47-
tagsRaw:=p.String(qp,"","tags")
47+
tags:=p.JSONStringMap(qp,database.StringMap{},"tags")
4848
p.ErrorExcessParams(qp)
4949
iflen(p.Errors)>0 {
5050
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
@@ -54,17 +54,6 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
5454
return
5555
}
5656

57-
tags:= database.StringMap{}
58-
iftagsRaw!="" {
59-
iferr:=tags.Scan([]byte(tagsRaw));err!=nil {
60-
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
61-
Message:"Invalid tags query parameter",
62-
Detail:err.Error(),
63-
})
64-
return
65-
}
66-
}
67-
6857
daemons,err:=api.Database.GetProvisionerDaemonsWithStatusByOrganization(
6958
ctx,
7059
database.GetProvisionerDaemonsWithStatusByOrganizationParams{

‎coderd/provisionerjobs.go

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func (api *API) handleAuthAndFetchProvisionerJobs(rw http.ResponseWriter, r *htt
108108
ifids==nil {
109109
ids=p.UUIDs(qp,nil,"ids")
110110
}
111-
tagsRaw:=p.String(qp,"","tags")
111+
tags:=p.JSONStringMap(qp,database.StringMap{},"tags")
112112
p.ErrorExcessParams(qp)
113113
iflen(p.Errors)>0 {
114114
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
@@ -118,17 +118,6 @@ func (api *API) handleAuthAndFetchProvisionerJobs(rw http.ResponseWriter, r *htt
118118
returnnil,false
119119
}
120120

121-
tags:= database.StringMap{}
122-
iftagsRaw!="" {
123-
iferr:=tags.Scan([]byte(tagsRaw));err!=nil {
124-
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
125-
Message:"Invalid tags query parameter",
126-
Detail:err.Error(),
127-
})
128-
returnnil,false
129-
}
130-
}
131-
132121
jobs,err:=api.Database.GetProvisionerJobsByOrganizationAndStatusWithQueuePositionAndProvisioner(ctx, database.GetProvisionerJobsByOrganizationAndStatusWithQueuePositionAndProvisionerParams{
133122
OrganizationID:org.ID,
134123
Status: slice.StringEnums[database.ProvisionerJobStatus](status),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp