github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/access/rest/request/request.go (about) 1 package request 2 3 import ( 4 "net/http" 5 "strings" 6 7 "github.com/gorilla/mux" 8 9 "github.com/onflow/flow-go/engine/access/rest/middleware" 10 "github.com/onflow/flow-go/model/flow" 11 ) 12 13 // Request a convenience wrapper around the http request to make it easy to read request query params 14 type Request struct { 15 *http.Request 16 ExpandFields map[string]bool 17 selectFields []string 18 Chain flow.Chain 19 } 20 21 func (rd *Request) GetScriptRequest() (GetScript, error) { 22 var req GetScript 23 err := req.Build(rd) 24 return req, err 25 } 26 27 func (rd *Request) GetBlockRequest() (GetBlock, error) { 28 var req GetBlock 29 err := req.Build(rd) 30 return req, err 31 } 32 33 func (rd *Request) GetBlockByIDsRequest() (GetBlockByIDs, error) { 34 var req GetBlockByIDs 35 err := req.Build(rd) 36 return req, err 37 } 38 39 func (rd *Request) GetBlockPayloadRequest() (GetBlockPayload, error) { 40 var req GetBlockPayload 41 err := req.Build(rd) 42 return req, err 43 } 44 45 func (rd *Request) GetCollectionRequest() (GetCollection, error) { 46 var req GetCollection 47 err := req.Build(rd) 48 return req, err 49 } 50 51 func (rd *Request) GetAccountRequest() (GetAccount, error) { 52 var req GetAccount 53 err := req.Build(rd) 54 return req, err 55 } 56 57 func (rd *Request) GetAccountKeyRequest() (GetAccountKey, error) { 58 var req GetAccountKey 59 err := req.Build(rd) 60 return req, err 61 } 62 63 func (rd *Request) GetExecutionResultByBlockIDsRequest() (GetExecutionResultByBlockIDs, error) { 64 var req GetExecutionResultByBlockIDs 65 err := req.Build(rd) 66 return req, err 67 } 68 69 func (rd *Request) GetExecutionResultRequest() (GetExecutionResult, error) { 70 var req GetExecutionResult 71 err := req.Build(rd) 72 return req, err 73 } 74 75 func (rd *Request) GetTransactionRequest() (GetTransaction, error) { 76 var req GetTransaction 77 err := req.Build(rd) 78 return req, err 79 } 80 81 func (rd *Request) GetTransactionResultRequest() (GetTransactionResult, error) { 82 var req GetTransactionResult 83 err := req.Build(rd) 84 return req, err 85 } 86 87 func (rd *Request) GetEventsRequest() (GetEvents, error) { 88 var req GetEvents 89 err := req.Build(rd) 90 return req, err 91 } 92 93 func (rd *Request) CreateTransactionRequest() (CreateTransaction, error) { 94 var req CreateTransaction 95 err := req.Build(rd) 96 return req, err 97 } 98 99 func (rd *Request) SubscribeEventsRequest() (SubscribeEvents, error) { 100 var req SubscribeEvents 101 err := req.Build(rd) 102 return req, err 103 } 104 105 func (rd *Request) Expands(field string) bool { 106 return rd.ExpandFields[field] 107 } 108 109 func (rd *Request) Selects() []string { 110 return rd.selectFields 111 } 112 113 func (rd *Request) GetVar(name string) string { 114 vars := mux.Vars(rd.Request) 115 return vars[name] 116 } 117 118 func (rd *Request) GetVars(name string) []string { 119 vars := mux.Vars(rd.Request) 120 return toStringArray(vars[name]) 121 } 122 123 func (rd *Request) GetQueryParam(name string) string { 124 return rd.Request.URL.Query().Get(name) 125 } 126 127 func (rd *Request) GetQueryParams(name string) []string { 128 param := rd.Request.URL.Query().Get(name) 129 return toStringArray(param) 130 } 131 132 // Decorate takes http request and applies functions to produce our custom 133 // request object decorated with values we need 134 func Decorate(r *http.Request, chain flow.Chain) *Request { 135 decoratedReq := &Request{ 136 Request: r, 137 Chain: chain, 138 } 139 140 if expandFields, found := middleware.GetFieldsToExpand(r); found { 141 decoratedReq.ExpandFields = sliceToMap(expandFields) 142 } 143 144 if selectFields, found := middleware.GetFieldsToSelect(r); found { 145 decoratedReq.selectFields = selectFields 146 } 147 148 return decoratedReq 149 } 150 151 func sliceToMap(values []string) map[string]bool { 152 valueMap := make(map[string]bool, len(values)) 153 for _, v := range values { 154 valueMap[v] = true 155 } 156 return valueMap 157 } 158 159 func toStringArray(in string) []string { 160 // currently, the swagger generated Go REST client is incorrectly doing a `fmt.Sprintf("%v", id)` for the id slice 161 // resulting in the client sending the ids in the format [id1 id2 id3...]. This is a temporary workaround to 162 // accommodate the client for now by doing a strings.Fields if commas are not present. 163 // Issue to to fix the client: https://github.com/onflow/flow/issues/698 164 in = strings.TrimSuffix(in, "]") 165 in = strings.TrimPrefix(in, "[") 166 var out []string 167 168 if len(in) == 0 { 169 return []string{} 170 } 171 172 if strings.Contains(in, ",") { 173 out = strings.Split(in, ",") 174 } else { 175 out = strings.Fields(in) 176 } 177 178 return out 179 }