Skip to content

Typed Scalars #697

Closed
Closed
@wtrocki

Description

@wtrocki

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions