GraphQL Tutorial #3 – GraphQL Components

We can use different languages to implement a GraphQL server. GraphQL is a strongly typed language and it is really important to learn about the type system. Also, even though you are going to use a single framework in the future for developing your server or client-side application, it is a good idea to learn about the different GraphQL Components like a client, server, schema etc. libraries available.

In this post, we are going to discuss different GraphQL client-server frameworks, type systems, and the validation and execution process of a GraphQL request.

GraphQL Client and Server :

A GraphQL server can be implemented in many programming languages. Many popular client-side frameworks are available to build the client application. But you can also call a GraphQL server using a simple POST request. Mark the ‘Content-type’ as ‘application/json’ and pass the query as a ‘query’ field in a JSON payload. For example :

This ‘curl’ request will return the output as JSON for the query ‘{ student }’. For testing GraphQL queries during development time, you can use Graphical user interface libraries like GraphiQL and Insomnia.

Without a client framework, a GraphQL application can be built but the main advantage of using a client framework is that they already have many useful inbuilt features like caching, batching, etc. Also, a framework makes it easier to organize the application. You can check this page to learn more about the popular client libraries, server-side frameworks, services, and other useful GraphQL related packages.

GraphQL Schema and Type system:

GraphQL is available in a lot of backend technologies. You can use any one of them to develop a GraphQL server. GraphQL Schema is used to describe the functionalities of a GraphQL server that the client will use to connect. A Schema is defined by various data types. GraphQL is strongly typed and the Schema is defined using the type system. For example,

Suppose this GraphQL query is used to get the ‘name’ and ‘age’ of a ‘student’ object. The client can request for any type of data from the server using different queries. But the main functionality of the server is still unavailable to the client. Schema is used for that. It will define the type operations available for the client, the relationship between different types and kind of data the client will receive. The Schemas are validated and executed when the server receives a query.

GraphQL Schemas are written in their own language called ‘Schema Definition language’ or ‘SDL’. It is easy to use human-readable language.

Object types, fields and Scalar types :

Objects are the basic components of a GraphQL schema. It is used to represent what type of objects we are fetching from the server. Each object includes some fields or the properties we want for that object. Each field will resolve based on its ‘scalar type’. Let me quickly explain to you these concepts with a simple example :

In this Schema :

  • Student and Mark are both object type. Each object holds the fields that can be included in these objects.
  • name, age, marks, subject, and mark are all fields of Student and Mark
  • String and Int are built-in scalar types. The ‘!’ sign marks the field as non-nullable. So, if you are querying for ‘Student’, the server will return always non-nullable ‘name’, ‘age’ and ‘marks’.

In the above example, we have seen two scalar types ‘String’ and ‘Int’. GraphQL comes with the following default scalar types :

  • Int: Signed 32 bit integer
  • String : UTF-8 character sequence
  • Float: Signed double-precision floating point value
  • ID: Unique identifier
  • Boolean: true or false boolean value

GraphQL also provides us the option to create custom scalar types like below :

Arguments and Enumeration type:

The field of a GraphQL object can have zero or more arguments. The GraphQL arguments are named. For example :

In this example, ‘getMarks’ field has one defined argument ‘rollNo’ . This is a required argument. We can also mark an argument as ‘optional’ and provide one default value for that.

Enumeration type, also known as Enums are used to define a set of constant values like below :

i.e. for type ‘Grade’, we can have a type of ‘A’, ‘B’ or ‘C’. Different languages deal differently with enums in GraphQL. For example, JavaScript doesn’t support enum. So, enum values are mapped to a set of integers internally in JavaScript. These things are handled internally by GraphQL and we can use enums as String for all languages.

Query and Mutation type :

A query is used to fetch data from a GraphQL server and Mutation is used to modify (create, delete and update) data of a GraphQL server. For defining a query, schema definition language is used. The query and mutation types are similar to any GraphQL object types. For example :

The first example is a ‘Query’ type and the second example is ‘Mutation’ type.

List and Non-null :

Sometimes, the client may require only non-null values from the server. In GraphQL we can mark any type as non-null using the ‘!’ sign. Let’s take a look at the below example :

Here, we are expecting a ‘String’ type ‘name’ from the server. We have also marked it as ‘non-null’ by adding a ‘!’ sign to the end. The server will try to find a non-null value for ‘name’ and if it finds any ‘null’ value, it will inform the client that something went wrong. We can also use this non-null type modifier with arguments as well. If you use it with an argument, the client will have to deal with it. i.e. if any null value is passed, it will return one validation error.

We can also mark a type modifier as List by wrapping it inside square bracket ‘[]’ . It means the server will return an array of the type. For example ‘[String]’ means an array of String variables.

The list can also be used as an argument and we can also mark a list or its type as ‘non-null’.

[String!] means that the list can be null but it can’t have any null members.

[String]! means that the list can’t be null but it can have null members.

[String!]! means that the list can’t be null and also it can’t have any null members.

Interface, union and input types :

An interface is used to define a set of common fields. It is an abstract type and any other type can implement it. If a type implements an interface, it will have to include the fields defined by that interface. For example :

The above interface defines the common properties of a car. Any other type can implement this interface like below :

As you can see, ‘Audi’ type has implemented the ‘Car’ interface and it includes all the fields defined in the interface ‘Car’, but it can also add extra fields that are specific to the type.

A union type is used to represent multiple types that don’t need to have any common fields. For example, if our server can return any ‘Car’, ‘Bus’ or ‘Plane’ type for a specific query, we can define the return type as below :

We can also use Scalar types to create a union.

In our previous examples, we have seen how to pass a scalar value as an argument. But we can also pass complex objects as an argument in GraphQL. This is useful for mutation. If we are creating a new object, we can pass it as an argument.

The input type is defined with the keyword ‘input’ . For example,

It looks similar to the object ‘type’.

Validation and execution :

In GraphQL, all requests are validated first before executing them. An invalid request will provide a meaningful message to the user during the compilation time. GraphQL has few predefined validation rules and these rules are checked for each query. The GraphQL service validates a request when it is required. If a request is validated, the service will memorize the request and it will not change if it doesn’t change.

Once a query is validated, it will be executed on a GraphQL server. The server will produce one result JSON based on the request query and returns it. Each field of a GraphQL query is backed by a function called resolver function. When a GraphQL query is executed, the resolver function for each field will execute. The resolver function will check if it is a scalar value or not. If it is not a scalar and if it is an object, its included field resolver functions will execute. The process will continue until a scalar value is reached.

A resolver function of a GraphQL schema accepts four arguments :

  • obj: The previous object or the result returned by the previous parent resolver of the execution.
  • args: arguments provided to the field in the GraphQL query
  • context: This object is shared by all resolvers in a query. It holds important information like currently database access permission, logged in user details, etc.
  • info: Holds different information about the execution state of the query and schema details.

Tutorial Index:

  1. GraphQL Tutorial #1 -Introduction
  2. GgraphQL Tutorial #2 – Setting Basic Project in GraphQL
  3. GraphQL Tutorial #3 – GraphQL Components
  4. GraphQL Tutorial #4 – GraphQL Operations
  5. GraphQL Tutorial #5 – Introduction to Apollo GraphQL
  6. GraphQL Tutorial #6 – 51 Most Important GraphQL Interview Q&A

Add a Comment

Your email address will not be published. Required fields are marked *