# Extended Scalars for graphql-java [![Build Status](https://github.com/graphql-java/graphql-java-extended-scalars/actions/workflows/master.yml/badge.svg)](https://github.com/graphql-java/graphql-java-extended-scalars/actions/workflows/master.yml) [![Latest Release](https://img.shields.io/maven-central/v/com.graphql-java/graphql-java-extended-scalars?versionPrefix=24.)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java-extended-scalars/) [![Latest Snapshot](https://img.shields.io/maven-central/v/com.graphql-java/graphql-java-extended-scalars??label=maven-central%20snapshot&versionPrefix=0.0.0)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java-extended-scalars/) [![MIT licensed](https://img.shields.io/badge/license-MIT-green)](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) [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 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 ```java implementation 'com.graphql-java:graphql-java-extended-scalars:24.0' ``` or the following into your Maven config ```xml com.graphql-java graphql-java-extended-scalars 24.0 ``` > Note: > > use 24.0 or above for graphql-java 24.x and above > > use 22.0 or above for graphql-java 22.x and above > > use 21.0 for graphql-java 21.x > > use 20.2 for graphql-java 20.x > ## How to use extended scalars ### Direct use Register the scalar with `graphql-java` ```java RuntimeWiring.newRuntimeWiring().scalar(ExtendedScalars.DateTime) ``` ### Spring for GraphQL If you are using [Spring for GraphQL](https://docs.spring.io/spring-graphql/docs/current/reference/html/), register the scalar with `RuntimeWiringConfigurer` ```java @Configuration public class GraphQlConfig { @Bean public RuntimeWiringConfigurer runtimeWiringConfigurer() { return wiringBuilder -> wiringBuilder.scalar(ExtendedScalars.DateTime); } } ``` ### Netflix DGS Note: Netflix also wraps this library in `com.netflix.graphql.dgs:graphql-dgs-extended-scalars` for [automatic registration](https://netflix.github.io/dgs/scalars/#automatically-register-scalar-extensions-via-graphql-dgs-extended-scalars). If you are using [Netflix DGS](https://netflix.github.io/dgs), please see the following docs: - [registration through runtime wiring](https://netflix.github.io/dgs/scalars/#register-scalar-extensions-via-dgsruntimewiring) - [configuration documentation](https://netflix.github.io/dgs/configuration/#dgs-extended-scalars-graphql-dgs-extended-scalars) ## How to add extended scalars to your schema 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 ``` To use a extended scalar in your schema, define the scalar like shown below for `DateTime` ```graphql scalar DateTime @specifiedBy(url: "https://scalars.graphql.org/andimarek/date-time.html") type Something { someDateTime: DateTime } ``` # Custom Scalars ## Alias Scalars
Scalar Definition Description
scalar AliasedScalar
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: ```java AliasedScalar socialMediaLink = ExtendedScalars.newAliasedScalar("SocialMediaLink") .aliasedScalar(Scalars.GraphQLString) .build(); ``` And use it in a SDL schema like this : ```graphql type Customer { name: String socialMediaLink: SocialMediaLink } ``` ## 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.
scalar SecondsSinceEpoch
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 java.time.ZonedDateTime objects at runtime (with UTC timezone).

Using seconds since epoch is preferable to formatted date time strings in several scenarios:
  • When you need a universal representation of a point in time that is timezone-agnostic
  • For easier date/time arithmetic and comparison operations
  • When storage space or bandwidth efficiency is important (more compact representation)
  • To avoid complexities with different date formats and timezone conversions
  • For better interoperability with systems that natively work with Unix timestamps
  • When working with time-series data or logging systems where timestamps are commonly used
However, human readability is sacrificed compared to formatted date strings, so consider your use case requirements when choosing between DateTime and SecondsSinceEpoch.
An example declaration in SDL might be: ```graphql type Customer { birthDay: Date workStartTime: Time bornAt: DateTime createdAtTimestamp: SecondsSinceEpoch } type Query { customers(bornAfter: DateTime, createdAfter: SecondsSinceEpoch): [Customers] } ``` And example query might look like: ```graphql query { customers(bornAfter: "1996-12-19T16:39:57-08:00", createdAfter: 1609459200) { birthDay bornAt createdAtTimestamp } } ``` ## 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
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: ```graphql type Customer { name: String currentHeight: PositiveInt weightLossGoal: NonPositiveInt averageWeightLoss: NegativeFloat } type Query { customers(height: PositiveInt): [Customers] } ``` And example query might look like: ```graphql query { customers(height: 182) { name height weightLossGoal } } ``` ## Java Primitives
Scalar Definition Description
scalar Long
A scalar which represents java.lang.Long
scalar Short
A scalar which represents java.lang.Short
scalar Byte
A scalar which represents java.lang.Byte
scalar BigDecimal
A scalar which represents java.math.BigDecimal
scalar BigInteger
A scalar which represents java.math.BigInteger
scalar Char
A scalar which represents java.lang.Character
## Locale Scalar
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 { name: String locale: Locale } type Query { customers(inLocale: Locale): [Customers] } ``` An example query to look for customers in the Romanian locale might look like: ```graphql query { customers(inLocale: "ro-RO") { name locale } } ``` ## Country Code Scalar
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: ```graphql scalar CountryCode type Customer { name: String countryCode: CountryCode } ``` And example query might look like: ```graphql query { customers(code: "US") { name countryCode } } ``` ## Currency Scalar
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: ```graphql scalar Currency type Account { id: String currency: Currency accountNumber: String } ``` And example query might look like: ```graphql query { accounts(currency: "USD") { id currency accountNumber } } ``` ## 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.
## Object / JSON Scalars
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. 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: ```graphql type Customer { name: String associatedMetaData: JSON } type Query { customers(filterSyntax: JSON): [Customers] } ``` And example query might look like: ```graphql 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 serialization protocol is up to you. Choose whichever name you think adds more semantic readers to your schema consumers. ## Regex Scalars
Scalar Name Description
RegexScalar Allows you to build a new scalar via a builder pattern using regular expressions.
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() ``` ## HexColorCode Scalar
Scalar Definition Description
scalar HexColorCode
  @specifiedBy(url: 
    "https://tools.ietf.org/html/bcp47"
  )
The HexColorCode scalar handles hex color code. You can handle it via java.awt.Color (which was built into JDK)
It Support Following Formats: - #RRGGBB - #RGB - #RRGGBBAA - #RGBA