Skip to content

Typed Scalars #697

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

Closed
wtrocki opened this issue Mar 13, 2020 · 3 comments
Closed

Typed Scalars #697

wtrocki opened this issue Mar 13, 2020 · 3 comments

Comments

@wtrocki
Copy link

wtrocki commented Mar 13, 2020

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.

@wtrocki
Copy link
Author

wtrocki commented Mar 13, 2020

Actually using generics as the term might be confusing as they would typically apply to a different context

@wtrocki wtrocki changed the title Generic/Typed Scalars Typed Scalars Mar 13, 2020
@sungam3r
Copy link
Contributor

sungam3r commented Mar 13, 2020

In most programming languages developers have access to generics 

Yes. But keep in mind that GraphQL is not a programming language.

GraphQL is missing the ability to define some dynamic types

GraphQL is missing a lot of abilities of general purpose programming languages. GraphQL solves narrower tasks.

Refers to #190

@wtrocki
Copy link
Author

wtrocki commented Apr 23, 2020

I have done a couple of investigations on top of the graphql-js implementation in order to introduce generics.
The suggestion here is not strongly tied to Generics (and related problems with reflecting them). Since scalars will not suffer from __typename problem they can be introduced without large refactoring of every reference implementation. This could be a path to introduce generics gradually starting with scalars. Generics on scalar might sound controversial as scalars are used mostly for serialization/deserialization purposes, however, it might be a good way to introduce additional semantics that will give extra capabilities

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

2 participants