diff --git a/README.md b/README.md
index 9463f26..b71af40 100644
--- a/README.md
+++ b/README.md
@@ -5,28 +5,36 @@
[](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java-extended-scalars/)
[](https://github.com/graphql-java/graphql-java-extended-scalars/blob/master/LICENSE.md)
+## Overview
+
This library provides extended scalars for [graphql-java](https://github.com/graphql-java/graphql-java)
-Scalars in graphql are the leaf nodes of a query, the non-compound values that can't be queried further via sub-field selections.
+[GraphQL Scalars](https://spec.graphql.org/draft/#sec-Scalars) are the primitive leaf values in the GraphQL type system which cannot 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.
+The GraphQL Specification defines `String`, `Int`, `Float`, `Boolean` and `ID` as well-defined [built-in scalars](https://spec.graphql.org/draft/#sec-Scalars.Built-in-Scalars) that must be present in a graphql type
+system. Beyond these, it is up to an implementation to decide what [custom scalars](https://spec.graphql.org/draft/#sec-Scalars.Custom-Scalars) are present.
You would use custom scalars when you want to describe more meaningful behavior or ranges of values.
+# Getting started
+
## How to install
To use this library put the following into your gradle config
- implementation 'com.graphql-java:graphql-java-extended-scalars:20.0'
+```java
+implementation 'com.graphql-java:graphql-java-extended-scalars:20.0'
+```
or the following into your Maven config
-
- com.graphql-java
- graphql-java-extended-scalars
- 20.0
-
+```xml
+
+ com.graphql-java
+ graphql-java-extended-scalars
+ 20.2
+
+```
> Note:
>
@@ -34,106 +42,142 @@ or the following into your Maven config
>
> use 20.0 or above for graphql-java 20.x and above
-It's currently available from Maven Central.
-
## How to use extended scalars
-Register the scalar with graphql-java
+### Direct use
- RuntimeWiring.newRuntimeWiring().scalar(ExtendedScalars.DateTime)
+Register the scalar with `graphql-java`
-Or if using [Spring for GraphQL](https://docs.spring.io/spring-graphql/docs/current/reference/html/), register the scalar with `RuntimeWiringConfigurer`
+```java
+RuntimeWiring.newRuntimeWiring().scalar(ExtendedScalars.DateTime)
+```
- @Configuration
- public class GraphQlConfig {
- @Bean
- public RuntimeWiringConfigurer runtimeWiringConfigurer() {
- return wiringBuilder -> wiringBuilder.scalar(ExtendedScalars.DateTime);
- }
- }
+### Spring for GraphQL
-And use the scalar in your schema
+If you are using [Spring for GraphQL](https://docs.spring.io/spring-graphql/docs/current/reference/html/), register the scalar with `RuntimeWiringConfigurer`
- scalar DateTime
- type Something {
- someDateTime: DateTime
+```java
+@Configuration
+public class GraphQlConfig {
+ @Bean
+ public RuntimeWiringConfigurer runtimeWiringConfigurer() {
+ return wiringBuilder -> wiringBuilder.scalar(ExtendedScalars.DateTime);
}
+}
+```
-## DateTime Scalars
-
-- `DateTime` - [specification](https://scalars.graphql.org/andimarek/date-time.html)
- - See specification
- - An RFC-3339 compliant date time scalar that accepts string values like `1996-12-19T16:39:57-08:00` and produces
- `java.time.OffsetDateTime` objects at runtime.
-- `Time`
- - An RFC-3339 compliant time scalar that accepts string values like `16:39:57-08:00` and produces
- `java.time.OffsetTime` objects at runtime
-- `LocalTime`
- - 24-hour clock time string in the format `hh:mm:ss.sss` or `hh:mm:ss` if partial seconds is zero and
- produces `java.time.LocalTime` objects at runtime.
-- `Date`
- - An RFC-3339 compliant date scalar that accepts string values like `1996-12-19` and produces
- `java.time.LocalDate` objects at runtime
+### Netflix DGS
-An example declaration in SDL might be:
+If you are using [Netflix DGS](https://netflix.github.io/dgs), please see their [configuration documentation](https://netflix.github.io/dgs/configuration/#dgs-extended-scalars-graphql-dgs-extended-scalars).
-```graphql
-type Customer {
- birthDay: Date
- workStartTime: Time
- bornAt: DateTime
-}
+## How to add extended scalars to your schema
-type Query {
- customers(bornAfter: DateTime): [Customers]
-}
+The GraphQL Specification recommends the use of the [@specifiedBy](https://spec.graphql.org/October2021/#sec--specifiedBy) built-in schema directive to provide a scalar specification URL for specifying the behavior of custom scalar types.
+
+```graphql
+directive @specifiedBy(url: String!) on SCALAR
```
-And example query might look like:
+To use a extended scalar in your schema, define the scalar like shown below for `DateTime`
```graphql
-query {
- customers(bornAfter: "1996-12-19T16:39:57-08:00") {
- birthDay
- bornAt
- }
+scalar DateTime
+ @specifiedBy(url: "https://scalars.graphql.org/andimarek/date-time.html")
+
+type Something {
+ someDateTime: DateTime
}
```
-## ID Scalars
+# Custom Scalars
-- `UUID`
- - A universally unique identifier scalar that accepts uuid values like `2423f0a0-3b81-4115-a189-18df8b35e8fc` and produces
- `java.util.UUID` instances at runtime.
+## Alias Scalars
-## Object / JSON Scalars
+
+
+Scalar Definition |
+Description |
+
+
+
+scalar AliasedScalar
+ |
+You can create aliases for existing scalars to add more semantic meaning to them. |
+
+
-- `Object`
+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.
- - An object scalar that accepts any object as a scalar value
+For example, you would build it like this:
-- `JSON`
- - A synonym for the `Object` scalar, it will accept any object as a scalar value
+```java
+AliasedScalar socialMediaLink = ExtendedScalars.newAliasedScalar("SocialMediaLink")
+ .aliasedScalar(Scalars.GraphQLString)
+ .build()
+```
-One of the design goals of graphql, is that the type system describes the shape of the data returned.
+And use it in a SDL schema like this :
-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.
+```graphql
+type Customer {
+ name: String
+ socialMediaLink: SocialMediaLink
+}
+```
-An example might be an extensible graphql system where systems can input custom metadata objects that cant be known at
-schema type design time.
+## Date & Time Scalars
+
+
+
+Scalar Definition |
+Description |
+
+
+
+scalar DateTime
+ @specifiedBy(url:
+ "https://scalars.graphql.org/andimarek/date-time.html"
+ )
+ |
+A RFC-3339 compliant date time scalar that accepts string values like 1996-12-19T16:39:57-08:00 and produces java.time.OffsetDateTime objects at runtime. |
+
+
+
+scalar Date
+ @specifiedBy(url:
+ "https://tools.ietf.org/html/rfc3339"
+ ) |
+A RFC-3339 compliant date scalar that accepts string values like 1996-12-19 and produces java.time.LocalDate objects at runtime. |
+
+
+
+scalar Time
+ @specifiedBy(url:
+ "https://tools.ietf.org/html/rfc3339"
+ )
+ |
+A RFC-3339 compliant time scalar that accepts string values like 16:39:57-08:00 and produces java.time.OffsetTime objects at runtime. |
+
+
+
+scalar LocalTime
+ |
+24-hour clock time string in the format hh:mm:ss.sss or hh:mm:ss if partial seconds is zero and produces java.time.LocalTime objects at runtime. |
+
+
An example declaration in SDL might be:
```graphql
type Customer {
- name: String
- associatedMetaData: JSON
+ birthDay: Date
+ workStartTime: Time
+ bornAt: DateTime
}
type Query {
- customers(filterSyntax: JSON): [Customers]
+ customers(bornAfter: DateTime): [Customers]
}
```
@@ -141,42 +185,73 @@ And example query might look like:
```graphql
query {
- customers(
- filterSyntax: {
- startSpan: "First"
- matchCriteria: { countryCode: "AU", isoCodes: ["27B-34R", "95A-E23"] }
- }
- ) {
- name
- associatedMetaData
+ customers(bornAfter: "1996-12-19T16:39:57-08:00") {
+ birthDay
+ bornAt
}
}
```
-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.
+## ID Scalars
+
+
+
+Scalar Definition |
+Description |
+
+
+
+scalar UUID
+ @specifiedBy(url:
+ "https://tools.ietf.org/html/rfc4122"
+ )
+ |
+A universally unique identifier scalar that accepts uuid values like 2423f0a0-3b81-4115-a189-18df8b35e8fc and produces java.util.UUID instances at runtime. |
+
+
## Numeric Scalars
-- `PositiveInt`
- - An `Int` scalar that MUST be greater than zero
-- `NegativeInt`
- - An `Int` scalar that MUST be less than zero
-- `NonPositiveInt`
- - An `Int` scalar that MUST be less than or equal to zero
-- `NonNegativeInt`
- - An `Int` scalar that MUST be greater than or equal to zero
-- `PositiveFloat`
- - An `Float` scalar that MUST be greater than zero
-- `NegativeFloat`
- - An `Float` scalar that MUST be less than zero
-- `NonPositiveFloat`
- - An `Float` scalar that MUST be less than or equal to zero
-- `NonNegativeFloat`
- - An `Float` scalar that MUST be greater than or equal to zero
-
-The numeric scalars are derivations of the standard graphql `Int` and `Float` scalars that enforce range limits.
+
+
+Scalar Definition |
+Description |
+
+
+scalar PositiveInt |
+An Int scalar that MUST be greater than zero. |
+
+
+scalar NegativeInt |
+An Int scalar that MUST be less than zero. |
+
+
+scalar NonPositiveInt |
+An Int scalar that MUST be less than or equal to zero. |
+
+
+scalar NonNegativeInt |
+An Int scalar that MUST be greater than or equal to zero. |
+
+
+scalar PositiveFloat |
+An Float scalar that MUST be greater than zero. |
+
+
+scalar NegativeFloat |
+An Float scalar that MUST be less than zero. |
+
+
+scalar NonPositiveFloat |
+An Float scalar that MUST be less than or equal to zero. |
+
+
+scalar NonNegativeFloat |
+An Float scalar that MUST be greater than or equal to zero. |
+
+
+
+The numeric scalars are derivations of the standard GraphQL `Int` and `Float` scalars that enforce range limits.
An example declaration in SDL might be:
@@ -205,27 +280,56 @@ query {
}
```
-## Regex Scalars
-
-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 :
-
-```java
-
- RegexScalar phoneNumberScalar = ExtendedScalars.newRegexScalar("phoneNumber")
- .addPattern(Pattern.compile("\\([0-9]*\\)[0-9]*"))
- .build()
+## Java Primitives
-```
+
+
+Scalar Definition |
+Description |
+
+
+scalar GraphQLLong |
+A scalar which represents java.lang.Long
|
+
+
+scalar GraphQLShort |
+A scalar which represents java.lang.Short
|
+
+
+scalar GraphQLByte |
+A scalar which represents java.lang.Byte
|
+
+
+scalar GraphQLBigDecimal |
+A scalar which represents java.lang.BigDecimal
|
+
+
+scalar GraphQLBigInteger |
+A scalar which represents java.lang.BigInteger
|
+
+
+scalar GraphQLChar |
+A scalar which represents java.lang.Character
|
+
+
## Locale Scalar
-The Locale scalar handles [IETF BCP 47](https://tools.ietf.org/html/bcp47) language tags via the
-JDK method [Locale.forLanguageTag]()
+
+
+Scalar Definition |
+Description |
+
+
+
+scalar Locale
+ @specifiedBy(url:
+ "https://tools.ietf.org/html/bcp47"
+ )
+ |
+The Locale scalar handles IETF BCP 47 language tags via the JDK method Locale.forLanguageTag. |
+
+
```graphql
type Customer {
@@ -251,7 +355,21 @@ query {
## Country Code Scalar
-The CountryCode scalar type as defined by [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
+
+
+Scalar Definition |
+Description |
+
+
+
+scalar CountryCode
+ @specifiedBy(url:
+ "https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2"
+ )
+ |
+The CountryCode scalar type as defined by ISO 3166-1 alpha-2. |
+
+
An example declaration in SDL might be:
@@ -277,7 +395,21 @@ query {
## Currency Scalar
-A field whose value is an [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217) currency.
+
+
+Scalar Definition |
+Description |
+
+
+
+scalar Currency
+ @specifiedBy(url:
+ "https://en.wikipedia.org/wiki/ISO_4217"
+ )
+ |
+A field whose value is an ISO-4217 currency. |
+
+
An example declaration in SDL might be:
@@ -303,51 +435,107 @@ query {
}
```
-## Alias Scalars
+## URL Scalars
+
+
+
+Scalar Definition |
+Description |
+
+
+
+scalar URL
+ @specifiedBy(url:
+ "https://www.w3.org/Addressing/URL/url-spec.txt"
+ )
+ |
+An url scalar that accepts string values like https://www.w3.org/Addressing/URL/url-spec.txt and produces java.net.URL objects at runtime. |
+
+
-You can create aliases for existing scalars to add more semantic meaning to them.
+## Object / JSON Scalars
-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.
+
+
+Scalar Definition |
+Description |
+
+
+scalar Object |
+An object scalar that accepts any object as a scalar value. |
+
+
+scalar JSON |
+A synonym for the Object scalar, it will accept any object as a scalar value. |
+
+
+
+One of the design goals of GraphQL, is that the type system describes the shape of the data returned.
-For example, you would build it like this:
+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.
-```java
+An example might be an extensible GraphQL system where systems can input custom metadata objects that cant be known at
+schema type design time.
- AliasedScalar socialMediaLink = ExtendedScalars.newAliasedScalar("SocialMediaLink")
- .aliasedScalar(Scalars.GraphQLString)
- .build()
+An example declaration in SDL might be:
+```graphql
+type Customer {
+ name: String
+ associatedMetaData: JSON
+}
+
+type Query {
+ customers(filterSyntax: JSON): [Customers]
+}
```
-And use it in a SDL schema like this :
+And example query might look like:
```graphql
-type Customer {
- name: String
- socialMediaLink: SocialMediaLink
+query {
+ customers(
+ filterSyntax: {
+ startSpan: "First"
+ matchCriteria: { countryCode: "AU", isoCodes: ["27B-34R", "95A-E23"] }
+ }
+ ) {
+ name
+ associatedMetaData
+ }
}
```
-Note: A future version of the graphql specification may add this capability but in the meantime you can use this facility.
+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 serialization protocol is up to you. Choose whichever name you think
+adds more semantic readers to your schema consumers.
-## Java Primitives
+## Regex Scalars
+
+
+
+Scalar Name |
+Description |
+
+
+RegexScalar |
+Allows you to build a new scalar via a builder pattern using regular expressions. |
+
+
-- `GraphQLLong`
- - A scalar which represents `java.lang.Long`
-- `GraphQLShort`
- - A scalar which represents `java.lang.Short`
-- `GraphQLByte`
- - A scalar which represents `java.lang.Byte`
-- `GraphQLBigDecimal`
- - A scalar which represents `java.math.BigDecimal`
-- `GraphQLBigInteger`
- - A scalar which represents `java.math.BigInteger`
-- `GraphQLChar`
- - A scalar which represents `java.lang.Character`
-
-## Other Scalars
-
-- `Url`
- - An url scalar that accepts string values like `https://www.w3.org/Addressing/URL/url-spec.txt` and produces
- `java.net.URL` objects at runtime
+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 :
+
+```java
+
+ RegexScalar phoneNumberScalar = ExtendedScalars.newRegexScalar("phoneNumber")
+ .addPattern(Pattern.compile("\\([0-9]*\\)[0-9]*"))
+ .build()
+
+```