package graphql import ( "context" "fmt" "strings" "github.com/pkg/errors" ) type Query[ReturnType any, Params any] struct { c *Client gqltype string containerLayers []string additionalPayloadParams map[string]interface{} additionalQueryParams map[string]interface{} } func NewQuery[ReturnType any, Params any]( c *Client, gqlType string, containerLayers []string, ) *Query[ReturnType, Params] { return &Query[ReturnType, Params]{ c: c, gqltype: gqlType, containerLayers: containerLayers, additionalPayloadParams: make(map[string]interface{}), additionalQueryParams: make(map[string]interface{}), } } func (r *Query[ReturnType, Params]) WithPayloadParam( name string, value interface{}, ) *Query[ReturnType, Params] { r.additionalPayloadParams[name] = value return r } func (r *Query[ReturnType, Params]) WithQueryParam( name string, value interface{}, ) *Query[ReturnType, Params] { r.additionalQueryParams[name] = value return r } func (r *Query[ReturnType, Params]) Get(ctx context.Context, params Params) (ReturnType, error) { paramsMap := convertParamsToMap(params) for k, v := range r.additionalPayloadParams { paramsMap[k] = v } gqltype := r.gqltype if len(paramsMap) > 0 { keys := make([]string, 0, len(paramsMap)) for k := range paramsMap { keys = append(keys, fmt.Sprintf("%s:$%s", k, k)) } gqltype = fmt.Sprintf("%s(%s)", gqltype, strings.Join(keys, ",")) } for k, v := range r.additionalQueryParams { paramsMap[k] = v } q := NewPayload[ReturnType](gqltype, r.containerLayers...) err := r.c.Query(ctx, q, paramsMap) if err != nil { var res ReturnType return res, errors.Wrap(err, "querying records") } return q.GetValue(), nil }