Skip to content
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

Can't use pointers for GQL fragments #91

Open
austingandy opened this issue Apr 29, 2023 · 0 comments
Open

Can't use pointers for GQL fragments #91

austingandy opened this issue Apr 29, 2023 · 0 comments

Comments

@austingandy
Copy link

I'm writing a query that involves querying a type union. Here are the relevant gql typedefs:

type SellingPlanPriceAdjustment {
    adjustmentValue: SellingPlanPriceAdjustmentValue!
    orderCount: Int
}

union SellingPlanPriceAdjustmentValue = SellingPlanFixedAmountPriceAdjustment | SellingPlanFixedPriceAdjustment | SellingPlanPercentagePriceAdjustment

type SellingPlanFixedAmountPriceAdjustment {
    adjustmentAmount: MoneyV2!
}

type SellingPlanFixedPriceAdjustment {
    price: MoneyV2!
}

type SellingPlanPercentagePriceAdjustment {
    adjustmentPercentage: Int!
}

type MoneyV2 {
    amount: Decimal!
    currencyCode: CurrencyCode!
}

My query to get back the price adjustment on a selling plan is as follows:

adjustmentValue {
    ... on SellingPlanFixedAmountPriceAdjustment {
        adjustmentAmount {
            amount
            currencyCode
        }
    }
    ... on SellingPlanFixedPriceAdjustment {
        price {
            amount
            currencyCode
        }
    }
    ... on SellingPlanPercentagePriceAdjustment {
        adjustmentPercentage
    }
}

When the query gets run, I end up with a response like:

"adjustmentValue": {
  "adjustmentPercentage": 5
}

I would like for my go structs for this query to look something along the lines of:

type AdjustmentValue struct {
	PercentageAdjustment  *PercentageAdjustment  `graphql:"... on SellingPlanPercentagePriceAdjustment"`
	FixedAmountAdjustment *FixedAmountAdjustment `graphql:"... on SellingPlanFixedAmountPriceAdjustment"`
	FixedPriceAdjustment  *FixedPriceAdjustment  `graphql:"... on SellingPlanFixedPriceAdjustment"`
}

type PercentageAdjustment struct {
	AdjustmentPercentage int
}

type FixedAmountAdjustment struct {
	AdjustmentAmount Money
}

type FixedPriceAdjustment struct {
	Price Money
}

type Money struct {
	Amount       graphql.Float
	CurrencyCode string
}

Unfortunately, using pointers for the fields in the AdjustmentValue struct results in an error:

struct field for "adjustmentPercentage" doesn't exist in any of 2 places to unmarshal

I suspect that this has something to do with which fields end up getting added to the stack on d.vs in the decoder.decode() func when iterating through the frontier, but it's not totally clear to me what specifically needs to change in order to remediate this.

Here's a test case for the above:

func TestUnmarshalGraphQL_pointerForInlineFragment(t *testing.T) {
	type user struct {
		DatabaseID uint64
	}
	type actor struct {
		User *user `graphql:"... on User"`
		Login string
	}
	type query struct {
		Author actor
		Editor *actor
	}
	var got query
	err := jsonutil.UnmarshalGraphQL([]byte(`{
		"author": {
			"databaseId": 1,
			"login": "test1"
		},
		"editor": {
			"databaseId": 2,
			"login": "test2"
		}
	}`), &got)
	if err != nil {
		t.Fatal(err)
	}
	var want query
	want.Author = actor{
		User:  struct{ DatabaseID uint64 }{1},
		Login: "test1",
	}
	want.Editor = &actor{
		User:  struct{ DatabaseID uint64 }{2},
		Login: "test2",
	}

	if !reflect.DeepEqual(got, want) {
		t.Error("not equal")
	}
}

I'll add -- if this is expected behavior and not something to fix, I'd love to see the constraint reflected a bit more clearly in the gql fragment section of the docs. As-is, I'm not sure it's particularly clear that we should expect for this situation to be unsupported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant