Description
Ability to provide Types for Scalars
Summary
This RFC calls for the ability to supply GraphQLObjectType as a parameter for GraphQLScalar.
So given:
scalar MongoQueryFilter
type User {
id: ID!
name: String!
}
Developers should be able to do define
type Query {
findUserBy(filter: MongoQueryFilter[User]))
}
or
Developers should be able to do define
type Query {
findUserBy(filter: MongoQueryFilter(User)))
}
Scalar implementation should be able to receive extra GraphQLObjectType
Introduction
In most programming languages developers have access to generics that are usually reflected by specifying brackets over the object. For example List<string>
can define the list of the string values.
GraphQL is missing the ability to define some dynamic types that their internal properties will depend on.
This can be useful in situations when we want to provide a generic standard for handling some specifics of the data but then make it very specific to work with GraphQL type.
This is the use case when new abstracts like Input Unions resolve this problem only partially.
For example, when trying to define mongo query specifics like $eq
(https://docs.mongodb.com/manual/reference/operator/query/#query-selectors) we might also want to validate it with the specific fields of the type.
Developers should be able to perform query like this
find(filter: { age: { $lt: 25 } })
Where age could be one of the fields from the provided type.
There could be other benefits of being able to specify generic scalars.
Workarounds
The community was trying to resolve this problem by workarounds.
For example:
- Directive with type
- Code Generation with multiple combinations of InputTypes and Unions
For example https://www.opencrud.org/ - Specifying queries in directives
- Using field names as a way to build a query
- JSON scalar
- description metadata and tooling to hack it
findUserBy(
"""
@filter.type: User
"""
filter: MongoQueryFilter
)
See: https://github.com/aerogear/graphql-metadata
Problems with workarounds
The most popular approach used now my major GraphQL adopters is source code generation.
Generating the source code leads to an overly large schema
where a large number of elements might not be used.
Example: https://www.opencrud.org/#sec-Data-types
Dealing with such big schema gives problems when parsing and querying the data.
Scalar vs InputType vs ObjectType
Generics on scalars could be confusing as there is no such concept in programming languages. Generics are usually applied to classes.
Both Object and InputTypes do not bring any implementation with them
so generic parameter does not make much sense as there is no way to consume that information.
How this could be implemented
To provide backward compatibility new GenericScalar
can be introduced.
Changes in parser should be able to incorporate new < > tokens.