Introducing GraphQL Concepts for Angular 8|7 Devs: Schemas, Resolvers, Queries & Mutations

In this tutorial, we'll teach you about the fundamental GraphQL concepts starting with an introduction and then explain the building blocks for a GraphQL API.

In nutshell, you'll understand:

  • What is GraphQL and why using it to build web APIs instead of REST,
  • What is the difference between a Schema-first-approach vs. a Code-first-approach,
  • What is a Schema and how to use it to define the structure of the data in your API,
  • What's a Schema Definition Language (SDL) and how can be used to define a Schema,
  • What's a builtin scalar type and how to use it to create object types,
  • What are object types and how they are used to define a Schema,
  • Root types such as queries, mutations, and subscriptions,
  • What's a resolver function,
  • How to map resolvers to fields in the root types of a Schema,
  • How to make executable Schemas to actually create a GraphQL API.

As far as Angular is concerned, you only need to know how to consume a GraphQL API not how to build it, but if you want to take it further, you can learn how to use Node.js to build a web API with our easy-to-follow tutorial.

Angular is not a server-side framework, so it can't be used to build web APIs with GraphQL but as an Angular developer, most often than not, you would need to consume an API which may be, very well, written in GraphQL as the technology became very popular in the recent years.

As a frontend developer, you are not required to know about server-side technologies like GraphQL but will definitively help you to better communicate with the backend team/developer if you know the fundamental concepts of GraphQL.

Note: GraphQL has been open-sourced and released as an open-source specification, so the GraphQL API server can be developed in any server-side programming language that you know including TypeScript (On top of Node.js).

What is GraphQL?

GraphQL stands for Graph Query Language.

The official website defines GraphQL as:

A query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

So, GraphQL is a query language (In the same sense as SQL is a query language) but not for databases, instead it's designed for querying data over the HTTP protocol and creating an API in the same way REST is used but with more advantages.

It's also a runtime that provides the actual mechanisms for processing the API queries and returning data and responses.

GraphQL allows you to provide a complete description of the data used in your application. As a result, clients will be able to query for the exact data that they need no less, no more. If you used REST before, you can imagine how powerful the GraphQL approach is.

GraphQL was originally created by Facebook and later open-sourced. Nowadays, more companies are using it ranging from IBM and GitHub to Twitter and PayPal.

Advantages of GraphQL

According to the official website, these are the advantages of GraphQL:

  • Ask for what you need, get exactly that.
  • Get many resources in a single request.
  • Describe what’s possible with a type system.
  • Move faster with powerful developer tools like GraphiQL.

Since you can describe the exact data that you need to fetch from your API server, you can send only a single HTTP request for multiple resources instead of many requests in the case of REST.

This means you'll have less network overhead and more performance.

When using REST, things may become tedious and error-prone for complex data requirements but with GraphQL, you can have nested queries which make it easy to get related data without trying to figure out how much requests you need to send and in what order. You may even end up failing to get the desired data if a proper endpoint is not present in the backend in the case of REST but not with GraphQL.

What is a GraphQL Schema?

A GraphQL schema is a fundamental concept around which you can build your API.

The first step of building a GraphQL API is the definition of the schema. You can consider a schema as a blueprint for all of the data that you can return in your API.

The schema describes the data types and the relationships between them. It also defines the possible queries that can be used to fetch data and what mutations can be used to create and update data.

A schema may contain types and their fields, queries, mutations, and subscriptions. a type can be either an object type or builtin scalar.

Additional information can be added as custom directives.

You need to include at most one schema definition when using the type system definition language.

In this example, a GraphQL schema is defined with both query and mutation root types:

schema {
  query: QueryRootType
  mutation: MutationRootType
}

What is an SDL?

GraphQL provides its own Schema Definition Language or SDL which provides an agnostic way to define a GraphQL schema no matter what programming language is used.

Schema-first-approach vs. Code-first-approach

You can write a GraphQL API in one of two approaches, a schema first approach or code first approach. The latter approach is more tied to a specific implementation provided by a programming language since you need to use code to define your GraphQL schema.

In a schema-first approach, we write our schema in the GraphQL SDL language and we call some methods to execute it. We then need to map resolvers (the methods that actually implement the queries and mutations) to fields. This is the leading approach in the GraphQL community.

In a schema-first approach, you write your data types, queries and mutations in the schema first then you add the implementation using resolvers.

This offers many benefits, for example, it allows frontend developers to start building the UI based on the schema before it's implemented by backend developers.

GraphQL Scalar and Object Types

In GraphQL, types are en essential concept. In fact, everything in the schema is a type even queries and mutations.

Queries, mutations, and subscriptions are called root types.

The basic elements of a GraphQL schema are object types, which define a type of object you can fetch from your API, and what fields it has. We create the object types out of the builtin scalar types.

GraphQL provides various built-in scalar types defined by the specification such as:

  • ID,
  • String,
  • Int,
  • Float,
  • Boolean

It also allows you to create object types for describing the structure of your data.

You can define a type using the type keyword:

type Employee {
  id: ID!
  name: String
  phone: String
  address: String
  emails: [String]
}

Employee is an object type, created using the builtin scalar types. It doesn’t provide any functionality except defining the structure or shape of our employee model in the application/database.

It's composed of fields. A field has a name and a type:

name: String

Note: In addition to scalar types, a field can use any other type defined in the schema definition.

You can make the field non-nullable by adding an exclamation mark, as follows:

id: ID!

You can define list fields using square brackets around the type:

emails: [String]

To implement the API, you will need to add fields to the root types (Queries, Mutations, and Subscriptions) of the GraphQL schema. These types define the entry points for the GraphQL API.

GraphQL Enums

An enum allows you to define a type that has a predefined set of possible values. For example:

enum Category {
  CAT1
  CAT2
}

GraphQL Interfaces

An interface is comprised of a list of fields and can be implemented by a GraphQL type which must have the same fields as the implemented interface:

interface Person {
  name: String!
}

You can use the implements keyword to implement the interface:

type Employee implements Person {
}

What is a GraphQL Query Type?

A GraphQL query is a root type that defines the shape of the queries that can be accepted by the API server. For example:

type Query {
  empolyee(id: ID!): Employee
}

This root type exposes an employee field that takes an ID and returns an Employee.

Note: The root types of a schema define the shape of the queries and mutations that will be permitted by the API server. This enables GraphQL to provide a concise contract for client-server communication.

What is a GraphQL Mutation Type?

Mutations are root types that are used to create, update or delete data. They are similar to the PUT, POST, PATCH and DELETE operations in REST APIs.

We use the Query root type to define the entry-points for operations used to fetch data and the Mutation root type to add the entry points for the operations to create, update and delete data.

For example:

type Mutation {
  addEmployee(name: String, phone: String, emails: String[], address: String): Employee
}

Here we add a single addEmployee mutation which accepts the name, phone, emails and address arguments (also called input types) and returns the created Employee object.

What is a GraphQL Resolver?

When you build GraphQL APIs, the process is centered around the schema. The process is generally as follows:

  • You create the schema definition,
  • And you implement the actual operations using the resolver functions.

GraphQL makes a separation between the structure and behaviour.

The structure is defined with the schema. You then need to write an implementation that provides the behavior of the fields in the root types. This is done with what's called a resolver function which needs to be provided for each field in the root types.

A question that arises is how to map the resolver functions to the fields?

This can be done in many approaches. In the code-first approach, you have objects that you can use to define fields and resolvers in the same place. See graphene-js or express-graphql for JavaScript.

In the schema first approach, you can't add resolvers directly in the schema, but you have various APIs (available from different packages such as GraphQL.js and graph-tools) to map the resolvers after defining your schema such as:

  • Using the buildSchema() method which is available from the GraphQL.js package,
  • Using the makeExecutableSchema() method of the graphql-tools package.

Conclusion

In this tutorial, we've introduced you to the fundamental GraphQL concepts such as: - Schemas, - Scalar and object types, - Queries, mutations, and subscriptions, - Resolvers.

We have seen the difference between the schema first approach and code first approach for creating GraphQL APIs. How you can make an executable schema using methods like buildSchema() and makeExecutableSchema() from the GraphQL.js and graph-tools packages.

About the Author

Techiediaries is a website dedicated to bring you tutorials for the latest web technologies


comments powered by Disqus
DMCA.com Protection Status