- When defining a type in the GraphQL schema, is it required to have an identifier? For example, in the following type, I don’t have an
ID
field because Net Worth is not an identifiable entity. So is this a valid type?
type NetWorth {
investments: Float!
cash: Float!
}
- Assuming that the above type is valid, how does it impact the Apollo cache and data normalization? I assume that
NetWorth
cannot be normalized because it does not have an ID
field. Is this correct? And can Apollo use the cached value in a subsequent query?
Hello, great question!
NetWorth
is not required to have an id
field or any other uniquely identifying field. When you query your server for an object that includes a field of type NetWorth
, such as the following…
type User {
id: ID!
netWorth: NetWorth!
}
…then Apollo Client caches the NetWorth
directly inside the parent object instead of using a reference to a separate cached object:
'User:5': {
__typename: 'User',
id: '5',
netWorth: {
__typename: 'NetWorth',
investments: 100.0,
cash: 50.0
}
}
Apollo Client can absolutely use the cached value for subsequent queries, but only as it pertains to the parent object. Because it sounds like a NetWorth
is directly tied to a particular parent object, this sounds acceptable for your use case.
Thanks @StephenBarlow. I can see how I might attach NetWorth
to a user with an id to cache it. That’s an interesting idea. FYI, the way I am currently using it is without attaching it to a user. Here’s my query:
query GetNetWorth($userId: ID!) {
netWorth(userId: $userId) {
investments
cash
}
}
It seems to work. Could I think of this as a query returning just a scalar? Is this even legal in GraphQL (query returning a scalar)?
FYI, looking at Apollo DevTools, it looks like the client is caching NetWorth based on __typename
and the query variable userId
. For example, there are two cache entries below for two users:
netWorth({"userId": "u100"}):
__typename:"NetWorth"
investments: 10000
cash: 200
netWorth({"userId": "u200"}):
__typename:"NetWorth"
investments: 5000
cash: 100
@StephenBarlow, I really like your last point about treating netWorth
as a field of User
type. I never thought about designing the schema that way - but I can see the value of this approach. I was thinking of the schema more in “relational” terms so not putting any computed values in there. But I suppose GraphQL does not have any such restriction, so adding computed fields to the object works out very well.
Thanks again for your insights!
1 Like