Skip to content

Commit 850ae19

Browse files
authored
Merge pull request #159 from graphql-java/valueToLiteral_support
This removes all the deprecated Coercing methods and replaces them with the desired ones
2 parents 64a2449 + df78c80 commit 850ae19

File tree

57 files changed

+1097
-624
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1097
-624
lines changed

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,22 @@ scalar LocalTime
172172
</pre></td>
173173
<td>24-hour clock time string in the format <code>hh:mm:ss.sss</code> or <code>hh:mm:ss</code> if partial seconds is zero and produces <code>java.time.LocalTime</code> objects at runtime.</td>
174174
</tr>
175+
<tr>
176+
<td><pre lang="graphql">
177+
scalar SecondsSinceEpoch
178+
</pre></td>
179+
<td>A scalar that represents a point in time as seconds since the Unix epoch (January 1, 1970, 00:00:00 UTC). It accepts integers or strings containing integers as input values and produces <code>java.time.ZonedDateTime</code> objects at runtime (with UTC timezone).<br><br>
180+
Using seconds since epoch is preferable to formatted date time strings in several scenarios:
181+
<ul>
182+
<li>When you need a universal representation of a point in time that is timezone-agnostic</li>
183+
<li>For easier date/time arithmetic and comparison operations</li>
184+
<li>When storage space or bandwidth efficiency is important (more compact representation)</li>
185+
<li>To avoid complexities with different date formats and timezone conversions</li>
186+
<li>For better interoperability with systems that natively work with Unix timestamps</li>
187+
<li>When working with time-series data or logging systems where timestamps are commonly used</li>
188+
</ul>
189+
However, human readability is sacrificed compared to formatted date strings, so consider your use case requirements when choosing between <code>DateTime</code> and <code>SecondsSinceEpoch</code>.</td>
190+
</tr>
175191
</table>
176192

177193
An example declaration in SDL might be:
@@ -181,20 +197,22 @@ type Customer {
181197
birthDay: Date
182198
workStartTime: Time
183199
bornAt: DateTime
200+
createdAtTimestamp: SecondsSinceEpoch
184201
}
185202

186203
type Query {
187-
customers(bornAfter: DateTime): [Customers]
204+
customers(bornAfter: DateTime, createdAfter: SecondsSinceEpoch): [Customers]
188205
}
189206
```
190207

191208
And example query might look like:
192209

193210
```graphql
194211
query {
195-
customers(bornAfter: "1996-12-19T16:39:57-08:00") {
212+
customers(bornAfter: "1996-12-19T16:39:57-08:00", createdAfter: 1609459200) {
196213
birthDay
197214
bornAt
215+
createdAtTimestamp
198216
}
199217
}
200218
```

src/main/java/graphql/scalars/ExtendedScalars.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import graphql.scalars.datetime.AccurateDurationScalar;
1111
import graphql.scalars.datetime.LocalTimeCoercing;
1212
import graphql.scalars.datetime.NominalDurationScalar;
13+
import graphql.scalars.datetime.SecondsSinceEpochScalar;
1314
import graphql.scalars.datetime.TimeScalar;
1415
import graphql.scalars.datetime.YearMonthScalar;
1516
import graphql.scalars.datetime.YearScalar;
@@ -138,6 +139,34 @@ public class ExtendedScalars {
138139
*/
139140
public static final GraphQLScalarType NominalDuration = NominalDurationScalar.INSTANCE;
140141

142+
/**
143+
* A scalar that represents a point in time as seconds since the Unix epoch (Unix timestamp).
144+
* <p>
145+
* It accepts integers or strings containing integers as input values and produces
146+
* `java.time.ZonedDateTime` objects at runtime (with UTC timezone).
147+
* <p>
148+
* Its {@link graphql.schema.Coercing#serialize(java.lang.Object)} method accepts various
149+
* {@link java.time.temporal.TemporalAccessor} types and returns the number of seconds since epoch
150+
* (January 1, 1970, 00:00:00 UTC).
151+
* <p>
152+
* Using seconds since epoch is preferable to formatted date time strings in several scenarios:
153+
* <ul>
154+
* <li>When you need a universal representation of a point in time that is timezone-agnostic</li>
155+
* <li>For easier date/time arithmetic and comparison operations</li>
156+
* <li>When storage space or bandwidth efficiency is important (more compact representation)</li>
157+
* <li>To avoid complexities with different date formats and timezone conversions</li>
158+
* <li>For better interoperability with systems that natively work with Unix timestamps</li>
159+
* <li>When working with time-series data or logging systems where timestamps are commonly used</li>
160+
* </ul>
161+
* <p>
162+
* However, human readability is sacrificed compared to formatted date strings, so consider your use case
163+
* requirements when choosing between {@link #DateTime} and {@link #SecondsSinceEpoch}.
164+
*
165+
* @see java.time.Instant
166+
* @see java.time.ZonedDateTime
167+
*/
168+
public static final GraphQLScalarType SecondsSinceEpoch = SecondsSinceEpochScalar.INSTANCE;
169+
141170
/**
142171
* An object scalar allows you to have a multi level data value without defining it in the graphql schema.
143172
* <p>

src/main/java/graphql/scalars/alias/AliasedScalar.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
package graphql.scalars.alias;
22

33
import graphql.Assert;
4+
import graphql.GraphQLContext;
45
import graphql.Internal;
6+
import graphql.execution.CoercedVariables;
57
import graphql.language.Value;
68
import graphql.schema.Coercing;
79
import graphql.schema.CoercingParseLiteralException;
810
import graphql.schema.CoercingParseValueException;
911
import graphql.schema.CoercingSerializeException;
1012
import graphql.schema.GraphQLScalarType;
1113

12-
import java.util.Map;
14+
import java.util.Locale;
1315

1416
/**
1517
* Access this via {@link graphql.scalars.ExtendedScalars#newAliasedScalar(String)}
1618
*/
1719
@Internal
1820
public final class AliasedScalar {
1921

20-
private AliasedScalar() {}
22+
private AliasedScalar() {
23+
}
2124

2225
/**
2326
* A builder for {@link graphql.scalars.alias.AliasedScalar}
@@ -75,31 +78,25 @@ public GraphQLScalarType build() {
7578

7679
private static GraphQLScalarType aliasedScalarImpl(String name, String description, GraphQLScalarType aliasedScalar) {
7780
Assert.assertNotNull(aliasedScalar);
78-
Coercing<Object, Object> coercing = new Coercing<Object, Object>() {
79-
@Override
80-
public Object serialize(Object input) throws CoercingSerializeException {
81-
return aliasedScalar.getCoercing().serialize(input);
82-
}
83-
81+
Coercing<Object, Object> coercing = new Coercing<>() {
8482
@Override
85-
public Object parseValue(Object input) throws CoercingParseValueException {
86-
return aliasedScalar.getCoercing().parseValue(input);
83+
public Object serialize(Object input, GraphQLContext graphQLContext, Locale locale) throws CoercingSerializeException {
84+
return aliasedScalar.getCoercing().serialize(input, graphQLContext, locale);
8785
}
8886

8987
@Override
90-
public Object parseLiteral(Object input) throws CoercingParseLiteralException {
91-
return aliasedScalar.getCoercing().parseLiteral(input);
88+
public Object parseValue(Object input, GraphQLContext graphQLContext, Locale locale) throws CoercingParseValueException {
89+
return aliasedScalar.getCoercing().parseValue(input, graphQLContext, locale);
9290
}
9391

9492
@Override
95-
public Object parseLiteral(Object input, Map<String, Object> variables) throws CoercingParseLiteralException {
96-
Coercing<?, ?> c = aliasedScalar.getCoercing();
97-
return c.parseLiteral(input, variables);
93+
public Object parseLiteral(Value<?> input, CoercedVariables variables, GraphQLContext graphQLContext, Locale locale) throws CoercingParseLiteralException {
94+
return aliasedScalar.getCoercing().parseLiteral(input, variables, graphQLContext, locale);
9895
}
9996

10097
@Override
101-
public Value<?> valueToLiteral(Object input) {
102-
return aliasedScalar.getCoercing().valueToLiteral(input);
98+
public Value<?> valueToLiteral(Object input, GraphQLContext graphQLContext, Locale locale) {
99+
return aliasedScalar.getCoercing().valueToLiteral(input, graphQLContext, locale);
103100
}
104101
};
105102
return GraphQLScalarType.newScalar()

src/main/java/graphql/scalars/color/hex/HexColorCodeScalar.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
package graphql.scalars.color.hex;
22

3+
import graphql.GraphQLContext;
4+
import graphql.execution.CoercedVariables;
35
import graphql.language.StringValue;
46
import graphql.language.Value;
5-
import graphql.schema.*;
7+
import graphql.schema.Coercing;
8+
import graphql.schema.CoercingParseLiteralException;
9+
import graphql.schema.CoercingParseValueException;
10+
import graphql.schema.CoercingSerializeException;
11+
import graphql.schema.GraphQLScalarType;
612

713
import java.awt.*;
14+
import java.util.Locale;
815
import java.util.function.Function;
916
import java.util.regex.Pattern;
1017

1118
import static graphql.scalars.util.Kit.typeName;
19+
1220
/**
1321
* Access this via {@link graphql.scalars.ExtendedScalars#HexColorCode}
1422
* See the <a href="https://en.wikipedia.org/wiki/Web_colors">Web colors</a> for more details.
@@ -21,28 +29,28 @@ public class HexColorCodeScalar {
2129

2230

2331
static {
24-
Coercing<Color, String> coercing = new Coercing<Color, String>() {
32+
Coercing<Color, String> coercing = new Coercing<>() {
2533

2634
private final Pattern HEX_PATTERN = Pattern.compile("^(#([A-Fa-f0-9]{3,4}){1,2})$");
2735

2836
@Override
29-
public String serialize(Object input) throws CoercingSerializeException {
37+
public String serialize(Object input, GraphQLContext graphQLContext, Locale locale) throws CoercingSerializeException {
3038
Color color = parseColor(input, CoercingSerializeException::new);
3139
boolean hasAlpha = color.getAlpha() != 255;
32-
if (hasAlpha){
40+
if (hasAlpha) {
3341
return String.format("#%02x%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
3442
} else {
3543
return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue());
3644
}
3745
}
3846

3947
@Override
40-
public Color parseValue(Object input) throws CoercingParseValueException {
48+
public Color parseValue(Object input, GraphQLContext graphQLContext, Locale locale) throws CoercingParseValueException {
4149
return parseColor(input, CoercingParseValueException::new);
4250
}
4351

4452
@Override
45-
public Color parseLiteral(Object input) throws CoercingParseLiteralException {
53+
public Color parseLiteral(Value<?> input, CoercedVariables variables, GraphQLContext graphQLContext, Locale locale) throws CoercingParseLiteralException {
4654
if (!(input instanceof StringValue)) {
4755
throw new CoercingParseLiteralException("Expected type 'StringValue' but was '" + typeName(input) + "'.");
4856
}
@@ -51,8 +59,8 @@ public Color parseLiteral(Object input) throws CoercingParseLiteralException {
5159
}
5260

5361
@Override
54-
public Value<?> valueToLiteral(Object input) {
55-
String s = serialize(input);
62+
public Value<?> valueToLiteral(Object input, GraphQLContext graphQLContext, Locale locale) {
63+
String s = serialize(input, graphQLContext, locale);
5664
return StringValue.newStringValue(s).build();
5765
}
5866

src/main/java/graphql/scalars/country/code/CountryCodeScalar.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
package graphql.scalars.country.code;
22

3+
import graphql.GraphQLContext;
34
import graphql.Internal;
5+
import graphql.execution.CoercedVariables;
46
import graphql.language.StringValue;
57
import graphql.language.Value;
6-
import graphql.schema.*;
8+
import graphql.schema.Coercing;
9+
import graphql.schema.CoercingParseLiteralException;
10+
import graphql.schema.CoercingParseValueException;
11+
import graphql.schema.CoercingSerializeException;
12+
import graphql.schema.GraphQLScalarType;
713

14+
import java.util.Locale;
815
import java.util.function.Function;
916

1017
import static graphql.scalars.util.Kit.typeName;
@@ -18,21 +25,21 @@ public class CountryCodeScalar {
1825
public static final GraphQLScalarType INSTANCE;
1926

2027
static {
21-
Coercing<CountryCode, String> coercing = new Coercing<CountryCode, String>() {
28+
Coercing<CountryCode, String> coercing = new Coercing<>() {
2229

2330
@Override
24-
public String serialize(Object input) throws CoercingSerializeException {
31+
public String serialize(Object input, GraphQLContext graphQLContext, Locale locale) throws CoercingSerializeException {
2532
CountryCode countryCode = parseCountryCode(input, CoercingParseValueException::new);
2633
return countryCode.name();
2734
}
2835

2936
@Override
30-
public CountryCode parseValue(Object input) throws CoercingParseValueException {
37+
public CountryCode parseValue(Object input, GraphQLContext graphQLContext, Locale locale) throws CoercingParseValueException {
3138
return parseCountryCode(input, CoercingParseValueException::new);
3239
}
3340

3441
@Override
35-
public CountryCode parseLiteral(Object input) throws CoercingParseLiteralException {
42+
public CountryCode parseLiteral(Value<?> input, CoercedVariables variables, GraphQLContext graphQLContext, Locale locale) throws CoercingParseLiteralException {
3643
if (!(input instanceof StringValue)) {
3744
throw new CoercingParseLiteralException("Expected AST type 'StringValue' but was '" + typeName(input) + "'.");
3845
}
@@ -42,8 +49,8 @@ public CountryCode parseLiteral(Object input) throws CoercingParseLiteralExcepti
4249
}
4350

4451
@Override
45-
public Value<?> valueToLiteral(Object input) {
46-
String s = serialize(input);
52+
public Value<?> valueToLiteral(Object input, GraphQLContext graphQLContext, Locale locale) {
53+
String s = serialize(input, graphQLContext, locale);
4754
return StringValue.newStringValue(s).build();
4855
}
4956

src/main/java/graphql/scalars/currency/CurrencyScalar.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
package graphql.scalars.currency;
22

3+
import graphql.GraphQLContext;
34
import graphql.Internal;
5+
import graphql.execution.CoercedVariables;
46
import graphql.language.StringValue;
57
import graphql.language.Value;
6-
import graphql.schema.*;
8+
import graphql.schema.Coercing;
9+
import graphql.schema.CoercingParseLiteralException;
10+
import graphql.schema.CoercingParseValueException;
11+
import graphql.schema.CoercingSerializeException;
12+
import graphql.schema.GraphQLScalarType;
713

814
import java.util.Currency;
15+
import java.util.Locale;
916
import java.util.function.Function;
1017

1118
import static graphql.scalars.util.Kit.typeName;
@@ -19,21 +26,21 @@ public class CurrencyScalar {
1926
public static final GraphQLScalarType INSTANCE;
2027

2128
static {
22-
Coercing<Currency, String> coercing = new Coercing<Currency, String>() {
29+
Coercing<Currency, String> coercing = new Coercing<>() {
2330
@Override
24-
public String serialize(Object input) throws CoercingSerializeException {
31+
public String serialize(Object input, GraphQLContext graphQLContext, Locale locale) throws CoercingSerializeException {
2532
Currency currency = parseCurrency(input, CoercingSerializeException::new);
2633
return currency.getCurrencyCode();
2734
}
2835

2936
@Override
30-
public Currency parseValue(Object input) throws CoercingParseValueException {
37+
public Currency parseValue(Object input, GraphQLContext graphQLContext, Locale locale) throws CoercingParseValueException {
3138
return parseCurrency(input, CoercingParseValueException::new);
3239
}
3340

3441

3542
@Override
36-
public Currency parseLiteral(Object input) throws CoercingParseLiteralException {
43+
public Currency parseLiteral(Value<?> input, CoercedVariables variables, GraphQLContext graphQLContext, Locale locale) throws CoercingParseLiteralException {
3744
if (!(input instanceof StringValue)) {
3845
throw new CoercingParseLiteralException("Expected AST type 'StringValue' but was '" + typeName(input) + "'.");
3946
}
@@ -42,8 +49,8 @@ public Currency parseLiteral(Object input) throws CoercingParseLiteralException
4249
}
4350

4451
@Override
45-
public Value<?> valueToLiteral(Object input) {
46-
String serializedInput = serialize(input);
52+
public Value<?> valueToLiteral(Object input, GraphQLContext graphQLContext, Locale locale) {
53+
String serializedInput = serialize(input, graphQLContext, locale);
4754
return StringValue.newStringValue(serializedInput).build();
4855
}
4956

0 commit comments

Comments
 (0)