Developed by Facebook in 2012, GraphQL has rapidly become one of the most popular query languages for APIs nowadays. Even though it was created for internal use only, Facebook has realized the importance of GraphQL becoming open source in 2015.
Mobile applications often have difficulties with slow network connections, and that is when GraphQL becomes helpful. Using GraphQL allows you to fetch all the data that you need with only one request and more importantly you get exactly what you ask for. The fact that it can be used with any backend framework and programming language, makes it an excellent choice for every application.

Querying a GraphQL server
There are three types of operations that define the interaction with the data in your GraphQL server:
- queries
- mutations
- subscriptions.
Queries
Defined by a keyword query, they are used to fetch data from the server. Their structure usually includes query name, fields you want to fetch, and arguments. The result has the same shape as the query itself. They can refer to a field, but also to an object. Fields can have zero or more arguments which can be of different types. Unlike mutations they don’t cause side effects on the server.
query ListCountries { countries(filter: { name: { regex: "^S" } }) { name capital emoji } }
{ "data": { "countries": [ { "name": "Saint Barthélemy", "capital": "Gustavia", "emoji": "🇧🇱" }, { "name": "Switzerland", "capital": "Bern", "emoji": "🇨🇭" }, { "name": "Spain", "capital": "Madrid", "emoji": "🇪🇸" }, { "name": "South Georgia and the South Sandwich Islands", "capital": "King Edward Point", "emoji": "🇬🇸" }, { "name": "Saint Kitts and Nevis", "capital": "Basseterre", "emoji": "🇰🇳" }, { "name": "South Korea", "capital": "Seoul", "emoji": "🇰🇷" }, { "name": "Saint Lucia", "capital": "Castries", "emoji": "🇱🇨" }, { "name": "Sri Lanka", "capital": "Colombo", "emoji": "🇱🇰" }, { "name": "Saint Martin", "capital": "Marigot", "emoji": "🇲🇫" } ] } }
Mutations
Defined by a keyword mutation, they are used to make changes on the server. They allow you to make data modifications, by either inserting, updating, or deleting the data. The structure generally includes the mutation name, input arguments, and the fields you want to return after the mutation is performed.
mutation { addCountry(name: "New Country") { id name } }
Subscriptions
Defined by a keyword subscription, they are used for real-time data updates. They allow a client to subscribe to a specific event or data change. Typically they use web sockets for communication. They are crucial for applications requiring live or dynamic data, such as chat applications, notifications, live sports scores, etc.
Subscription workflow:
- The client subscribes to a specific event using a subscription operation
- The server detects an event (such as a data change) that matches the subscription criteria
- The server sends the updated data to all subscribed clients
Types in GraphQL
GraphQL is a strongly typed language, every query has its own set of arguments which can be of many different types.
Object types and fields
The most basic components of GraphQL schema represent a collection of related fields. They are used to define entities in your schema and the relationships between them.
type Person { id: ID! firstName: String! lastName: String! age: Int }
Scalar types
Default scalar types in GraphQL are:
- Int: A signed 32‐bit integer.
- Float: A signed double-precision floating-point value.
- String: A UTF‐8 character sequence.
- Boolean: values are either true or false.
- ID: The ID scalar type represents a unique identifier.
GraphQL also allows you to define custom scalar types using a keyword scalar.
scalar NewScalarType
Lists, interfaces, and non-nulls
List type represents an array of certain types. They are denoted using square brackets [ ]. Interface is an abstract type that includes a certain set of fields that a type must include to implement the interface. Non null type indicates that a field cannot be null. They are denoted using exclamation mark !
Enums and union types
Enumeration types also called enums are a special kind of scalar that is restricted to a particular set of allowed values. GraphQL service implementations in various languages will have their own language-specific way of dealing with enums. Union types are used to define a new type that lists out the different possible object types it can resolve to. They are similar to interfaces but they don’t define any common fields.
Validation
GraphQL uses a type system to check if a query is valid or not. It can be implemented at various stages of the GraphQL workflow, including during schema definition, query parsing, and query execution. The are three types of validation in GraphQL:
- Syntax validation- ensures that schema follows grammar rules, which includes a correct syntax for fields, arguments, operations, etc.
- Semantic validation - verifies semantics of GraphQL documents against a GraphQL schema, and ensures that fields, arguments, and types are valid according to the schema definition.
- Input validation - validates input data provided in GraphQL mutations against predefined rules like data types, required fields, etc.
query { countries(filter: { name: { eq: 1 } }) { name capital emoji } }
⚠️ Error:
Argument "filter" has invalid value {name: {eq: 1}}. In field "name": In field "eq": Expected type "String", found 1.
Execution
After the process of validation, a GraphQL query is being executed by a GraphQL server. The result of execution is typically a JSON, but it can also be XML. Each field in the GraphQL query is backed by a resolver function.
Resolver function typically has four parameters:
- parent- return value of resolver for a parent field
- args- argument passed to the field
- context- value which is provided to every resolver, contains important context information
- value- holds field-specific information relevant to the current query as well as the schema details
There are a couple of different types of resolvers:
- Asynchronous resolvers - typically communicate with the database, and execute operations on it
- Trivial resolvers - return data that is already available, such as fields of an object
- Scalar coercion- GraphQL can coerce scalar values returned by resolvers to match the expected type in the schema
- List resolvers - resolvers can return lists of values, which may include lists of Promises. GraphQL waits for all Promises to resolve before proceeding.
GraphQL vs RestAPI
GraphQL and REST API are two popular paradigms for building APIs, each with its own strengths and use cases.

Similarities
- Sharing the same architectural principles
- Using HTTP as a transport layer
- Using the standard data formats for communication (JSON, XML, etc)
- Able to be extended with middleware to add functionalities like logging, caching, and authentication.
Differences
- GraphQL enforces the use of schema, unlike RestAPI
- RestAPI is still the most popular standard for building APIs
- GraphQL only uses the 200 status code for all responses
- GraphQL has built-in support for introspection, whereas for RestAPI you have to use specifications like OpenAPI or AsyncAPI
Advantages and disadvantages of GraphQL
Some of the benefits of GraphQL have already been mentioned in this article - accessing data with a single endpoint, flexible data retrieval, network performance, and built-in introspection. GraphQL APIs are self-documenting due to their strongly typed schema. This schema provides clear and detailed documentation of available data types and relationships, making it easier for developers to understand and use the API. GraphQL APIs can evolve without versioning. New fields and types can be added without impacting existing queries, allowing for seamless API evolution and reducing the need for managing multiple API versions
However, the learning curve of GraphQL can be quite challenging, compared to other alternatives. It requires a good understanding of its schema and query language. Maintaining the GraphQL schema can become complex, especially as the API grows and evolves. Implementing authorization and authentication in GraphQL can be more complex compared to REST, as each field and query may require specific access controls. The introspective nature of GraphQL can expose the entire schema to clients, potentially revealing sensitive information if not properly secured.
Conclusion
GraphQL presents a modern and efficient approach to API development, offering several advantages over traditional APIs. Its ability to allow clients to request precisely the data they need reduces unnecessary data transfer and improves overall efficiency. This flexibility, combined with a strong typing system and versionless API approach, fosters clearer communication between clients and servers and reduces development overhead. However, GraphQL does come with its challenges, including a learning curve for developers accustomed to RESTful APIs, complexities in caching and server implementation, and potential issues with over-fetching data. Despite these challenges, GraphQL's benefits make it a compelling choice for projects that prioritize performance, flexibility, and streamlined data retrieval. See you in our next blog with a new topic!
