This library provides extended scalars for graphql-java
Scalars in graphql are the leaf nodes of a query, the non compound values that cant be queried further via sub field selections.
The graphql standard specifies that the String
, Int
, Float
, Boolean
and ID
scalars must be present in a graphql type
system but after that it is up to an implementation about what custom scalars are present.
You would use custom scalars when you want to describe more meaningful behavior or ranges of values.
To use this library put the following into your gradle config
compile 'com.graphql-java:graphql-java-extended-scalars:1.0'
or the following into your Maven config
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-extended-scalars</artifactId>
<version>1.0</version>
</dependency>
Then register the scalar with graphql-java
RuntimeWiring.newRuntimeWiring().scalar(ExtendedScalars.DateTime)
And use it in your schema
scalar DateTime
type Something {
someDateTime: DateTime
}
DateTime
- An RFC-3339 compliant date time scalar that accepts string values like
1996-12-19T16:39:57-08:00
and producesjava.time.OffsetDateTime
objects at runtime
- An RFC-3339 compliant date time scalar that accepts string values like
Time
- An RFC-3339 compliant time scalar that accepts string values like
16:39:57-08:00
and producesjava.time.LocalDate
objects at runtime
- An RFC-3339 compliant time scalar that accepts string values like
Date
- An RFC-3339 compliant date scalar that accepts string values like
1996-12-19
and producesjava.time.LocalDate
objects at runtime
- An RFC-3339 compliant date scalar that accepts string values like
See the rfc3339 spec for more details on the format.
An example declaration in SDL might be:
type Customer {
birthDay : Date
workStartTime : Time
bornAt : DateTime
}
type Query {
customers(bornAfter : DateTime) : [Customers]
}
And example query might look like:
query {
customers(bornAfter : "1996-12-19T16:39:57-08:00") {
birthDay
bornAt
}
}
-
Object
- An object scalar that accepts any object as a scalar value
-
JSON
- A synonym for the
Object
scalar, it will accept any object as a scalar value
- A synonym for the
One of the design goals of graphql, is that the type system describes the shape of the data returned.
The Object
/ JSON
scalars work against this some what because they can return compound values outside the type system. As such
they should be used sparingly. In general your should aim to describe the data via the graphql type system where you can and only
resort to the Object
/ JSON
scalars in very rare circumstances.
An example might be an extensible graphql system where systems can input custom metadata objects that cant be known at schema type design time.
An example declaration in SDL might be:
type Customer {
name : String
associatedMetaData : JSON
}
type Query {
customers(filterSyntax : JSON) : [Customers]
}
And example query might look like:
query {
customers(filterSyntax : {
startSpan : "First",
matchCriteria : {
countryCode : "AU",
isoCodes : ["27B-34R", "95A-E23"],
}
}) {
name
associatedMetaData
}
}
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
all just objects at runtime in graphql-java terms and what network serialisation protocol is up to you. Choose whichever name you think
adds more semantic readers to your schema consumers.
PositiveInt
- An
Int
scalar that MUST be greater than zero
- An
NegativeInt
- An
Int
scalar that MUST be less than zero
- An
NonPositiveInt
- An
Int
scalar that MUST be less than or equal to zero
- An
NonNegativeInt
- An
Int
scalar that MUST be greater than or equal to zero
- An
PositiveFloat
- An
Float
scalar that MUST be greater than zero
- An
NegativeFloat
- An
Float
scalar that MUST be less than zero
- An
NonPositiveFloat
- An
Float
scalar that MUST be less than or equal to zero
- An
NonNegativeFloat
- An
Float
scalar that MUST be greater than or equal to zero
- An
The numeric scalars are derivations of the standard graphql Int
and Float
scalars that enforce range limits.
An example declaration in SDL might be:
type Customer {
name : String
currentHeight : PositiveInt
weightLossGoal : NonPositiveInt
averageWeightLoss : NegativeFloat
}
type Query {
customers(height : PositiveInt) : [Customers]
}
And example query might look like:
query {
customers(height : 182) {
name
height
weightLossGoal
}
}
The RegexScalar has a builder where you provide one or more regex patterns that control the acceptable values for a new scalar.
You name the scalar and it provides an implementation.
For example, imagine a phoneNumber
scalar like this :
RegexScalar phoneNumberScalar = ExtendedScalars.newRegexScalar("phoneNumber")
.addPattern(Pattern.compile("\\([0-9]*\\)[0-9]*"))
.build()
The Locale scalar handles IETF BCP 47 language tags via the JDK method Locale.forLanguageTag
type Customer {
name : String
locale : Locale
}
type Query {
customers(inLocale : Locale) : [Customers]
}
An example query to look for customers in the Romanian locale might look like:
query {
customers(inLocale : "ro-RO") {
name
locale
}
}
You can create aliases for existing scalars to add more semantic meaning to them.
For example a link to a social media post could be representing by a String
but the name SocialMediaLink
is a
more semantically meaningful name for that scalar type.
For example, you would build it like this:
AliasedScalar socialMediaLink = ExtendedScalars.newAliasedScalar("SocialMediaLink")
.aliasedScalar(Scalars.GraphQLString)
.build()
And use it in a SDL schema like this :
type Customer {
name : String
socialMediaLink : SocialMediaLink
}
Note: A future version of the graphql specification may add this capability but in the meantime you can use this facility.
Url
- An url scalar that accepts string values like
https://www.w3.org/Addressing/URL/url-spec.txt
and producesjava.net.URL
objects at runtime
- An url scalar that accepts string values like