Understanding the GraphQL Type System
Schemas and Types

Understanding the GraphQL Type System

In this article, you will learn about GraphQL types: the five built-in scalar types, Enums, the List and Non-Null wrapping types, Object types, and the abstract Interface and Union types that work alongside them. You will review examples for each type and learn how to use them to build a complete GraphQL schema.

Scalar Types

All the data in a GraphQL schema ultimately resolve to various scalar types. GraphQL responses can be represented as a tree, and the scalar types are the leaves at the ends of the tree. There can be many levels in a nested response, but the last level will always resolve to a scalar (or Enum) type. GraphQL comes with five built-in scalar types:

  1. Int
  2. Float
  3. String
  4. Boolean
  5. ID.

Lets look at them in detail

Int

Int is a signed 32-bit non-fractional numerical value. It is a signed (positive or negative) integer that does not include decimals. The maximum value of a signed 32-bit integer is 2,147,483,647. This is one of the two built-in scalars used for numerical data.

Float

A Float is a signed double-precision fractional value. It is a signed (positive or negative) number that contains a decimal point, such as 1.4. This is the other built-in scalar used for numerical data.

String

A String is a UTF-8 character sequence. The String type is used for any textual data. This can also include data like very large numbers. Most custom scalars will be types of string data.

Boolean

A Boolean is a true or false value.

ID

An ID is a unique identifier. This value is always serialized as a string, even if the ID is numerical. An ID type might be commonly represented with a Universally Unique Identifier (UUID).

Custom Scalars

In addition to these built-in scalars, the scalar keyword can be used to define a custom scalar. You can use custom scalars to create types that have additional server-level validation, such as Date, Time, or Url. Here is an example defining a new Date type

scalar Date        
The server will know how to handle interactions with this new type using the GraphQLScalarType.

Enum Type

The Enum type, also known as an Enumerator type, describes a set of possible values.

Enum types are a special kind of scalar that is restricted to a particular set of allowed values. This allows you to:

  1. Validate that any arguments of this type are one of the allowed values
  2. Communicate through the type system that a field will always be one of a finite set of values

Here's what an enum definition might look like in the GraphQL schema language:

"The job class of the RangerNature."
enum Job {
  DOCTOR
  WIZARD
}

"The Species or what type of the RangerNature."
enum Species {
  HUMAN
  ALIEN
  DWARF
}        

In this way, it is guaranteed that the Job of a ranger nature is DOCTOR or WIZARD and can never accidentally be "purple" or some other random string, which could be possible if you used a String type instead of making a custom Enum. Enums are written in all-caps by convention.

Enums can also be used as the accepted values in arguments. For example, you might make a USAGE enum to denote whether a weapon is single-handed (like a short sword) or double-handed (like a strong axe), and use that to determine whether one or two can be equipped:

enum USAGE {
  SINGLE
  DOUBLE
}

"A valiant weapon wielded by a fighter."
type Weapon {
  name: String!
  attack: Int
  range: Int
  hand: Hand
}

type Query {
  weapons(usage: USAGE = SINGLE): [Weapon]
}        

The USAGE enum has been declared with SINGLE and DOUBLE as values, and the argument on the weapons field has a default value of SINGLE, meaning if no argument is passed then it will fall back to SINGLE.

Non-Null Type

You might notice that null or undefined, a common type that many languages consider a primitive, is missing from the list of built-in scalars. Null does exist in GraphQL and represents the lack of a value.

All types in GraphQL are nullable by default and therefore null is a valid response for any type. In order to make a value required, it must be converted to a GraphQL NON-NULL type with a trailing exclamation point (!). Non-Null is defined as a type modifier, which are types used to modify the type it is referring to. As an example, String is an optional (or nullable) string, and String! is a required (or Non-Null) string.

List Type

A List type in GraphQL is another type modifier. Any type that is wrapped in square brackets ([]) becomes a List type, which is a collection that defines the type of each item in a list.

As an example, a type defined as [Int] will be a collection of Int types, and [String] will be a collection of String types. Non-Null and List can be used together to make a type both required and defined as a List, such as [String]!.

Object Type

If GraphQL scalar types describe the “leaves” at the last of the ladder.GraphQL response, then Objects types describe the median “branches”, and almost everything in a GraphQL schema is a type of Object.

Objects consist of a list of named fields (keys) and the value type that each field will resolve to. Objects are defined with the type keyword. At least one or more fields must be defined, and fields cannot begin with two underscores (__) to avoid conflict with the GraphQL introspection system.

"A Power ranger who saves world with his strong power and sharp mind."
type PowerRanger {
   id: ID!
   age: Int
   org: String!
   active: Boolean!
   name: String
   friends:[String]
}        

In this example, the PowerRanger Object type has been declared, and it has has four named fields:

  • id yields a Non-Null ID type.
  • name yields a Null String type.
  • age yields an Int type.
  • org yield a Non-Null String type.
  • active yields a Non-Null Boolean type.
  • friends yields a Null List of String type

Above the declaration, you can also add a comment using double quotes, as in this example: "A Power ranger who saves world with his strong power and sharp mind.". This will appear as the description for the type.

In this example, each field resolves to a scalar type, but Object fields can also resolve to other Object types. For example, you could create a Weapon type, and the GraphQL schema can be set up where the weapon field on the PowerRanger will resolve to a Weapon Object

"A valiant weapon powered by a PowerRanger."
type Weapon {
  name: String!
  attack: Int
  range: Int
}

"A Power ranger who saves world with his strong power and sharp mind."
type PowerRanger {
   id: ID!
   age: Int
   org: String!
   active: Boolean!
   name: String
   weapon: Weapon
   friends:[String]
}        

Interface Type

As other languages offer GraphQL also supports interfaces. Like the Object type, the abstract Interface type consists of a list of named fields and their associated value types. Interfaces look like and follow all the same rules as Objects but are used to define a subset of an Object’s implementation.

So far in our schema, we have a PowerRanger Object, but you might also want to make a Doctor, a Healer, and other Objects that will share many of the same fields but have a few differences. In this case, you can use an Interface to define the fields they all have in common, and create Objects that are implementations of the Interface.

In the following example, you could create a Ranger Interface using the interface keyword with all the fields every type of ranger will possess

"A ranger on request ."
interface Ranger {
  id: ID!
  name: String!
  org: String!
  age: Int!
  active: Boolean!
}        

Every ranger type will have the fields id, name, org, age, and active.

Now, imagine you have a PowerRanger type and a Wizard type that have these shared fields, but PowerRangers use a Weapon and Wizards use Spells. You can use the implements keyword to delineate each as a Ranger implementation, which means they must have all the fields from the created Interface:

"A Power ranger who saves world with his strong power and sharp mind."
type PowerRanger {
   id: ID!
   age: Int
   org: String!
   active: Boolean!
   name: String
   friends:[String]
}

"A Ranger with a variety of powers."
type Wizard implements Ranger{
  id: ID!
  name: String!
  org: String!
  age: Int!
  active: Boolean!
  spells: [Spell]
}        

PowerRanger and Wizard are both valid implementations of the Ranger Interface because they have the required subset of fields.


Union Type

Another abstract type that can be used with Objects is the Union type. Using the union keyword, you can define a type with a list of Objects that are all valid as responses.

Using the Interfaces created in the previous section, you can create a RangerNature Union that defines a nature as a Wizard OR a PowerRanger

union RangerNature = Wizard | Fighter        

The equal character (=) sets the definition, and the pipe character (|) functions as the OR statement. Note that a Union must consist of Objects or Interfaces. Scalar types are not valid on a Union.

Now if you query for a list of characters, it could use the RangerNature Union and return all Wizard and PowerRanger types.


要查看或添加评论,请登录

Muthuraman Nagarajan的更多文章

  • What are GraphQL Queries?

    What are GraphQL Queries?

    Queries are entry points on a GraphQL server that provides read access to your data sources. GraphQL queries are a…

  • an earlier time !

    an earlier time !

    In the dynamic landscape of web development, GraphQL has emerged as a game-changer, redefining how APIs are designed…

  • Blue - Green - Deployment

    Blue - Green - Deployment

    In this new era of software development , every one wants a continuous development and hassle free deployment…

    1 条评论
  • Microservices -Divide and Conquer (A Brief Primer)

    Microservices -Divide and Conquer (A Brief Primer)

    Microservice Architecture is a software design pattern which divides the entire system into granular, independent, and…

    9 条评论

社区洞察