Introduction

GraphQL Scalars are the basic data types that represent the leaf nodes of a GraphQL query. They are the simplest form of data that can be returned from a GraphQL server. Scalars are used to define the types of fields in your GraphQL schema.

Built-in Scalar Types

GraphQL comes with several built-in scalar types:

  1. Int: A signed 32-bit integer.
  2. Float: A signed double-precision floating-point value.
  3. String: A UTF-8 character sequence.
  4. Boolean: A true or false value.
  5. ID: A unique identifier, often used to refetch an object or as a key for a cache.

Example Schema with Scalars

type User {
  id: ID!
  name: String!
  age: Int
  email: String
  isActive: Boolean!
  balance: Float
}

In this example:

  • id is an ID scalar type.
  • name and email are String scalar types.
  • age is an Int scalar type.
  • isActive is a Boolean scalar type.
  • balance is a Float scalar type.

Using Scalars in Queries

Scalars are used in both the schema definition and the queries. Here’s an example of how you might query scalar fields:

Example Query

query {
  user(id: "1") {
    id
    name
    age
    email
    isActive
    balance
  }
}

Example Response

{
  "data": {
    "user": {
      "id": "1",
      "name": "John Doe",
      "age": 30,
      "email": "[email protected]",
      "isActive": true,
      "balance": 100.50
    }
  }
}

Custom Scalars

While the built-in scalars cover many common use cases, sometimes you need more specific types. For example, you might need a Date type or a URL type. In such cases, you can define custom scalars.

Defining a Custom Scalar

To define a custom scalar, you need to:

  1. Define the scalar in your schema.
  2. Implement the scalar in your server code.

Example: Date Scalar

Schema Definition

scalar Date

type Event {
  id: ID!
  name: String!
  date: Date!
}

Server Implementation (JavaScript Example)

const { GraphQLScalarType, Kind } = require('graphql');

const DateScalar = new GraphQLScalarType({
  name: 'Date',
  description: 'Custom scalar type for dates',
  parseValue(value) {
    return new Date(value); // value from the client input variables
  },
  serialize(value) {
    return value.toISOString(); // value sent to the client
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      return new Date(ast.value); // value from the client query
    }
    return null;
  }
});

const resolvers = {
  Date: DateScalar,
  Query: {
    event: () => ({
      id: '1',
      name: 'GraphQL Conference',
      date: new Date()
    })
  }
};

Practical Exercise

Task

  1. Define a custom scalar type URL in your schema.
  2. Implement the URL scalar in your server code.
  3. Create a type Article with fields id, title, and url (using the URL scalar).
  4. Write a query to fetch an article by its id.

Solution

Schema Definition

scalar URL

type Article {
  id: ID!
  title: String!
  url: URL!
}

type Query {
  article(id: ID!): Article
}

Server Implementation (JavaScript Example)

const { GraphQLScalarType, Kind } = require('graphql');

const URLScalar = new GraphQLScalarType({
  name: 'URL',
  description: 'Custom scalar type for URLs',
  parseValue(value) {
    try {
      return new URL(value); // value from the client input variables
    } catch (e) {
      throw new Error('Invalid URL');
    }
  },
  serialize(value) {
    return value.toString(); // value sent to the client
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      try {
        return new URL(ast.value); // value from the client query
      } catch (e) {
        throw new Error('Invalid URL');
      }
    }
    return null;
  }
});

const resolvers = {
  URL: URLScalar,
  Query: {
    article: () => ({
      id: '1',
      title: 'Introduction to GraphQL',
      url: new URL('https://graphql.org/')
    })
  }
};

Example Query

query {
  article(id: "1") {
    id
    title
    url
  }
}

Example Response

{
  "data": {
    "article": {
      "id": "1",
      "title": "Introduction to GraphQL",
      "url": "https://graphql.org/"
    }
  }
}

Conclusion

In this section, we covered the basics of GraphQL Scalars, including built-in scalar types and how to define and use custom scalars. Scalars are fundamental to defining the types of fields in your GraphQL schema and are essential for ensuring data integrity and type safety. In the next module, we will dive deeper into more complex schema design concepts such as interfaces, unions, and enums.

© Copyright 2024. All rights reserved