Skip to content

Commit d6834f9

Browse files
committed
Started to document the scalars
1 parent b5f9ab7 commit d6834f9

26 files changed

+568
-41
lines changed

readme.md

Lines changed: 165 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,169 @@
1+
# Extended Scalars for graphql-java
12

3+
This library provides extended scalars for [graphql-java](https://github.com/graphql-java/graphql-java)
24

3-
# Big work in PROGRESS
5+
Scalars in graphql are the leaf nodes of a query, the non compound values that cant be queried further via sub field selections.
46

5-
Not released and not ready for external consumption yet!
7+
The graphql standard specifies `String`, `Int`, `Float`, `Boolean` and `ID` must be present in a graphql type
8+
system but after that it is up to an implementation about what custom scalars are present.
69

7-
Still exploring what it could be
10+
You would use custom scalars when you want to describe more meaningful behavior or ranges of values.
11+
12+
## DateTime Scalars
13+
14+
* `DateTime`
15+
* An RFC-3339 compliant date time scalar that accepts string values like `1996-12-19T16:39:57-08:00` and produces
16+
`java.time.OffsetDateTime` objects at runtime
17+
* `Time`
18+
* An RFC-3339 compliant time scalar that accepts string values like `16:39:57-08:00` and produces
19+
`java.time.LocalDate` objects at runtime
20+
* `Date`
21+
* An RFC-3339 compliant date scalar that accepts string values like `1996-12-19` and produces
22+
`java.time.LocalDate` objects at runtime
23+
24+
See [the rfc3339 spec](https://www.ietf.org/rfc/rfc3339.txt) for more details on the format.
25+
26+
An example declaration in SDL might be:
27+
28+
```graphql
29+
30+
type Customer {
31+
birthDay : Date
32+
workStartTime : Time
33+
bornAt : DateTime
34+
}
35+
36+
type Query {
37+
customers(bornAfter : DateTime) : [Customers]
38+
}
39+
40+
```
41+
42+
And example query might look like:
43+
```graphql
44+
45+
query {
46+
customers(bornAfter : "1996-12-19T16:39:57-08:00") {
47+
birthDay
48+
bornAt
49+
}
50+
}
51+
52+
```
53+
54+
## Object / Json Scalars
55+
56+
* `Object`
57+
* An object scalar that accepts any object as a scalar value
58+
59+
* `Json`
60+
* A synonym for the `Object` scalar, it will accept any object as a scalar value
61+
62+
One of the design goals of graphql, is that the type system describes the shape of the data returned.
63+
64+
The `Object` / `Json` scalars work against this some what because they can return compound values outside the type system. As such
65+
they should be used sparingly. In general your should aim to describe the data via the graphql type system where you can and only
66+
resort to the `Object` / `Json` scalars in very rare circumstances.
67+
68+
An example might be an extensible graphql system where systems can input custom metadata objects that cant be known at
69+
schema type design time.
70+
71+
An example declaration in SDL might be:
72+
73+
```graphql
74+
75+
type Customer {
76+
name : String
77+
associatedMetaData : Json
78+
}
79+
80+
type Query {
81+
customers(filterSyntax : Json) : [Customers]
82+
}
83+
84+
```
85+
86+
And example query might look like:
87+
88+
```graphql
89+
90+
query {
91+
customers(filterSyntax : {
92+
startSpan : "First",
93+
matchCriteria : {
94+
countryCode : "AU",
95+
isoCodes : ["27B-34R", "95A-E23"],
96+
97+
}
98+
}) {
99+
name
100+
associatedMetaData
101+
}
102+
}
103+
104+
```
105+
106+
Note : The `Json` scalar is a simple alias type to the `Object` scalar because often the returned data is a blob of JSON. They are
107+
all just objects at runtime in graphql-java terms and what network serialisation protocol is up to you. Choose whichever name you think
108+
adds more semantic readers to your schema consumers.
109+
110+
111+
## Numeric Scalars
112+
113+
114+
* `PositiveInt`
115+
* An `Int` scalar that MUST be a greater than zero
116+
* `NegativeInt`
117+
* An `Int` scalar that MUST be a less than zero
118+
* `NonPositiveInt`
119+
* An `Int` scalar that MUST be a less than or equal to zero
120+
* `NonNegativeInt`
121+
* An `Int` scalar that MUST be a greater than or equal to zero
122+
* `PositiveFloat`
123+
* An `Float` scalar that MUST be a greater than zero
124+
* `NegativeFloat`
125+
* An `Float` scalar that MUST be a less than zero
126+
* `NonPositiveFloat`
127+
* An `Float` scalar that MUST be a less than or equal to zero
128+
* `NonNegativeFloat`
129+
* An `Float` scalar that MUST be a greater than or equal to zero
130+
131+
The numeric scalars are derivations of the standard graphql `Int` and `Float` scalars that enforce range limits.
132+
133+
An example declaration in SDL might be:
134+
135+
```graphql
136+
137+
type Customer {
138+
name : String
139+
currentHeight : PositiveInt
140+
weightLossGoal : NonPositiveInt
141+
averageWeightLoss : NegativeFloat
142+
}
143+
144+
type Query {
145+
customers(height : PositiveInt) : [Customers]
146+
}
147+
148+
```
149+
150+
And example query might look like:
151+
152+
```graphql
153+
154+
query {
155+
customers(height : 182) {
156+
name
157+
height
158+
weightLossGoal
159+
}
160+
}
161+
162+
```
163+
164+
165+
## Other Scalars
166+
167+
* `Url`
168+
* An url scalar that accepts string values like `https://www.w3.org/Addressing/URL/url-spec.txt` and produces
169+
`java.net.URL` objects at runtime

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
import graphql.PublicApi;
44
import graphql.scalars.datetime.DateTimeScalar;
5-
import graphql.scalars.datetime.FullDateScalar;
6-
import graphql.scalars.datetime.FullTimeScalar;
7-
import graphql.scalars.numbers.NegativeFloatScalar;
8-
import graphql.scalars.numbers.NegativeIntScalar;
9-
import graphql.scalars.numbers.NonNegativeFloatScalar;
10-
import graphql.scalars.numbers.NonNegativeIntScalar;
11-
import graphql.scalars.numbers.NonPositiveFloatScalar;
12-
import graphql.scalars.numbers.NonPositiveIntScalar;
13-
import graphql.scalars.numbers.PositiveFloatScalar;
14-
import graphql.scalars.numbers.PositiveIntScalar;
5+
import graphql.scalars.datetime.DateScalar;
6+
import graphql.scalars.datetime.TimeScalar;
7+
import graphql.scalars.numeric.NegativeFloatScalar;
8+
import graphql.scalars.numeric.NegativeIntScalar;
9+
import graphql.scalars.numeric.NonNegativeFloatScalar;
10+
import graphql.scalars.numeric.NonNegativeIntScalar;
11+
import graphql.scalars.numeric.NonPositiveFloatScalar;
12+
import graphql.scalars.numeric.NonPositiveIntScalar;
13+
import graphql.scalars.numeric.PositiveFloatScalar;
14+
import graphql.scalars.numeric.PositiveIntScalar;
1515
import graphql.scalars.object.JsonScalar;
1616
import graphql.scalars.object.ObjectScalar;
1717
import graphql.scalars.url.UrlScalar;
@@ -22,8 +22,8 @@ public class ExtendedScalars {
2222

2323

2424
public static GraphQLScalarType DateTime = new DateTimeScalar();
25-
public static GraphQLScalarType Date = new FullDateScalar();
26-
public static GraphQLScalarType Time = new FullTimeScalar();
25+
public static GraphQLScalarType Date = new DateScalar();
26+
public static GraphQLScalarType Time = new TimeScalar();
2727

2828
/**
2929
* An object scalar allows you to have a multi level data value without defining it in the graphql schema.

src/main/java/graphql/scalars/datetime/FullDateScalar.java renamed to src/main/java/graphql/scalars/datetime/DateScalar.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717

1818
import static graphql.scalars.util.Kit.typeName;
1919

20+
/**
21+
* Access this via {@link graphql.scalars.ExtendedScalars#Date}
22+
*/
2023
@Internal
21-
public class FullDateScalar extends GraphQLScalarType {
24+
public class DateScalar extends GraphQLScalarType {
2225

2326
private final static DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
24-
;
2527

26-
public FullDateScalar() {
28+
public DateScalar() {
2729
super("Date", "An RFC-3339 compliant Full Date Scalar", new Coercing<LocalDate, String>() {
2830
@Override
2931
public String serialize(Object input) throws CoercingSerializeException {

src/main/java/graphql/scalars/datetime/DateTimeScalar.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
import static graphql.scalars.util.Kit.typeName;
1919

20+
/**
21+
* Access this via {@link graphql.scalars.ExtendedScalars#DateTime}
22+
*/
2023
@Internal
2124
public class DateTimeScalar extends GraphQLScalarType {
2225

src/main/java/graphql/scalars/datetime/FullTimeScalar.java renamed to src/main/java/graphql/scalars/datetime/TimeScalar.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@
1717

1818
import static graphql.scalars.util.Kit.typeName;
1919

20+
/**
21+
* Access this via {@link graphql.scalars.ExtendedScalars#Time}
22+
*/
2023
@Internal
21-
public class FullTimeScalar extends GraphQLScalarType {
24+
public class TimeScalar extends GraphQLScalarType {
2225

2326
private final static DateTimeFormatter dateFormatter = DateTimeFormatter.ISO_OFFSET_TIME;
2427

25-
public FullTimeScalar() {
28+
public TimeScalar() {
2629
super("Time", "An RFC-3339 compliant Full Time Scalar", new Coercing<OffsetTime, String>() {
2730
@Override
2831
public String serialize(Object input) throws CoercingSerializeException {

src/main/java/graphql/scalars/numbers/FloatCoercing.java renamed to src/main/java/graphql/scalars/numeric/FloatCoercing.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
package graphql.scalars.numbers;
1+
package graphql.scalars.numeric;
22

3+
import graphql.Internal;
34
import graphql.schema.Coercing;
45
import graphql.schema.CoercingParseLiteralException;
56
import graphql.schema.CoercingParseValueException;
@@ -9,6 +10,7 @@
910

1011
import static graphql.Scalars.GraphQLFloat;
1112

13+
@Internal
1214
abstract class FloatCoercing implements Coercing<Double, Double> {
1315

1416
abstract protected Double check(Double d, Function<String, RuntimeException> exceptionMaker);

src/main/java/graphql/scalars/numbers/IntCoercing.java renamed to src/main/java/graphql/scalars/numeric/IntCoercing.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
package graphql.scalars.numbers;
1+
package graphql.scalars.numeric;
22

3+
import graphql.Internal;
34
import graphql.schema.Coercing;
45
import graphql.schema.CoercingParseLiteralException;
56
import graphql.schema.CoercingParseValueException;
@@ -9,6 +10,7 @@
910

1011
import static graphql.Scalars.GraphQLInt;
1112

13+
@Internal
1214
abstract class IntCoercing implements Coercing<Integer, Integer> {
1315

1416
abstract protected Integer check(Integer i, Function<String, RuntimeException> exceptionMaker);

src/main/java/graphql/scalars/numbers/NegativeFloatScalar.java renamed to src/main/java/graphql/scalars/numeric/NegativeFloatScalar.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
package graphql.scalars.numbers;
1+
package graphql.scalars.numeric;
22

3+
import graphql.Internal;
34
import graphql.schema.GraphQLScalarType;
45

56
import java.util.function.Function;
67

8+
/**
9+
* Access this via {@link graphql.scalars.ExtendedScalars#NegativeFloat}
10+
*/
11+
@Internal
712
public class NegativeFloatScalar extends GraphQLScalarType {
813
public NegativeFloatScalar() {
914
super("NegativeFloat", "An Float scalar that must be a negative value", new FloatCoercing() {

src/main/java/graphql/scalars/numbers/NegativeIntScalar.java renamed to src/main/java/graphql/scalars/numeric/NegativeIntScalar.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
package graphql.scalars.numbers;
1+
package graphql.scalars.numeric;
22

3+
import graphql.Internal;
34
import graphql.schema.GraphQLScalarType;
45

56
import java.util.function.Function;
67

8+
/**
9+
* Access this via {@link graphql.scalars.ExtendedScalars#NegativeInt}
10+
*/
11+
@Internal
712
public class NegativeIntScalar extends GraphQLScalarType {
813
public NegativeIntScalar() {
914
super("NegativeInt", "An Int scalar that must be a negative value", new IntCoercing() {

src/main/java/graphql/scalars/numbers/NonNegativeFloatScalar.java renamed to src/main/java/graphql/scalars/numeric/NonNegativeFloatScalar.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
package graphql.scalars.numbers;
1+
package graphql.scalars.numeric;
22

3+
import graphql.Internal;
34
import graphql.schema.GraphQLScalarType;
45

56
import java.util.function.Function;
67

8+
/**
9+
* Access this via {@link graphql.scalars.ExtendedScalars#NonNegativeFloat}
10+
*/
11+
@Internal
712
public class NonNegativeFloatScalar extends GraphQLScalarType {
813
public NonNegativeFloatScalar() {
914
super("NonNegativeFloat", "An Float scalar that must be greater than or equal to zero", new FloatCoercing() {

0 commit comments

Comments
 (0)