Skip to content
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

Design: DateTime support #122

Open
DawidNiezgodka opened this issue Oct 18, 2022 · 0 comments
Open

Design: DateTime support #122

DawidNiezgodka opened this issue Oct 18, 2022 · 0 comments
Labels
type/design Design documents for enhancements

Comments

@DawidNiezgodka
Copy link
Contributor

DawidNiezgodka commented Oct 18, 2022

Caveat: The document is still in progress.

This document describes the approach to provide the support for DateTime in Quick.
Furthermore, it identifies potential problems that might arise along the way and the solutions to address them.

Currently, there are two issues related to the DateTime support:

  1. Basic support + Avro/Proto conversion
  2. JSON Conversion

Applying a schema with the DateTime included

What happens if DateTime is a return value of a query?

type Query {
    findContract(id: ID): Contract @topic(name: "contract-topic", keyArgument: "id")
}

type Contract  {
    _id: String!
    issued: DateTime
}

What happens if DateTime is given as a key?

type Query {
    findContract(issued: DateTime): Contract @topic(name: "contract-topic", keyArgument: "issued")
}

type Contract  {
    _id: String!
    issued: DateTime!
}

Does DateTime affect Subscription in any particular way?
No (?)

What happens if a user wants to apply a schema with a range query, where rangeFrom and rangeTo are DateTimes?
This is not supported at the moment, but will be later.

What happens if a user creates a topic with DateTime included?
GraphQL's DateTime has to be converted into Avro or Proto counterparts.

By and large, one has to be cautious about possible conversions between GraphQL's DateTime and other types that represent date and time. This involves:

  1. DateTime to Avro (and the other way around), f.e., topic creation,
  2. DateTime to Proto (and conversely), f.e., topic creation,
  3. DateTime to JSON (and conversely), f.e., data ingestion.

Implementation

We start by adding ExtendedScalars.DateTime to the list of GraphQLScalarTypes in GraphQLSchemaGenerator.

Topic creation

How to implement a specific conversion when a user creates a topic with the type schema, i.e.:
quick topic create contract --key-type string --value-type schema --schema example.Contract

Avro

In GraphQL, DateTime is a string.
In Avro, DateTime would be represented as Timestamp, which is long.
However, it is not that simple as Timestamp in Avro is a so-called LogicalType.

Problem: If we receive a string as input, we can't map it directly into long. How would we know that this is a date?
The question is how to create a schema with a logical type?
We can't just create a schema using Schema.create(type) as LogicalType is not a subtype of Type.
Thus, we can't use final Schema.Type type = SCALAR_MAPPING.get(scalarType.getName()); to obtain the Schema.Type.
An idea is to create a field ourselves when we recognize that ExtendedScalars.DataTime was passed.
We would than create a LogicalType and add it to a schema, i.e.:

// ...
if (type.equals(ExtendedScalars.DateTime)) {
// ...
final LogicalType timestamp = new LogicalType("timestamp-millis");
timestamp.addToSchema(schema);
return Schema.Field(name, schema, desc);
}

Proto
In Proto, there is a Timestamp, which is of type Message.
This means that proto.Timestamp is not a separate type in FieldDescriptorProto.Types. The idea is to add a field to the current message by providing a FieldDescriptionProto that has a type Message and TypeName Timestamp, i.e.:

final FieldDescriptorProto fd = FieldDescriptorProto.newBuilder()
                    .setName(graphQLFieldDefinition.getName())
                    .setType(FieldDescriptorProto.Type.TYPE_MESSAGE)
                    .setTypeName(Timestamp.getDescriptor().getFullName())
                    .setNumber(fieldNumber)
                    .setLabel(label)
                    .build();
                currentMessage.addField(fd);

Data ingestion

What should be the format of date time object in JSON so that it can be read correctly?

@raminqaf raminqaf added the type/design Design documents for enhancements label Oct 18, 2022
@DawidNiezgodka DawidNiezgodka added this to the DateTime support milestone Oct 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/design Design documents for enhancements
Projects
None yet
Development

No branches or pull requests

2 participants