Scalars

Strawberry Shake supports the following scalars out of the box:

TypeDescription
IntSigned 32-bit numeric non-fractional value
FloatDouble-precision fractional values as specified by IEEE 754
StringUTF-8 character sequences
BooleanBoolean type representing true or false
IDUnique identifier
Byte
ByteArrayBase64 encoded array of bytes
ShortSigned 16-bit numeric non-fractional value
LongSigned 64-bit numeric non-fractional value
Decimal.NET Floating Point Type
UrlUrl
DateTimeISO-8601 date time
DateISO-8601 date
UuidGUID

Custom Scalars

As an addition to the scalars listed above, you can define your own scalars for the client. A scalar has two representation: the runtimeType and the serializationType. The runtimeType refers to the type you use in your dotnet application. The serializationType is the type that is used to transport the value.

Let us explore this with the example of DateTime. The server serializes a date into a string on the server. It is transported as a string over the wire:

JSON
{
"user": {
// the serializationType in this case is string
"registrationDate": "02-04-2001T12:00:03Z"
}
}

The registrationDate in our .NET client, should on the other hand be represented as a System.DateTime.

C#
public partial class GetUser_User : IEquatable<GetUser_User>, IGetUser_User
{
// ....
// The runtimeType is DateTime
public DateTime? RegistrationDate { get; }
// ....
}

By default, all custom scalars are treated like the String scalar. This means, that the client expects a string value and will deserialize it to a System.String.

If you want to change the serializationType or/and the runtimeType of a scalar, you have to specify the desired types in the schema.extensions.graphql. You can declare a scalar extension and add the @serializationType or/and the @runtimeType directive.

GraphQL
"Defines the serializationType of a scalar"
directive @serializationType(name: String!) on SCALAR
"Defines the runtimeType of a scalar"
directive @runtimeType(name: String!) on SCALAR
"Represents a integer value that is greater or equal to 0"
extend scalar PositiveInt
@serializationType(name: "global::System.Int32")
@runtimeType(name: "global::System.Int32")

As soon as you specify custom serialization and runtime types you also need to provide a serializer for the type.

Serializer

A scalar identifies its serializer by the scalar name, runtime- and serialization type. You have to provide an ISerializer as soon as you change the serializationType or the runtimeType. Use the base class ScalarSerializer<TValue> or ScalarSerializer<TSerializer, TRuntime> to create you custom serializer.

Simple Example

If the serialization and the value type are identical, you can just use the ScalarSerializer base class.

schema.extensions.graphql

GraphQL
extend scalar PositiveInt @serializationType(name: "global::System.Int32") @runtimeType(name: "global::System.Int32")

serializer

C#
public class PositiveIntSerializer : ScalarSerializer<int>
{
public PositiveInt()
: base(
// the name of the scalar
"PositiveInt")
{
}
}

configuration

C#
serviceCollection.AddSerializer<PositiveIntSerializer>();

Advanced Example

Your schema contains X509Certificate's. These are serialized to Base64 on the server and transported as strings.

schema.extensions.graphql

GraphQL
extend scalar X509Certificate
@serializationType(name: "global::System.String")
@runtimeType(name: "global::System.Security.Cryptography.X509Certificates.X509Certificate2")

serializer

C#
public class X509CertificateSerializer
: ScalarSerializer<string, X509Certificate2>
{
public X509CertificateSerializer()
: base(
// the name of the scalar
"X509Certificate")
{
}
// Parses the value that is returned from the server (Output)
public override X509Certificate2 Parse(string serializedValue)
{
return new X509Certificate2(Convert.FromBase64String(serializedValue));
}
// Formats the value to send to the server (Input)
protected override string Format(X509Certificate2 runtimeValue)
{
return Convert.ToBase64String(runtimeValue.Export(X509ContentType.Cert));
}
}

configuration

C#
serviceCollection.AddSerializer<X509CertificateSerializer>();