diff --git a/codegen/method.go b/codegen/method.go index 0372405d3..b3c333397 100644 --- a/codegen/method.go +++ b/codegen/method.go @@ -238,7 +238,7 @@ func NewMethod( method.setValidStatusCodes() - if method.HTTPMethod == "GET" && method.RequestType != "" { + if method.RequestType != "" { if method.IsEndpoint { err := method.setParseQueryParamStatements(funcSpec, packageHelper) if err != nil { @@ -1132,7 +1132,8 @@ func (ms *MethodSpec) setWriteQueryParamStatements( ) error { var statements LineBuilder var hasQueryFields bool - var stack = []string{} + var stack []string + isVoidReturn := funcSpec.ResultSpec.ReturnType == nil visitor := func( goPrefix string, thriftPrefix string, field *compile.FieldSpec, @@ -1140,6 +1141,11 @@ func (ms *MethodSpec) setWriteQueryParamStatements( realType := compile.RootTypeSpec(field.Type) longFieldName := goPrefix + "." + PascalCase(field.Name) + httpRefAnnotation := field.Annotations[ms.annotations.HTTPRef] + if !strings.HasPrefix(httpRefAnnotation, "query") { + return false + } + if len(stack) > 0 { if !strings.HasPrefix(longFieldName, stack[len(stack)-1]) { stack = stack[:len(stack)-1] @@ -1152,13 +1158,17 @@ func (ms *MethodSpec) setWriteQueryParamStatements( if field.Required { statements.appendf("if r%s == nil {", longFieldName) - // TODO: generate correct number of nils... - statements.append("\treturn nil, nil, errors.New(") + // Generate correct number of nils... + if isVoidReturn { + statements.append("\treturn nil, errors.New(") + } else { + statements.append("\treturn nil, nil, errors.New(") + } statements.appendf("\t\t\"The field %s is required\",", longFieldName, ) statements.append("\t)") - statements.appendf("}") + statements.append("}") } else { stack = append(stack, longFieldName) @@ -1168,11 +1178,6 @@ func (ms *MethodSpec) setWriteQueryParamStatements( return false } - httpRefAnnotation := field.Annotations[ms.annotations.HTTPRef] - if httpRefAnnotation != "" && !strings.HasPrefix(httpRefAnnotation, "query") { - return false - } - longQueryName := ms.getLongQueryName(field, thriftPrefix) identifierName := CamelCase(longQueryName) + "Query" _, isList := realType.(*compile.ListSpec) @@ -1250,6 +1255,11 @@ func (ms *MethodSpec) setParseQueryParamStatements( longFieldName := goPrefix + "." + PascalCase(field.Name) longQueryName := ms.getLongQueryName(field, thriftPrefix) + httpRefAnnotation := field.Annotations[ms.annotations.HTTPRef] + if !strings.HasPrefix(httpRefAnnotation, "query") { + return false + } + if len(stack) > 0 { if !strings.HasPrefix(longFieldName, stack[len(stack)-1]) { stack = stack[:len(stack)-1] @@ -1325,11 +1335,6 @@ func (ms *MethodSpec) setParseQueryParamStatements( } identifierName := CamelCase(longQueryName) + "Query" - httpRefAnnotation := field.Annotations[ms.annotations.HTTPRef] - if httpRefAnnotation != "" && !strings.HasPrefix(httpRefAnnotation, "query") { - return false - } - okIdentifierName := CamelCase(longQueryName) + "Ok" if field.Required { statements.appendf("%s := req.CheckQueryValue(%q)", diff --git a/examples/example-gateway/build/clients/bar/bar.go b/examples/example-gateway/build/clients/bar/bar.go index d239976ce..fc0f7abf0 100644 --- a/examples/example-gateway/build/clients/bar/bar.go +++ b/examples/example-gateway/build/clients/bar/bar.go @@ -88,6 +88,11 @@ type Client interface { reqHeaders map[string]string, args *clientsBarBar.Bar_DeleteFoo_Args, ) (map[string]string, error) + DeleteWithQueryParams( + ctx context.Context, + reqHeaders map[string]string, + args *clientsBarBar.Bar_DeleteWithQueryParams_Args, + ) (map[string]string, error) Hello( ctx context.Context, reqHeaders map[string]string, @@ -246,6 +251,7 @@ func NewClient(deps *module.Dependencies) Client { "ArgWithQueryHeader": "Bar::argWithQueryHeader", "ArgWithQueryParams": "Bar::argWithQueryParams", "DeleteFoo": "Bar::deleteFoo", + "DeleteWithQueryParams": "Bar::deleteWithQueryParams", "Hello": "Bar::helloWorld", "ListAndEnum": "Bar::listAndEnum", "MissingArg": "Bar::missingArg", @@ -757,9 +763,6 @@ func (c *barClient) ArgWithParams( // Generate full URL. fullURL := c.httpClient.BaseURL + "/bar" + "/argWithParams" + "/" + string(r.UUID) + "/segment" + "/" + string(r.Params.UserUUID) - if r.Params != nil { - } - err := req.WriteJSON("GET", fullURL, headers, nil) if err != nil { return defaultRes, nil, err @@ -1103,6 +1106,79 @@ func (c *barClient) DeleteFoo( } } +// DeleteWithQueryParams calls "/bar/withQueryParams" endpoint. +func (c *barClient) DeleteWithQueryParams( + ctx context.Context, + headers map[string]string, + r *clientsBarBar.Bar_DeleteWithQueryParams_Args, +) (map[string]string, error) { + reqUUID := zanzibar.RequestUUIDFromCtx(ctx) + if reqUUID != "" { + if headers == nil { + headers = make(map[string]string) + } + headers[c.requestUUIDHeaderKey] = reqUUID + } + + req := zanzibar.NewClientHTTPRequest(ctx, c.clientID, "DeleteWithQueryParams", "Bar::deleteWithQueryParams", c.httpClient) + + // Generate full URL. + fullURL := c.httpClient.BaseURL + "/bar" + "/withQueryParams" + + queryValues := &url.Values{} + filterQuery := r.Filter + queryValues.Set("filter", filterQuery) + if r.Count != nil { + countQuery := strconv.Itoa(int(*r.Count)) + queryValues.Set("count", countQuery) + } + fullURL += "?" + queryValues.Encode() + + err := req.WriteJSON("DELETE", fullURL, headers, r) + if err != nil { + return nil, err + } + + var res *zanzibar.ClientHTTPResponse + if c.circuitBreakerDisabled { + res, err = req.Do() + } else { + err = hystrix.DoC(ctx, "bar", func(ctx context.Context) error { + res, err = req.Do() + return err + }, nil) + } + if err != nil { + return nil, err + } + + respHeaders := map[string]string{} + for k := range res.Header { + respHeaders[k] = res.Header.Get(k) + } + + res.CheckOKResponse([]int{200}) + + switch res.StatusCode { + case 200: + _, err = res.ReadAll() + if err != nil { + return respHeaders, err + } + return respHeaders, nil + default: + _, err = res.ReadAll() + if err != nil { + return respHeaders, err + } + } + + return respHeaders, &zanzibar.UnexpectedHTTPError{ + StatusCode: res.StatusCode, + RawBody: res.GetRawBody(), + } +} + // Hello calls "/bar/hello" endpoint. func (c *barClient) Hello( ctx context.Context, diff --git a/examples/example-gateway/build/clients/bar/mock-client/mock_client.go b/examples/example-gateway/build/clients/bar/mock-client/mock_client.go index dc5e3a987..16fe0acf4 100644 --- a/examples/example-gateway/build/clients/bar/mock-client/mock_client.go +++ b/examples/example-gateway/build/clients/bar/mock-client/mock_client.go @@ -178,6 +178,21 @@ func (mr *MockClientMockRecorder) DeleteFoo(arg0, arg1, arg2 interface{}) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteFoo", reflect.TypeOf((*MockClient)(nil).DeleteFoo), arg0, arg1, arg2) } +// DeleteWithQueryParams mocks base method +func (m *MockClient) DeleteWithQueryParams(arg0 context.Context, arg1 map[string]string, arg2 *bar.Bar_DeleteWithQueryParams_Args) (map[string]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteWithQueryParams", arg0, arg1, arg2) + ret0, _ := ret[0].(map[string]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteWithQueryParams indicates an expected call of DeleteWithQueryParams +func (mr *MockClientMockRecorder) DeleteWithQueryParams(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWithQueryParams", reflect.TypeOf((*MockClient)(nil).DeleteWithQueryParams), arg0, arg1, arg2) +} + // EchoBinary mocks base method func (m *MockClient) EchoBinary(arg0 context.Context, arg1 map[string]string, arg2 *bar.Echo_EchoBinary_Args) ([]byte, map[string]string, error) { m.ctrl.T.Helper() diff --git a/examples/example-gateway/build/gen-code/clients/bar/bar/bar_deletewithqueryparams.go b/examples/example-gateway/build/gen-code/clients/bar/bar/bar_deletewithqueryparams.go new file mode 100644 index 000000000..1a7c3ac6b --- /dev/null +++ b/examples/example-gateway/build/gen-code/clients/bar/bar/bar_deletewithqueryparams.go @@ -0,0 +1,438 @@ +// Code generated by thriftrw v1.19.0. DO NOT EDIT. +// @generated + +package bar + +import ( + errors "errors" + fmt "fmt" + multierr "go.uber.org/multierr" + wire "go.uber.org/thriftrw/wire" + zapcore "go.uber.org/zap/zapcore" + strings "strings" +) + +// Bar_DeleteWithQueryParams_Args represents the arguments for the Bar.deleteWithQueryParams function. +// +// The arguments for deleteWithQueryParams are sent and received over the wire as this struct. +type Bar_DeleteWithQueryParams_Args struct { + Request *BarRequest `json:"request,required"` + Filter string `json:"filter,required"` + Count *int32 `json:"count,omitempty"` +} + +// ToWire translates a Bar_DeleteWithQueryParams_Args struct into a Thrift-level intermediate +// representation. This intermediate representation may be serialized +// into bytes using a ThriftRW protocol implementation. +// +// An error is returned if the struct or any of its fields failed to +// validate. +// +// x, err := v.ToWire() +// if err != nil { +// return err +// } +// +// if err := binaryProtocol.Encode(x, writer); err != nil { +// return err +// } +func (v *Bar_DeleteWithQueryParams_Args) ToWire() (wire.Value, error) { + var ( + fields [3]wire.Field + i int = 0 + w wire.Value + err error + ) + + if v.Request == nil { + return w, errors.New("field Request of Bar_DeleteWithQueryParams_Args is required") + } + w, err = v.Request.ToWire() + if err != nil { + return w, err + } + fields[i] = wire.Field{ID: 1, Value: w} + i++ + + w, err = wire.NewValueString(v.Filter), error(nil) + if err != nil { + return w, err + } + fields[i] = wire.Field{ID: 2, Value: w} + i++ + if v.Count != nil { + w, err = wire.NewValueI32(*(v.Count)), error(nil) + if err != nil { + return w, err + } + fields[i] = wire.Field{ID: 3, Value: w} + i++ + } + + return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil +} + +// FromWire deserializes a Bar_DeleteWithQueryParams_Args struct from its Thrift-level +// representation. The Thrift-level representation may be obtained +// from a ThriftRW protocol implementation. +// +// An error is returned if we were unable to build a Bar_DeleteWithQueryParams_Args struct +// from the provided intermediate representation. +// +// x, err := binaryProtocol.Decode(reader, wire.TStruct) +// if err != nil { +// return nil, err +// } +// +// var v Bar_DeleteWithQueryParams_Args +// if err := v.FromWire(x); err != nil { +// return nil, err +// } +// return &v, nil +func (v *Bar_DeleteWithQueryParams_Args) FromWire(w wire.Value) error { + var err error + + requestIsSet := false + filterIsSet := false + + for _, field := range w.GetStruct().Fields { + switch field.ID { + case 1: + if field.Value.Type() == wire.TStruct { + v.Request, err = _BarRequest_Read(field.Value) + if err != nil { + return err + } + requestIsSet = true + } + case 2: + if field.Value.Type() == wire.TBinary { + v.Filter, err = field.Value.GetString(), error(nil) + if err != nil { + return err + } + filterIsSet = true + } + case 3: + if field.Value.Type() == wire.TI32 { + var x int32 + x, err = field.Value.GetI32(), error(nil) + v.Count = &x + if err != nil { + return err + } + + } + } + } + + if !requestIsSet { + return errors.New("field Request of Bar_DeleteWithQueryParams_Args is required") + } + + if !filterIsSet { + return errors.New("field Filter of Bar_DeleteWithQueryParams_Args is required") + } + + return nil +} + +// String returns a readable string representation of a Bar_DeleteWithQueryParams_Args +// struct. +func (v *Bar_DeleteWithQueryParams_Args) String() string { + if v == nil { + return "" + } + + var fields [3]string + i := 0 + fields[i] = fmt.Sprintf("Request: %v", v.Request) + i++ + fields[i] = fmt.Sprintf("Filter: %v", v.Filter) + i++ + if v.Count != nil { + fields[i] = fmt.Sprintf("Count: %v", *(v.Count)) + i++ + } + + return fmt.Sprintf("Bar_DeleteWithQueryParams_Args{%v}", strings.Join(fields[:i], ", ")) +} + +// Equals returns true if all the fields of this Bar_DeleteWithQueryParams_Args match the +// provided Bar_DeleteWithQueryParams_Args. +// +// This function performs a deep comparison. +func (v *Bar_DeleteWithQueryParams_Args) Equals(rhs *Bar_DeleteWithQueryParams_Args) bool { + if v == nil { + return rhs == nil + } else if rhs == nil { + return false + } + if !v.Request.Equals(rhs.Request) { + return false + } + if !(v.Filter == rhs.Filter) { + return false + } + if !_I32_EqualsPtr(v.Count, rhs.Count) { + return false + } + + return true +} + +// MarshalLogObject implements zapcore.ObjectMarshaler, enabling +// fast logging of Bar_DeleteWithQueryParams_Args. +func (v *Bar_DeleteWithQueryParams_Args) MarshalLogObject(enc zapcore.ObjectEncoder) (err error) { + if v == nil { + return nil + } + err = multierr.Append(err, enc.AddObject("request", v.Request)) + enc.AddString("filter", v.Filter) + if v.Count != nil { + enc.AddInt32("count", *v.Count) + } + return err +} + +// GetRequest returns the value of Request if it is set or its +// zero value if it is unset. +func (v *Bar_DeleteWithQueryParams_Args) GetRequest() (o *BarRequest) { + if v != nil { + o = v.Request + } + return +} + +// IsSetRequest returns true if Request is not nil. +func (v *Bar_DeleteWithQueryParams_Args) IsSetRequest() bool { + return v != nil && v.Request != nil +} + +// GetFilter returns the value of Filter if it is set or its +// zero value if it is unset. +func (v *Bar_DeleteWithQueryParams_Args) GetFilter() (o string) { + if v != nil { + o = v.Filter + } + return +} + +// GetCount returns the value of Count if it is set or its +// zero value if it is unset. +func (v *Bar_DeleteWithQueryParams_Args) GetCount() (o int32) { + if v != nil && v.Count != nil { + return *v.Count + } + + return +} + +// IsSetCount returns true if Count is not nil. +func (v *Bar_DeleteWithQueryParams_Args) IsSetCount() bool { + return v != nil && v.Count != nil +} + +// MethodName returns the name of the Thrift function as specified in +// the IDL, for which this struct represent the arguments. +// +// This will always be "deleteWithQueryParams" for this struct. +func (v *Bar_DeleteWithQueryParams_Args) MethodName() string { + return "deleteWithQueryParams" +} + +// EnvelopeType returns the kind of value inside this struct. +// +// This will always be Call for this struct. +func (v *Bar_DeleteWithQueryParams_Args) EnvelopeType() wire.EnvelopeType { + return wire.Call +} + +// Bar_DeleteWithQueryParams_Helper provides functions that aid in handling the +// parameters and return values of the Bar.deleteWithQueryParams +// function. +var Bar_DeleteWithQueryParams_Helper = struct { + // Args accepts the parameters of deleteWithQueryParams in-order and returns + // the arguments struct for the function. + Args func( + request *BarRequest, + filter string, + count *int32, + ) *Bar_DeleteWithQueryParams_Args + + // IsException returns true if the given error can be thrown + // by deleteWithQueryParams. + // + // An error can be thrown by deleteWithQueryParams only if the + // corresponding exception type was mentioned in the 'throws' + // section for it in the Thrift file. + IsException func(error) bool + + // WrapResponse returns the result struct for deleteWithQueryParams + // given the error returned by it. The provided error may + // be nil if deleteWithQueryParams did not fail. + // + // This allows mapping errors returned by deleteWithQueryParams into a + // serializable result struct. WrapResponse returns a + // non-nil error if the provided error cannot be thrown by + // deleteWithQueryParams + // + // err := deleteWithQueryParams(args) + // result, err := Bar_DeleteWithQueryParams_Helper.WrapResponse(err) + // if err != nil { + // return fmt.Errorf("unexpected error from deleteWithQueryParams: %v", err) + // } + // serialize(result) + WrapResponse func(error) (*Bar_DeleteWithQueryParams_Result, error) + + // UnwrapResponse takes the result struct for deleteWithQueryParams + // and returns the erorr returned by it (if any). + // + // The error is non-nil only if deleteWithQueryParams threw an + // exception. + // + // result := deserialize(bytes) + // err := Bar_DeleteWithQueryParams_Helper.UnwrapResponse(result) + UnwrapResponse func(*Bar_DeleteWithQueryParams_Result) error +}{} + +func init() { + Bar_DeleteWithQueryParams_Helper.Args = func( + request *BarRequest, + filter string, + count *int32, + ) *Bar_DeleteWithQueryParams_Args { + return &Bar_DeleteWithQueryParams_Args{ + Request: request, + Filter: filter, + Count: count, + } + } + + Bar_DeleteWithQueryParams_Helper.IsException = func(err error) bool { + switch err.(type) { + default: + return false + } + } + + Bar_DeleteWithQueryParams_Helper.WrapResponse = func(err error) (*Bar_DeleteWithQueryParams_Result, error) { + if err == nil { + return &Bar_DeleteWithQueryParams_Result{}, nil + } + + return nil, err + } + Bar_DeleteWithQueryParams_Helper.UnwrapResponse = func(result *Bar_DeleteWithQueryParams_Result) (err error) { + return + } + +} + +// Bar_DeleteWithQueryParams_Result represents the result of a Bar.deleteWithQueryParams function call. +// +// The result of a deleteWithQueryParams execution is sent and received over the wire as this struct. +type Bar_DeleteWithQueryParams_Result struct { +} + +// ToWire translates a Bar_DeleteWithQueryParams_Result struct into a Thrift-level intermediate +// representation. This intermediate representation may be serialized +// into bytes using a ThriftRW protocol implementation. +// +// An error is returned if the struct or any of its fields failed to +// validate. +// +// x, err := v.ToWire() +// if err != nil { +// return err +// } +// +// if err := binaryProtocol.Encode(x, writer); err != nil { +// return err +// } +func (v *Bar_DeleteWithQueryParams_Result) ToWire() (wire.Value, error) { + var ( + fields [0]wire.Field + i int = 0 + ) + + return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil +} + +// FromWire deserializes a Bar_DeleteWithQueryParams_Result struct from its Thrift-level +// representation. The Thrift-level representation may be obtained +// from a ThriftRW protocol implementation. +// +// An error is returned if we were unable to build a Bar_DeleteWithQueryParams_Result struct +// from the provided intermediate representation. +// +// x, err := binaryProtocol.Decode(reader, wire.TStruct) +// if err != nil { +// return nil, err +// } +// +// var v Bar_DeleteWithQueryParams_Result +// if err := v.FromWire(x); err != nil { +// return nil, err +// } +// return &v, nil +func (v *Bar_DeleteWithQueryParams_Result) FromWire(w wire.Value) error { + + for _, field := range w.GetStruct().Fields { + switch field.ID { + } + } + + return nil +} + +// String returns a readable string representation of a Bar_DeleteWithQueryParams_Result +// struct. +func (v *Bar_DeleteWithQueryParams_Result) String() string { + if v == nil { + return "" + } + + var fields [0]string + i := 0 + + return fmt.Sprintf("Bar_DeleteWithQueryParams_Result{%v}", strings.Join(fields[:i], ", ")) +} + +// Equals returns true if all the fields of this Bar_DeleteWithQueryParams_Result match the +// provided Bar_DeleteWithQueryParams_Result. +// +// This function performs a deep comparison. +func (v *Bar_DeleteWithQueryParams_Result) Equals(rhs *Bar_DeleteWithQueryParams_Result) bool { + if v == nil { + return rhs == nil + } else if rhs == nil { + return false + } + + return true +} + +// MarshalLogObject implements zapcore.ObjectMarshaler, enabling +// fast logging of Bar_DeleteWithQueryParams_Result. +func (v *Bar_DeleteWithQueryParams_Result) MarshalLogObject(enc zapcore.ObjectEncoder) (err error) { + if v == nil { + return nil + } + return err +} + +// MethodName returns the name of the Thrift function as specified in +// the IDL, for which this struct represent the result. +// +// This will always be "deleteWithQueryParams" for this struct. +func (v *Bar_DeleteWithQueryParams_Result) MethodName() string { + return "deleteWithQueryParams" +} + +// EnvelopeType returns the kind of value inside this struct. +// +// This will always be Reply for this struct. +func (v *Bar_DeleteWithQueryParams_Result) EnvelopeType() wire.EnvelopeType { + return wire.Reply +} diff --git a/examples/example-gateway/build/gen-code/clients/bar/bar/bar_deletewithqueryparams_easyjson.go b/examples/example-gateway/build/gen-code/clients/bar/bar/bar_deletewithqueryparams_easyjson.go new file mode 100644 index 000000000..4c85bcc54 --- /dev/null +++ b/examples/example-gateway/build/gen-code/clients/bar/bar/bar_deletewithqueryparams_easyjson.go @@ -0,0 +1,355 @@ +// Code generated by zanzibar +// @generated +// Checksum : w4tJ9F0//opMGSTzPlQTsw== +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package bar + +import ( + json "encoding/json" + fmt "fmt" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams(in *jlexer.Lexer, out *Bar_DeleteWithQueryParams_Result) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeString() + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams(out *jwriter.Writer, in Bar_DeleteWithQueryParams_Result) { + out.RawByte('{') + first := true + _ = first + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Bar_DeleteWithQueryParams_Result) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Bar_DeleteWithQueryParams_Result) MarshalEasyJSON(w *jwriter.Writer) { + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Bar_DeleteWithQueryParams_Result) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Bar_DeleteWithQueryParams_Result) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams(l, v) +} +func easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams1(in *jlexer.Lexer, out *Bar_DeleteWithQueryParams_Args) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + var RequestSet bool + var FilterSet bool + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeString() + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "request": + if in.IsNull() { + in.Skip() + out.Request = nil + } else { + if out.Request == nil { + out.Request = new(BarRequest) + } + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBar(in, out.Request) + } + RequestSet = true + case "filter": + out.Filter = string(in.String()) + FilterSet = true + case "count": + if in.IsNull() { + in.Skip() + out.Count = nil + } else { + if out.Count == nil { + out.Count = new(int32) + } + *out.Count = int32(in.Int32()) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } + if !RequestSet { + in.AddError(fmt.Errorf("key 'request' is required")) + } + if !FilterSet { + in.AddError(fmt.Errorf("key 'filter' is required")) + } +} +func easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams1(out *jwriter.Writer, in Bar_DeleteWithQueryParams_Args) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"request\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Request == nil { + out.RawString("null") + } else { + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBar(out, *in.Request) + } + } + { + const prefix string = ",\"filter\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Filter)) + } + if in.Count != nil { + const prefix string = ",\"count\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int32(int32(*in.Count)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Bar_DeleteWithQueryParams_Args) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Bar_DeleteWithQueryParams_Args) MarshalEasyJSON(w *jwriter.Writer) { + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Bar_DeleteWithQueryParams_Args) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Bar_DeleteWithQueryParams_Args) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBarBarDeleteWithQueryParams1(l, v) +} +func easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBar(in *jlexer.Lexer, out *BarRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + var StringFieldSet bool + var BoolFieldSet bool + var BinaryFieldSet bool + var TimestampSet bool + var EnumFieldSet bool + var LongFieldSet bool + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeString() + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "stringField": + out.StringField = string(in.String()) + StringFieldSet = true + case "boolField": + out.BoolField = bool(in.Bool()) + BoolFieldSet = true + case "binaryField": + if in.IsNull() { + in.Skip() + out.BinaryField = nil + } else { + out.BinaryField = in.Bytes() + } + BinaryFieldSet = true + case "timestamp": + if data := in.Raw(); in.Ok() { + in.AddError((out.Timestamp).UnmarshalJSON(data)) + } + TimestampSet = true + case "enumField": + if data := in.Raw(); in.Ok() { + in.AddError((out.EnumField).UnmarshalJSON(data)) + } + EnumFieldSet = true + case "longField": + if data := in.Raw(); in.Ok() { + in.AddError((out.LongField).UnmarshalJSON(data)) + } + LongFieldSet = true + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } + if !StringFieldSet { + in.AddError(fmt.Errorf("key 'stringField' is required")) + } + if !BoolFieldSet { + in.AddError(fmt.Errorf("key 'boolField' is required")) + } + if !BinaryFieldSet { + in.AddError(fmt.Errorf("key 'binaryField' is required")) + } + if !TimestampSet { + in.AddError(fmt.Errorf("key 'timestamp' is required")) + } + if !EnumFieldSet { + in.AddError(fmt.Errorf("key 'enumField' is required")) + } + if !LongFieldSet { + in.AddError(fmt.Errorf("key 'longField' is required")) + } +} +func easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeClientsBarBar(out *jwriter.Writer, in BarRequest) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"stringField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.StringField)) + } + { + const prefix string = ",\"boolField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.BoolField)) + } + { + const prefix string = ",\"binaryField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Base64Bytes(in.BinaryField) + } + { + const prefix string = ",\"timestamp\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Timestamp).MarshalJSON()) + } + { + const prefix string = ",\"enumField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.EnumField).MarshalJSON()) + } + { + const prefix string = ",\"longField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.LongField).MarshalJSON()) + } + out.RawByte('}') +} diff --git a/examples/example-gateway/build/gen-code/endpoints/bar/bar/bar_deletewithqueryparams.go b/examples/example-gateway/build/gen-code/endpoints/bar/bar/bar_deletewithqueryparams.go new file mode 100644 index 000000000..1a7c3ac6b --- /dev/null +++ b/examples/example-gateway/build/gen-code/endpoints/bar/bar/bar_deletewithqueryparams.go @@ -0,0 +1,438 @@ +// Code generated by thriftrw v1.19.0. DO NOT EDIT. +// @generated + +package bar + +import ( + errors "errors" + fmt "fmt" + multierr "go.uber.org/multierr" + wire "go.uber.org/thriftrw/wire" + zapcore "go.uber.org/zap/zapcore" + strings "strings" +) + +// Bar_DeleteWithQueryParams_Args represents the arguments for the Bar.deleteWithQueryParams function. +// +// The arguments for deleteWithQueryParams are sent and received over the wire as this struct. +type Bar_DeleteWithQueryParams_Args struct { + Request *BarRequest `json:"request,required"` + Filter string `json:"filter,required"` + Count *int32 `json:"count,omitempty"` +} + +// ToWire translates a Bar_DeleteWithQueryParams_Args struct into a Thrift-level intermediate +// representation. This intermediate representation may be serialized +// into bytes using a ThriftRW protocol implementation. +// +// An error is returned if the struct or any of its fields failed to +// validate. +// +// x, err := v.ToWire() +// if err != nil { +// return err +// } +// +// if err := binaryProtocol.Encode(x, writer); err != nil { +// return err +// } +func (v *Bar_DeleteWithQueryParams_Args) ToWire() (wire.Value, error) { + var ( + fields [3]wire.Field + i int = 0 + w wire.Value + err error + ) + + if v.Request == nil { + return w, errors.New("field Request of Bar_DeleteWithQueryParams_Args is required") + } + w, err = v.Request.ToWire() + if err != nil { + return w, err + } + fields[i] = wire.Field{ID: 1, Value: w} + i++ + + w, err = wire.NewValueString(v.Filter), error(nil) + if err != nil { + return w, err + } + fields[i] = wire.Field{ID: 2, Value: w} + i++ + if v.Count != nil { + w, err = wire.NewValueI32(*(v.Count)), error(nil) + if err != nil { + return w, err + } + fields[i] = wire.Field{ID: 3, Value: w} + i++ + } + + return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil +} + +// FromWire deserializes a Bar_DeleteWithQueryParams_Args struct from its Thrift-level +// representation. The Thrift-level representation may be obtained +// from a ThriftRW protocol implementation. +// +// An error is returned if we were unable to build a Bar_DeleteWithQueryParams_Args struct +// from the provided intermediate representation. +// +// x, err := binaryProtocol.Decode(reader, wire.TStruct) +// if err != nil { +// return nil, err +// } +// +// var v Bar_DeleteWithQueryParams_Args +// if err := v.FromWire(x); err != nil { +// return nil, err +// } +// return &v, nil +func (v *Bar_DeleteWithQueryParams_Args) FromWire(w wire.Value) error { + var err error + + requestIsSet := false + filterIsSet := false + + for _, field := range w.GetStruct().Fields { + switch field.ID { + case 1: + if field.Value.Type() == wire.TStruct { + v.Request, err = _BarRequest_Read(field.Value) + if err != nil { + return err + } + requestIsSet = true + } + case 2: + if field.Value.Type() == wire.TBinary { + v.Filter, err = field.Value.GetString(), error(nil) + if err != nil { + return err + } + filterIsSet = true + } + case 3: + if field.Value.Type() == wire.TI32 { + var x int32 + x, err = field.Value.GetI32(), error(nil) + v.Count = &x + if err != nil { + return err + } + + } + } + } + + if !requestIsSet { + return errors.New("field Request of Bar_DeleteWithQueryParams_Args is required") + } + + if !filterIsSet { + return errors.New("field Filter of Bar_DeleteWithQueryParams_Args is required") + } + + return nil +} + +// String returns a readable string representation of a Bar_DeleteWithQueryParams_Args +// struct. +func (v *Bar_DeleteWithQueryParams_Args) String() string { + if v == nil { + return "" + } + + var fields [3]string + i := 0 + fields[i] = fmt.Sprintf("Request: %v", v.Request) + i++ + fields[i] = fmt.Sprintf("Filter: %v", v.Filter) + i++ + if v.Count != nil { + fields[i] = fmt.Sprintf("Count: %v", *(v.Count)) + i++ + } + + return fmt.Sprintf("Bar_DeleteWithQueryParams_Args{%v}", strings.Join(fields[:i], ", ")) +} + +// Equals returns true if all the fields of this Bar_DeleteWithQueryParams_Args match the +// provided Bar_DeleteWithQueryParams_Args. +// +// This function performs a deep comparison. +func (v *Bar_DeleteWithQueryParams_Args) Equals(rhs *Bar_DeleteWithQueryParams_Args) bool { + if v == nil { + return rhs == nil + } else if rhs == nil { + return false + } + if !v.Request.Equals(rhs.Request) { + return false + } + if !(v.Filter == rhs.Filter) { + return false + } + if !_I32_EqualsPtr(v.Count, rhs.Count) { + return false + } + + return true +} + +// MarshalLogObject implements zapcore.ObjectMarshaler, enabling +// fast logging of Bar_DeleteWithQueryParams_Args. +func (v *Bar_DeleteWithQueryParams_Args) MarshalLogObject(enc zapcore.ObjectEncoder) (err error) { + if v == nil { + return nil + } + err = multierr.Append(err, enc.AddObject("request", v.Request)) + enc.AddString("filter", v.Filter) + if v.Count != nil { + enc.AddInt32("count", *v.Count) + } + return err +} + +// GetRequest returns the value of Request if it is set or its +// zero value if it is unset. +func (v *Bar_DeleteWithQueryParams_Args) GetRequest() (o *BarRequest) { + if v != nil { + o = v.Request + } + return +} + +// IsSetRequest returns true if Request is not nil. +func (v *Bar_DeleteWithQueryParams_Args) IsSetRequest() bool { + return v != nil && v.Request != nil +} + +// GetFilter returns the value of Filter if it is set or its +// zero value if it is unset. +func (v *Bar_DeleteWithQueryParams_Args) GetFilter() (o string) { + if v != nil { + o = v.Filter + } + return +} + +// GetCount returns the value of Count if it is set or its +// zero value if it is unset. +func (v *Bar_DeleteWithQueryParams_Args) GetCount() (o int32) { + if v != nil && v.Count != nil { + return *v.Count + } + + return +} + +// IsSetCount returns true if Count is not nil. +func (v *Bar_DeleteWithQueryParams_Args) IsSetCount() bool { + return v != nil && v.Count != nil +} + +// MethodName returns the name of the Thrift function as specified in +// the IDL, for which this struct represent the arguments. +// +// This will always be "deleteWithQueryParams" for this struct. +func (v *Bar_DeleteWithQueryParams_Args) MethodName() string { + return "deleteWithQueryParams" +} + +// EnvelopeType returns the kind of value inside this struct. +// +// This will always be Call for this struct. +func (v *Bar_DeleteWithQueryParams_Args) EnvelopeType() wire.EnvelopeType { + return wire.Call +} + +// Bar_DeleteWithQueryParams_Helper provides functions that aid in handling the +// parameters and return values of the Bar.deleteWithQueryParams +// function. +var Bar_DeleteWithQueryParams_Helper = struct { + // Args accepts the parameters of deleteWithQueryParams in-order and returns + // the arguments struct for the function. + Args func( + request *BarRequest, + filter string, + count *int32, + ) *Bar_DeleteWithQueryParams_Args + + // IsException returns true if the given error can be thrown + // by deleteWithQueryParams. + // + // An error can be thrown by deleteWithQueryParams only if the + // corresponding exception type was mentioned in the 'throws' + // section for it in the Thrift file. + IsException func(error) bool + + // WrapResponse returns the result struct for deleteWithQueryParams + // given the error returned by it. The provided error may + // be nil if deleteWithQueryParams did not fail. + // + // This allows mapping errors returned by deleteWithQueryParams into a + // serializable result struct. WrapResponse returns a + // non-nil error if the provided error cannot be thrown by + // deleteWithQueryParams + // + // err := deleteWithQueryParams(args) + // result, err := Bar_DeleteWithQueryParams_Helper.WrapResponse(err) + // if err != nil { + // return fmt.Errorf("unexpected error from deleteWithQueryParams: %v", err) + // } + // serialize(result) + WrapResponse func(error) (*Bar_DeleteWithQueryParams_Result, error) + + // UnwrapResponse takes the result struct for deleteWithQueryParams + // and returns the erorr returned by it (if any). + // + // The error is non-nil only if deleteWithQueryParams threw an + // exception. + // + // result := deserialize(bytes) + // err := Bar_DeleteWithQueryParams_Helper.UnwrapResponse(result) + UnwrapResponse func(*Bar_DeleteWithQueryParams_Result) error +}{} + +func init() { + Bar_DeleteWithQueryParams_Helper.Args = func( + request *BarRequest, + filter string, + count *int32, + ) *Bar_DeleteWithQueryParams_Args { + return &Bar_DeleteWithQueryParams_Args{ + Request: request, + Filter: filter, + Count: count, + } + } + + Bar_DeleteWithQueryParams_Helper.IsException = func(err error) bool { + switch err.(type) { + default: + return false + } + } + + Bar_DeleteWithQueryParams_Helper.WrapResponse = func(err error) (*Bar_DeleteWithQueryParams_Result, error) { + if err == nil { + return &Bar_DeleteWithQueryParams_Result{}, nil + } + + return nil, err + } + Bar_DeleteWithQueryParams_Helper.UnwrapResponse = func(result *Bar_DeleteWithQueryParams_Result) (err error) { + return + } + +} + +// Bar_DeleteWithQueryParams_Result represents the result of a Bar.deleteWithQueryParams function call. +// +// The result of a deleteWithQueryParams execution is sent and received over the wire as this struct. +type Bar_DeleteWithQueryParams_Result struct { +} + +// ToWire translates a Bar_DeleteWithQueryParams_Result struct into a Thrift-level intermediate +// representation. This intermediate representation may be serialized +// into bytes using a ThriftRW protocol implementation. +// +// An error is returned if the struct or any of its fields failed to +// validate. +// +// x, err := v.ToWire() +// if err != nil { +// return err +// } +// +// if err := binaryProtocol.Encode(x, writer); err != nil { +// return err +// } +func (v *Bar_DeleteWithQueryParams_Result) ToWire() (wire.Value, error) { + var ( + fields [0]wire.Field + i int = 0 + ) + + return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil +} + +// FromWire deserializes a Bar_DeleteWithQueryParams_Result struct from its Thrift-level +// representation. The Thrift-level representation may be obtained +// from a ThriftRW protocol implementation. +// +// An error is returned if we were unable to build a Bar_DeleteWithQueryParams_Result struct +// from the provided intermediate representation. +// +// x, err := binaryProtocol.Decode(reader, wire.TStruct) +// if err != nil { +// return nil, err +// } +// +// var v Bar_DeleteWithQueryParams_Result +// if err := v.FromWire(x); err != nil { +// return nil, err +// } +// return &v, nil +func (v *Bar_DeleteWithQueryParams_Result) FromWire(w wire.Value) error { + + for _, field := range w.GetStruct().Fields { + switch field.ID { + } + } + + return nil +} + +// String returns a readable string representation of a Bar_DeleteWithQueryParams_Result +// struct. +func (v *Bar_DeleteWithQueryParams_Result) String() string { + if v == nil { + return "" + } + + var fields [0]string + i := 0 + + return fmt.Sprintf("Bar_DeleteWithQueryParams_Result{%v}", strings.Join(fields[:i], ", ")) +} + +// Equals returns true if all the fields of this Bar_DeleteWithQueryParams_Result match the +// provided Bar_DeleteWithQueryParams_Result. +// +// This function performs a deep comparison. +func (v *Bar_DeleteWithQueryParams_Result) Equals(rhs *Bar_DeleteWithQueryParams_Result) bool { + if v == nil { + return rhs == nil + } else if rhs == nil { + return false + } + + return true +} + +// MarshalLogObject implements zapcore.ObjectMarshaler, enabling +// fast logging of Bar_DeleteWithQueryParams_Result. +func (v *Bar_DeleteWithQueryParams_Result) MarshalLogObject(enc zapcore.ObjectEncoder) (err error) { + if v == nil { + return nil + } + return err +} + +// MethodName returns the name of the Thrift function as specified in +// the IDL, for which this struct represent the result. +// +// This will always be "deleteWithQueryParams" for this struct. +func (v *Bar_DeleteWithQueryParams_Result) MethodName() string { + return "deleteWithQueryParams" +} + +// EnvelopeType returns the kind of value inside this struct. +// +// This will always be Reply for this struct. +func (v *Bar_DeleteWithQueryParams_Result) EnvelopeType() wire.EnvelopeType { + return wire.Reply +} diff --git a/examples/example-gateway/build/gen-code/endpoints/bar/bar/bar_deletewithqueryparams_easyjson.go b/examples/example-gateway/build/gen-code/endpoints/bar/bar/bar_deletewithqueryparams_easyjson.go new file mode 100644 index 000000000..480355c60 --- /dev/null +++ b/examples/example-gateway/build/gen-code/endpoints/bar/bar/bar_deletewithqueryparams_easyjson.go @@ -0,0 +1,355 @@ +// Code generated by zanzibar +// @generated +// Checksum : w4tJ9F0//opMGSTzPlQTsw== +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package bar + +import ( + json "encoding/json" + fmt "fmt" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams(in *jlexer.Lexer, out *Bar_DeleteWithQueryParams_Result) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeString() + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams(out *jwriter.Writer, in Bar_DeleteWithQueryParams_Result) { + out.RawByte('{') + first := true + _ = first + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Bar_DeleteWithQueryParams_Result) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Bar_DeleteWithQueryParams_Result) MarshalEasyJSON(w *jwriter.Writer) { + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Bar_DeleteWithQueryParams_Result) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Bar_DeleteWithQueryParams_Result) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams(l, v) +} +func easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams1(in *jlexer.Lexer, out *Bar_DeleteWithQueryParams_Args) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + var RequestSet bool + var FilterSet bool + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeString() + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "request": + if in.IsNull() { + in.Skip() + out.Request = nil + } else { + if out.Request == nil { + out.Request = new(BarRequest) + } + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBar(in, out.Request) + } + RequestSet = true + case "filter": + out.Filter = string(in.String()) + FilterSet = true + case "count": + if in.IsNull() { + in.Skip() + out.Count = nil + } else { + if out.Count == nil { + out.Count = new(int32) + } + *out.Count = int32(in.Int32()) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } + if !RequestSet { + in.AddError(fmt.Errorf("key 'request' is required")) + } + if !FilterSet { + in.AddError(fmt.Errorf("key 'filter' is required")) + } +} +func easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams1(out *jwriter.Writer, in Bar_DeleteWithQueryParams_Args) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"request\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Request == nil { + out.RawString("null") + } else { + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBar(out, *in.Request) + } + } + { + const prefix string = ",\"filter\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Filter)) + } + if in.Count != nil { + const prefix string = ",\"count\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int32(int32(*in.Count)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Bar_DeleteWithQueryParams_Args) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Bar_DeleteWithQueryParams_Args) MarshalEasyJSON(w *jwriter.Writer) { + easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Bar_DeleteWithQueryParams_Args) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Bar_DeleteWithQueryParams_Args) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBarBarDeleteWithQueryParams1(l, v) +} +func easyjson883c5671DecodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBar(in *jlexer.Lexer, out *BarRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + var StringFieldSet bool + var BoolFieldSet bool + var BinaryFieldSet bool + var TimestampSet bool + var EnumFieldSet bool + var LongFieldSet bool + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeString() + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "stringField": + out.StringField = string(in.String()) + StringFieldSet = true + case "boolField": + out.BoolField = bool(in.Bool()) + BoolFieldSet = true + case "binaryField": + if in.IsNull() { + in.Skip() + out.BinaryField = nil + } else { + out.BinaryField = in.Bytes() + } + BinaryFieldSet = true + case "timestamp": + if data := in.Raw(); in.Ok() { + in.AddError((out.Timestamp).UnmarshalJSON(data)) + } + TimestampSet = true + case "enumField": + if data := in.Raw(); in.Ok() { + in.AddError((out.EnumField).UnmarshalJSON(data)) + } + EnumFieldSet = true + case "longField": + if data := in.Raw(); in.Ok() { + in.AddError((out.LongField).UnmarshalJSON(data)) + } + LongFieldSet = true + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } + if !StringFieldSet { + in.AddError(fmt.Errorf("key 'stringField' is required")) + } + if !BoolFieldSet { + in.AddError(fmt.Errorf("key 'boolField' is required")) + } + if !BinaryFieldSet { + in.AddError(fmt.Errorf("key 'binaryField' is required")) + } + if !TimestampSet { + in.AddError(fmt.Errorf("key 'timestamp' is required")) + } + if !EnumFieldSet { + in.AddError(fmt.Errorf("key 'enumField' is required")) + } + if !LongFieldSet { + in.AddError(fmt.Errorf("key 'longField' is required")) + } +} +func easyjson883c5671EncodeGithubComUberZanzibarExamplesExampleGatewayBuildGenCodeEndpointsBarBar(out *jwriter.Writer, in BarRequest) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"stringField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.StringField)) + } + { + const prefix string = ",\"boolField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.BoolField)) + } + { + const prefix string = ",\"binaryField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Base64Bytes(in.BinaryField) + } + { + const prefix string = ",\"timestamp\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Timestamp).MarshalJSON()) + } + { + const prefix string = ",\"enumField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.EnumField).MarshalJSON()) + } + { + const prefix string = ",\"longField\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.LongField).MarshalJSON()) + } + out.RawByte('}') +} diff --git a/examples/example-gateway/clients/bar/client-config.json b/examples/example-gateway/clients/bar/client-config.json index b6841b907..aab8b6bd7 100644 --- a/examples/example-gateway/clients/bar/client-config.json +++ b/examples/example-gateway/clients/bar/client-config.json @@ -20,6 +20,7 @@ "ArgWithParamsAndDuplicateFields": "Bar::argWithParamsAndDuplicateFields", "Hello": "Bar::helloWorld", "DeleteFoo": "Bar::deleteFoo", + "DeleteWithQueryParams": "Bar::deleteWithQueryParams", "ListAndEnum": "Bar::listAndEnum", "EchoI8": "Echo::echoI8", "EchoI16": "Echo::echoI16", diff --git a/examples/example-gateway/idl/clients/bar/bar.thrift b/examples/example-gateway/idl/clients/bar/bar.thrift index c20c7f16c..d078d79ef 100644 --- a/examples/example-gateway/idl/clients/bar/bar.thrift +++ b/examples/example-gateway/idl/clients/bar/bar.thrift @@ -53,21 +53,19 @@ struct BarResponseRecur { } struct QueryParamsStruct { - 1: required string name - 2: optional string userUUID + 1: required string name (zanzibar.http.ref = "query.name") + 2: optional string userUUID (zanzibar.http.ref = "query.userUUID") // TODO: support header annotation - 3: optional string authUUID - 4: optional string authUUID2 ( - zanzibar.http.ref = "query.myuuid" - ) - 5: required list foo + 3: optional string authUUID (zanzibar.http.ref = "query.authUUID") + 4: optional string authUUID2 (zanzibar.http.ref = "query.myuuid") + 5: required list foo (zanzibar.http.ref = "query.foo") } struct QueryParamsOptsStruct { - 1: required string name - 2: optional string userUUID - 3: optional string authUUID - 4: optional string authUUID2 + 1: required string name (zanzibar.http.ref = "query.name") + 2: optional string userUUID (zanzibar.http.ref = "query.userUUID") + 3: optional string authUUID (zanzibar.http.ref = "query.authUUID") + 4: optional string authUUID2 (zanzibar.http.ref = "query.authUUID2") } struct ParamsStruct { @@ -179,25 +177,25 @@ service Bar { zanzibar.http.status = "200" ) - BarResponse argWithNestedQueryParams( - 1: required QueryParamsStruct request - 2: optional QueryParamsOptsStruct opt + BarResponse argWithQueryParams( + 1: required string name (zanzibar.http.ref = "query.name") + 2: optional string userUUID (zanzibar.http.ref = "query.userUUID") + 3: optional list foo (zanzibar.http.ref = "query.foo") + 4: required list bar (zanzibar.http.ref = "query.bar") + 5: optional set baz (zanzibar.http.ref = "query.baz") + 6: optional set bazbaz (zanzibar.http.ref = "query.bazbaz") ) ( zanzibar.http.method = "GET" - zanzibar.http.path = "/bar/argWithNestedQueryParams" + zanzibar.http.path = "/bar/argWithQueryParams" zanzibar.http.status = "200" ) - BarResponse argWithQueryParams( - 1: required string name - 2: optional string userUUID - 3: optional list foo - 4: required list bar - 5: optional set baz - 6: optional set bazbaz + BarResponse argWithNestedQueryParams( + 1: required QueryParamsStruct request (zanzibar.http.ref = "query.request") + 2: optional QueryParamsOptsStruct opt (zanzibar.http.ref = "query.opt") ) ( zanzibar.http.method = "GET" - zanzibar.http.path = "/bar/argWithQueryParams" + zanzibar.http.path = "/bar/argWithNestedQueryParams" zanzibar.http.status = "200" ) @@ -220,38 +218,47 @@ service Bar { ) BarResponse argWithManyQueryParams( - 1: required string aStr - 2: optional string anOptStr + 1: required string aStr (zanzibar.http.ref = "query.aStr") + 2: optional string anOptStr (zanzibar.http.ref = "query.anOptStr") 3: required bool aBool ( zanzibar.http.ref = "query.aBoolean" ) - 4: optional bool anOptBool - 5: required i8 aInt8 - 6: optional i8 anOptInt8 - 7: required i16 aInt16 - 8: optional i16 anOptInt16 - 9: required i32 aInt32 - 10: optional i32 anOptInt32 - 11: required i64 aInt64 - 12: optional i64 anOptInt64 - 13: required double aFloat64 - 14: optional double anOptFloat64 - 15: required UUID aUUID - 16: optional UUID anOptUUID - 17: required list aListUUID - 18: optional list anOptListUUID - 19: required StringList aStringList - 20: optional StringList anOptStringList - 21: required UUIDList aUUIDList - 22: optional UUIDList anOptUUIDList - 23: required Timestamp aTs - 24: optional Timestamp anOptTs + 4: optional bool anOptBool (zanzibar.http.ref = "query.anOptBool") + 5: required i8 aInt8 (zanzibar.http.ref = "query.aInt8") + 6: optional i8 anOptInt8 (zanzibar.http.ref = "query.anOptInt8") + 7: required i16 aInt16 (zanzibar.http.ref = "query.aInt16") + 8: optional i16 anOptInt16 (zanzibar.http.ref = "query.anOptInt16") + 9: required i32 aInt32 (zanzibar.http.ref = "query.aInt32") + 10: optional i32 anOptInt32 (zanzibar.http.ref = "query.anOptInt32") + 11: required i64 aInt64 (zanzibar.http.ref = "query.aInt64") + 12: optional i64 anOptInt64 (zanzibar.http.ref = "query.anOptInt64") + 13: required double aFloat64 (zanzibar.http.ref = "query.aFloat64") + 14: optional double anOptFloat64 (zanzibar.http.ref = "query.anOptFloat64") + 15: required UUID aUUID (zanzibar.http.ref = "query.aUUID") + 16: optional UUID anOptUUID (zanzibar.http.ref = "query.anOptUUID") + 17: required list aListUUID (zanzibar.http.ref = "query.aListUUID") + 18: optional list anOptListUUID (zanzibar.http.ref = "query.anOptListUUID") + 19: required StringList aStringList (zanzibar.http.ref = "query.aStringList") + 20: optional StringList anOptStringList (zanzibar.http.ref = "query.anOptStringList") + 21: required UUIDList aUUIDList (zanzibar.http.ref = "query.aUUIDList") + 22: optional UUIDList anOptUUIDList (zanzibar.http.ref = "query.anOptUUIDList") + 23: required Timestamp aTs (zanzibar.http.ref = "query.aTs") + 24: optional Timestamp anOptTs (zanzibar.http.ref = "query.anOptTs") ) ( zanzibar.http.method = "GET" zanzibar.http.path = "/bar/argWithManyQueryParams" zanzibar.http.status = "200" ) + BarResponse argWithParamsAndDuplicateFields( + 1: required RequestWithDuplicateType request + 2: required string entityUUID (zanzibar.http.ref = "params.uuid") + ) ( + zanzibar.http.method = "POST" + zanzibar.http.path = "/bar/argWithParamsAndDuplicateFields/:uuid/segment" + zanzibar.http.status = "200" + ) + void deleteFoo( 1: required BarRequest request ) ( @@ -260,14 +267,16 @@ service Bar { zanzibar.http.status = "200" ) - BarResponse argWithParamsAndDuplicateFields( - 1: required RequestWithDuplicateType request - 2: required string entityUUID (zanzibar.http.ref = "params.uuid") + void deleteWithQueryParams( + 1: required BarRequest request + 2: required string filter (zanzibar.http.ref = "query.filter") + 3: optional i32 count (zanzibar.http.ref = "query.count") ) ( - zanzibar.http.method = "POST" - zanzibar.http.path = "/bar/argWithParamsAndDuplicateFields/:uuid/segment" - zanzibar.http.status = "200" + zanzibar.http.method = "DELETE" + zanzibar.http.path = "/bar/withQueryParams" + zanzibar.http.status = "200" ) + } service Echo { diff --git a/examples/example-gateway/idl/endpoints/bar/bar.thrift b/examples/example-gateway/idl/endpoints/bar/bar.thrift index e5f14b2f1..623f309b8 100644 --- a/examples/example-gateway/idl/endpoints/bar/bar.thrift +++ b/examples/example-gateway/idl/endpoints/bar/bar.thrift @@ -44,18 +44,18 @@ struct BarResponse { } struct QueryParamsStruct { - 1: required string name - 2: optional string userUUID + 1: required string name (zanzibar.http.ref = "query.name") // hack assumes caller + 2: optional string userUUID (zanzibar.http.ref = "query.userUUID") // hack 3: optional string authUUID (zanzibar.http.ref="headers.x-uuid") 4: optional string authUUID2 (zanzibar.http.ref="headers.x-uuid2") - 5: required list foo + 5: required list foo (zanzibar.http.ref = "query.foo") } struct QueryParamsOptsStruct { - 1: required string name - 2: optional string userUUID - 3: optional string authUUID - 4: optional string authUUID2 + 1: required string name (zanzibar.http.ref = "query.name") + 2: optional string userUUID (zanzibar.http.ref = "query.userUUID") + 3: optional string authUUID (zanzibar.http.ref = "query.authUUID") + 4: optional string authUUID2 (zanzibar.http.ref = "query.authUUID2") } struct ParamsStruct { @@ -158,12 +158,12 @@ service Bar { ) BarResponse argWithQueryParams( - 1: required string name - 2: optional string userUUID - 3: optional list foo - 4: required list bar - 5: optional set baz - 6: optional set bazbaz + 1: required string name (zanzibar.http.ref = "query.name") + 2: optional string userUUID (zanzibar.http.ref = "query.userUUID") + 3: optional list foo (zanzibar.http.ref = "query.foo") + 4: required list bar (zanzibar.http.ref = "query.bar") + 5: optional set baz (zanzibar.http.ref = "query.baz") + 6: optional set bazbaz (zanzibar.http.ref = "query.bazbaz") ) ( zanzibar.http.method = "GET" @@ -173,8 +173,8 @@ service Bar { ) BarResponse argWithNestedQueryParams( - 1: required QueryParamsStruct request - 2: optional QueryParamsOptsStruct opt + 1: required QueryParamsStruct request (zanzibar.http.ref = "query.request") + 2: optional QueryParamsOptsStruct opt (zanzibar.http.ref = "query.opt") ) ( zanzibar.http.method = "GET" zanzibar.http.path = "/bar/argWithNestedQueryParams" @@ -204,30 +204,30 @@ service Bar { ) BarResponse argWithManyQueryParams( - 1: required string aStr - 2: optional string anOptStr - 3: required bool aBool - 4: optional bool anOptBool - 5: required i8 aInt8 - 6: optional i8 anOptInt8 - 7: required i16 aInt16 - 8: optional i16 anOptInt16 - 9: required i32 aInt32 - 10: optional i32 anOptInt32 - 11: required i64 aInt64 - 12: optional i64 anOptInt64 - 13: required double aFloat64 - 14: optional double anOptFloat64 - 15: required UUID aUUID - 16: optional UUID anOptUUID - 17: required list aListUUID - 18: optional list anOptListUUID - 19: required StringList aStringList - 20: optional StringList anOptStringList - 21: required UUIDList aUUIDList - 22: optional UUIDList anOptUUIDList - 23: required Timestamp aTs - 24: optional Timestamp anOptTs + 1: required string aStr (zanzibar.http.ref = "query.aStr") + 2: optional string anOptStr (zanzibar.http.ref = "query.anOptStr") + 3: required bool aBool (zanzibar.http.ref = "query.aBool") + 4: optional bool anOptBool (zanzibar.http.ref = "query.anOptBool") + 5: required i8 aInt8 (zanzibar.http.ref = "query.aInt8") + 6: optional i8 anOptInt8 (zanzibar.http.ref = "query.anOptInt8") + 7: required i16 aInt16 (zanzibar.http.ref = "query.aInt16") + 8: optional i16 anOptInt16 (zanzibar.http.ref = "query.anOptInt16") + 9: required i32 aInt32 (zanzibar.http.ref = "query.aInt32") + 10: optional i32 anOptInt32 (zanzibar.http.ref = "query.anOptInt32") + 11: required i64 aInt64 (zanzibar.http.ref = "query.aInt64") + 12: optional i64 anOptInt64 (zanzibar.http.ref = "query.anOptInt64") + 13: required double aFloat64 (zanzibar.http.ref = "query.aFloat64") + 14: optional double anOptFloat64 (zanzibar.http.ref = "query.anOptFloat64") + 15: required UUID aUUID (zanzibar.http.ref = "query.aUUID") + 16: optional UUID anOptUUID (zanzibar.http.ref = "query.anOptUUID") + 17: required list aListUUID (zanzibar.http.ref = "query.aListUUID") + 18: optional list anOptListUUID (zanzibar.http.ref = "query.anOptListUUID") + 19: required StringList aStringList (zanzibar.http.ref = "query.aStringList") + 20: optional StringList anOptStringList (zanzibar.http.ref = "query.anOptStringList") + 21: required UUIDList aUUIDList (zanzibar.http.ref = "query.aUUIDList") + 22: optional UUIDList anOptUUIDList (zanzibar.http.ref = "query.anOptUUIDList") + 23: required Timestamp aTs (zanzibar.http.ref = "query.aTs") + 24: optional Timestamp anOptTs (zanzibar.http.ref = "query.anOptTs") ) ( zanzibar.http.method = "GET" zanzibar.http.path = "/bar/argWithManyQueryParams" @@ -242,4 +242,14 @@ service Bar { zanzibar.http.path = "/bar/argWithParamsAndDuplicateFields/:uuid/segment" zanzibar.http.status = "200" ) + + void deleteWithQueryParams( + 1: required BarRequest request + 2: required string filter (zanzibar.http.ref = "query.filter") + 3: optional i32 count (zanzibar.http.ref = "query.count") + ) ( + zanzibar.http.method = "DELETE" + zanzibar.http.path = "/bar/withQueryParams" + zanzibar.http.status = "200" + ) } diff --git a/test/clients/bar/bar_test.go b/test/clients/bar/bar_test.go index f22b0ac29..55fb1b7c0 100644 --- a/test/clients/bar/bar_test.go +++ b/test/clients/bar/bar_test.go @@ -1068,3 +1068,40 @@ func TestDeleteFoo(t *testing.T) { ) assert.NoError(t, err) } + +func TestDeleteWithQueryParams(t *testing.T) { + gateway, err := benchGateway.CreateGateway( + defaultTestConfig, + defaultTestOptions, + exampleGateway.CreateGateway, + ) + if !assert.NoError(t, err) { + return + } + defer gateway.Close() + + bgateway := gateway.(*benchGateway.BenchGateway) + + bgateway.HTTPBackends()["bar"].HandleFunc( + "DELETE", "/bar/withQueryParams", + func(w http.ResponseWriter, r *http.Request) { + body, err := ioutil.ReadAll(r.Body) + assert.NoError(t, err) + + err = r.Body.Close() + assert.NoError(t, err) + + assert.JSONEq(t, `{ "request":{ "binaryField": null, "boolField": false, "enumField": "APPLE", "longField": { "high": 0, "low": 0 }, "stringField": "", "timestamp": "1970-01-01T00:00:00Z" }, "filter": "foo", "count": 3}`, string(body)) + }, + ) + deps := bgateway.Dependencies.(*exampleGateway.DependenciesTree) + bar := deps.Client.Bar + var count int32 = 3 + + _, err = bar.DeleteWithQueryParams( + context.Background(), + map[string]string{"x-uuid": "a-uuid"}, + &barGen.Bar_DeleteWithQueryParams_Args{Request: &barGen.BarRequest{}, Filter: "foo", Count: &count}, + ) + assert.NoError(t, err) +}