graphql / graphql/graphql-js

consider memoizing getArgumentValues

Open
#383 3 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
20.3k
Forks
2.1k
Avg merge
44m
Merged PRs (30d)
6

Description

Maybe I don't understand something, but I didn't think it would be necessary for `GraphQLScalarType.parseLiteral` to be called every time a field argument is resolved.

e.g., given this GraphQL query:

```
{
clients(limit: 10) {
id,
fullName,
birthDate,
deathDate,
age(asOf: "Jan 1st, 1987 @ 04:12:34.456 -0500")
}
}
```

And this field:

```
export default new GraphQLObjectType({
name: 'Client',
description: `Person served`,
fields: () => ({
age: {
type: GraphQLString,
description: `Age in "#y #m" format`,
args: {
asOf: {
type: DateTime,
description: `Date to calculate age from`
}
},

resolve: (client, {asOf}) => {
dump(asOf.format('D-MMM-YYYY @ H:mm:ss.SSS Z'));
...
```

And this custom type:

```
export default new GraphQLScalarType({
name: "DateTime",
description: `Scalar type representing a date and time with offset, serialized as a string in ISO-8601 date format.\n\ne.g. \`"2016-05-05T20:16:06Z"\``,
serialize(value) {
let date;
if(_.isNumber(value)) {
if(value === 0) {
return null;
}
date = moment.unix(value);
} else {
date = moment(value);
}
if(!date.isValid()) {
throw new GraphQLError(`Serialization error: ${value} is not a valid date`)
}
return date.format();
},
parseValue(value) {
// see https://gist.github.com/olange/f6c57d3ca577955fc3a51aa62f88c948
// or https://github.com/soundtrackyourbrand/graphql-custom-datetype/blob/master/datetype.js
// but parse it with moment.js
throw new GraphQLError(`parseValue(${value}) not implemented`)
},
parseLiteral(ast) {
if(ast.kind !== Kind.STRING && ast.kind !== Kind.INT) {
throw new GraphQLError(`Parse error: expected date string, got ${JSON.stringify(ast.value)}`, [ast]);
}

let result = parseDate(ast.value);

if(!result.isValid()) {
throw new GraphQLError(`Invalid date: ${JSON.stringify(ast.value)}`);
}

return result;
}
});
```

The `asOf` argument is parsed every time `resolve` is called -- i.e., 10 times for this one query because I've limited the results to 10. It so happens that my `parseDate` function is slow, this is kind of painful. I can memoize it on my end, but I didn't think that should be necessary.

Why aren't all the literals parsed just once when the query is received?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.