-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[RFC] New Scalar for date-time #579
Comments
IMHO the extension to use time zones has to be absolutely avoided. Timezone information is not constant and has to be resolved inside a context, that makes things not more complicated but practically impossible to handle... As far as I am concerned I would greatly appreciate a specified format (even simplified to a pure UTC only) in other to make some more things working nicely across "vendors" without tedious conversions. NodaTime/JodaTime have the concept of "Instant" that is what is useful and good to take (which is the similar to this RFC = amount of seconds/ms since an epoch or its equivalent ISO representation). One questionable point is if we should allow that to be a "sum" type: have an alternative string representation and (possibly large) integer representation at the same time (Union type in GraphQL terms but a more elegant one without an explicit type resolver, as it can be deduced from the format). Here some Blog references about this topic:
This shows some pitfalls Lee Byron also pointed out in #315. The semantic around the type should be very clearly documented, so people choosing to use that type know what it is intended for and not intended for. The type having Date in its name still has something not universal enough. The Gregorian calendar is a very common system across the world but by no mean absolutely unique... So this type would be a bit opinionated, providing support for extensions would probably be a good thing. |
This doesn't use time zones (like I'd also be fine with forcing everything to convert to UTC for a |
I updated the proposal based on the feedback so far. |
🍺 what about the complexity it may bring besides, time zone itself may not be a universal good standard for big(wide) country like China(we only use Beijing Time) IMHO |
@zzz6519003 @jdehaan please have a look at the explanation above about "Offset is not a full Time zone" |
I updated the proposal to make the relationship to RFC 3339 clear. |
Just as a follow-up to last WG: I like Lee's idea of referencing URL of spec. I would propose to call introspection field scalar DateTime @descibedBy(url: "https://www.ietf.org/rfc/rfc3339.txt") I also would suggest allowing this directive on any type not only scalar that way we would be able to use it for complex specs (e.g. Relay connection spec or Realy global ID spec) interface Node @describedBy(url: "https://facebook.github.io/relay/graphql/objectidentification.htm") {
id: ID
} |
Just read last WG notes:
My five cents how I solved collisions with custom scalars in 1) Override build-in type before type constructionimport { schemaComposer } from 'graphql-compose';
// before any type construction user may change build-in types
schemaComposer.set('Date', MyCustomDateType);
schemaComposer.set('MongoID', MyCustomMongoID);
schemaComposer.createOTC({
name: 'User',
fields: {
id: { type: 'MongoId' },
}
}); 2) Override build-in type on the first usage (no type in registry with such name):import { schemaComposer } from 'graphql-compose';
const MyCustomMongoID = new GraphQLScalarType({
name: 'MongoId',
...
});
schemaComposer.createOTC({
name: 'User',
fields: {
id: { type: MyCustomMongoID }, // <-- override `MongoId` type in registry, if it not used yet
}
});
schemaComposer.createOTC({
name: 'Article',
fields: {
id: { type:'MongoID' }, // <-- will use `MyCustomMongoID` from registry
}
});
const MyCustomMongoID222 = new GraphQLScalarType({
name: 'MongoId',
...
});
schemaComposer.createOTC({
name: 'User',
fields: {
id: { type: MyCustomMongoID222 }, // <-- throw an error, cause in registry already exists type instance with same name `MongoId`
}
}); So if we allow overriding built-in scalars in graphql we provide a workaround for users who already use
But with
|
Why would the spec be concerned about clients already implementing a glaring hole in the spec? Specs are supposed to evolve, and DateTime is the most common thing that people implement precisely because the current spec doesn't have it. Libs implementing the spec will upgrade. People using the libs will upgrade. It's not the end of the world. Also from the notes:
🤦 ISO 8601 and RFC 3339 exists for a reason. All the spec has to say is: A voice of reason in the WG:
Indeed. |
Also: it's been more than a year, and there's still no resolution to this bikeshedding |
@dmitriid There's work being done on this; please keep in mind that GraphQL Foundation is ran mostly by volunteers - if you'd like to see things happen faster, please get involved! The GraphQL Working Group have decided to create a GraphQL Scalars project which you can find here: https://github.com/graphql/graphql-scalars/issues the beginnings of a website about it here: https://www.graphql-scalars.com/ and you can read about it in the notes from recent WG calls e.g. https://github.com/graphql/graphql-wg/blob/afff6661e8494b1d96b674b4046d0311439705ec/notes/2020-06-11.md#graphql-scalars-hosting-and-coordination-10m-evan-and-andi You're more than welcome to start collaborating with Evan, Andi and team to help this project move faster. |
Date/time is a must for standardized implementation in the spec and should match the spec used by other systems to prevent DB errors I just had to fix a Wordpress DB because Advanced Custom Fields changed the date format a while ago and instead of updating their DB they added all kinds of UNMARKED and UNDOCUMENTED "fixes" to their functions.php. My keyboard has a forehead shaped impression now. This was all ONLY possible because Advanced Custom Fields uses strings and post_meta instead of a date field for storing dates. I had to use fancy regex to distinguish between ALL the types of meta data and pick non-delimited dates (YYYYmmdd) out of field IDs, etc in a table with half a million rows. Just my luck that certain date conversion functions in mysql don't work on fields marked as string. |
Just wondering. What prevents you from making your own custom scalar (with all that formatting/validation logic) for handling dates properly? |
@sungam3r Because it doesn't scale. If I implement this in my own code in my own custom way, it doesn't mean it will be implemented by some other library, or by code that interfaces with my GraphQL server. As a result, the support for this core data type is as varied as are GraphQL libraries. Apollo or graphql-java don't provide it out of the box, but graphql-go does (but only provides DateTime, with no support for just Date). When such things (and, I repeat myself, these are core data types used by nearly everyone), you really want them properly specced and not rely on implementations to be accidentally compatible. |
My 2¢: having a defined type in the spec would allow codegen and "generic" GraphQL libraries to more usefully work with the types. They're, IME, fairly common in practice, have nice, unambiguous RFC specs to refer to (to avoid overly verbose things in the GraphQL spec itself), and are generally well-supported in the languages in use today. |
Exactly Data Types need to be standardized. I am guessing you are too young to know about all the issues there used to be with computers back in the day. My Uncle is still scared for life from the trauma 🤣 In addition EVERY system should have record keeping and logs. That means EVERY dev would need to implement it themselves. Then you have devs with little to no experience making things that might end up in production environments. FUN FACT: The GUI library used by many Arduino projects was actually a C learning project for someone in their twenties which is now in millions of IOT devices along with all the legacy bugs and issues. <---- YOU DON'T WANT THAT IN YOUR DB. I just started using graphQL and I wouldn't want to be implementing DateTime functions myself. Especially since you have to account for linux, sql and other legacy implementations along with time zones, daylight savings time (which changes on different dates around the globe). A misplaced comma can cost hundreds of millions in damages. Imagine a stock trading app that sells a stock an hour late because it is using daylight saving time on 1 server and not on the other. Or the stock doesn't sell at all because the time is invalid. By the time a problem like that is caught a share price can fluctuate several $ adding up to huge losses. If you ever want graphQL to be used for anything serious it will need to add a lot of features for safety and security but also convenience. DateTime will have to be part of that sooner or later. I do see it heading that route though. Especially since it already has very good documentation unlike Dgraph. I can't wait until they finally add resolvers into the base implementation. |
"If you ever want graphQL to be used for anything serious it will need to add a lot of features for safety and security but also convenience. DateTime will have to be part of that sooner or later" Precisely. I reviewed the possibility of using Graphql for a LARGE implementation I am heading up. I cannot use Graphql in that implementation for precisely this reason. This would have been a VERY prestigious implementation of graphql. Now not happening. |
Meanwhile in March 2023 there's no progress on this. Meanwhile literally every graphql library has an add-on, plugin or extension to add Date/DateTime to the available types. If this is not a failure of the spec and of the process, I don't know what is. |
It looks like there's literaly no intention to move this forward. [1] Well, the current spec draft from Feb 10 2023 has exactly one reference to it: in code in the the scalars section. |
@andimarek I think this issue is complete now; if you agree please go ahead and close it to avoid confusion :) @dmitriid I don't really know what you mean by move this forward, it seems complete to me. If you'd like to contribute something more, you can add an agenda item to the next working group or you can send a pull request to the DateTime spec or to the GraphQL spec or if it's RFC3339 that you have an issue with you can contribute your own DateTime spec that uses ISO8601 or whatever alternative you would like. |
How is it complete? It's not in the main spec, there's nothing to force consistent and compatible implementations, it's mentioned in passing in the main spec in the same breath (and authority) as literally any other "spec" from any random person on the internet. |
To put it differently: how exactly is this different from the situation right now where every single library implements their own date time? |
When a server implements the above DateTime scalar (which they may call Note that the GraphQL specification states:
So whenever there's a custom scalar in a GraphQL API it should have a So:
Libraries should use |
These are custom scalars. Translation: they are not enforced by the spec. should doesn't equal to must. And even if some server implements this custom scalar doesn't mean that clients or other server will.
Ah yes. "Hopefully". Exactly what a spec should be and exactly what this issue was about. Not to have an authoritative specification but a "hopefully". So? How exactly is this issue done when literally nothing has changed? |
If you don't feel this is done, perhaps you should put the work in to advance it yourself? I suggest that you first read the Guiding Principles and figure out how you can make this a must without breaking a large number of existing GraphQL schemas across the planet, and then write up your proposal as an RFC and raise it at a GraphQL Working Group for discussion. Also note that just because something existing in the spec doesn't mean people are mandated to use it. There are plenty of GraphQL APIs out there that don't use the I am finding this discussion to be neither positive nor productive, so I will not be responding further to you unless you get involved in a positive spirit and put forward a proposal to fix the issues that you see. |
I consider this issue as successfully done. We now have a working GraphQL project at https://github.com/graphql/graphql-scalars which allows everybody to publish their custom scalar spec, which then can be used as specifiedBy value. I published my own preferred version of date time at https://scalars.graphql.org/andimarek/date-time |
What more positive spirit do you want anyone to be in the face of uncaring disinterested people who turn "I think this is a fundamental type that should be a standard GraphQL type" into "yeah, shunt it off to a side project that people will hopefully perhaps use at one point and if not, who cares"
Of course it cannot be used. Because But oh well. I've said my piece. If you don't care, why should I? |
This is a new attempt to add a date/time scalar to GraphQL in order to represent date and time. There has been previous discussions, which resulted in the decision not to extend GraphQL (see #315 )
Why a standard scalar for date/time
I think a scalar handling date/time is the most fundamental scalar missing in GraphQL. The arguments for having a standard scalar (or multiple) are:
Proposal: DateTime
The proposal is to add one new scalar: DateTime.
An DateTime is a specific point in time. It is represented in input and output as
yyyy-MM-dd'T'HH:mm:ss.SSSZ
. (The ultimate authority for the format is RFC 3339). For example2011-12-03T10:15:30.123+01:00
is a valid value.It doesn't include full timezone information (for example "Europe/Berlin").
The goal here is be very precise in the naming and strict in the allowed formats: it is an explicit non-goal to support a wide range of different formats.
Date/Time as defined in RFC 3339
The specific details of the format are defined in RFC 3339. This proposal doesn't introduce or change any new concepts.
Format definition
The format is defined in RFC 3339 section 5.6 section 5.6
date-time
.Offset is not a full Time zone
This scalar only deals with offsets (hours and minutes differences to UTC) and not full time zones. Full time zones also include rules regarding daylight saving time. For example "Europe/Berlin" represents a full timezone, but +02:00 is an offset used by "Europe/Berlin" during the summer.
Comparison is not trivial
A comparison between different DateTime is not trivial because two DateTime can represent the same point in time: For example
2008-12-03T11:00+01:00
and
2008-12-03T12:00+02:00
are both equal in this regard, but the strings are notWhy not have more formats?
The goal here is to make it easier to communicate a specific point in time. Having one well defined (and widely supported) format is the best way to achieve that imho.
What about other scalars?
I wanted to keep this proposal as simple as possible and I think
DateTime
is a good start for supporting date/time better in GraphQL.I think having a LocalDateTime or LocalDate or LocalTime are worth having a discussion, but at the same time they can be represented as an DateTime in some way and I didn't want to make this proposal more complex.
Why not restrict to just UTC?
This is a possible alternative. (In this case the format would be
yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
with a constZ
at the end). I would prefer calling this scalar notDateTime
anymore, butInstant
.By restricting it to just
UTC
it would be somehow simpler, but we would also loose flexibility.With
DateTime
one can easily imagine a type like this:This would allow for a point in a Time in a specific zone. (for example a recurring calendar entry).
Using an
Instant
in this way is not really possible, because it would always be formatted inUTC
.I see
Instant
as a possible additional scalar which could be introduced later (if needed).DateTime or OffsetDateTime or ....
The first version of this RFC named the scalar
OffsetDateTime
. It was then renamed toDateTime
to reflect that this is the name most people use for a date-time scalar.The text was updated successfully, but these errors were encountered: