How to GraphQl, from Frontend perspective[Part I]
Hey, Did you dreamed one day as a Front end engineer to write your API response with yourself without a long conversation with the Back end engineer to agree on every API response schema?
FE: could you please retrieve the ID for me here? 👀
BE: oh, you need that, okay I will 👌
—
FE: did you change the API name? I got a not found on my request 🥴
BE: Oh, my bad yes it’s changed yesterday 🤦
No more discussions like that with GraphQl 🎇
What is GraphQl?
GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data.
How does it work?
Once a GraphQL service is running (typically at a URL on a web service), it can receive GraphQL queries to validate and execute. A received query is first checked to ensure it only refers to the types and fields defined, then runs the provided functions to produce a result.
Queries and Mutations
Queries are for getting data from GraphQl server like [get] method in Rest APIs
Mutations are for adding/modifying data to GraphQl server
like [post — put — delete] methods in Rest APIs
How to query?
Fields
GraphQL is about asking for specific fields on objects,
you could imagine it like a key in an object in javascript.
// [id - name - age] all of those called fields
query getEmployees {
employees {
id
name
age
}
}
Arguments
This is the ability to pass arguments to fields, which power GraphQl fetching functionality,
you could imagine it like passing arguments to functions in javascript.
// The argument is id: "2" to fetch single employee that match the given id
query getEmployees {
employees(id: "2") {
id
name
age
}
}
every field and a nested object can get its own set of arguments, making GraphQL a complete replacement for making multiple API fetches.
Aliases
You can’t directly query for the same field with different arguments. That’s why you need [Aliases] they let you rename the result of a field to anything you want.
query getEmployees {
NewEmployee: employees(type: NEW) {
name
}
OldEmployee: employees(type: OLD) {
name
}
}
Fragments
If you have two sections in your app page that have the same fields but with different types, here GraphQl introduces fragments it’s reusable units which let you construct sets of fields, and then include them in queries where you need to.
query getEmployees {
leftEmployees: employees(type: left) {
...employeesFields
}
rightEmployees: employees(type: right) {
...employeesFields
}
}fragment employeesFields on employee {
name
friends {
name
}
}
It is possible for fragments to access variables declared in the query or mutation.
variables are defined like that ($type: new)
you could also give it a default value ($type: new = ‘I’m a defualt value’)
query getEmployees($first: Int = 3) {
leftEmployees: employees(type: left) {
...employeesFields
}
rightEmployees: employees(type: right) {
...employeesFields
}
}fragment employeesFields on employee{
name
friendsConnection(first: $first) {
totalCount
edges {
node {
name
}
}
}
}
Inline Fragments
If you are querying a field that returns an interface or a union type — we will talk about these types in the next part of that series — , you will need to use inline fragments to access data on the underlying concrete type.
query getEmployees($type: Type!) {
employees(employeeType: $type!) {
__typename
name
... on OldEmployee {
leftYear
}
... on FullData {
height
}
}
}
GraphQL allows you to request __typename
, a meta field, at any point in a query to get the name of the object type at that point [__typename: “oldEmployee"]
.
Directives
If we can imagine a UI component that has a summarized and detailed view, where one includes more fields than the other, so we want here to retrieve data conditionally.
query getEmployees($withFriends: Boolean!) {
employees {
name
friends @include(if: $withFriends) {
name
}
}
}
So here if I send withFriends: true when I query it will return the friends array otherwise it will not return it.
The core GraphQL specification includes exactly two directives:
@include(if: Boolean)
Only include this field in the result if the argument istrue
.@skip(if: Boolean)
Skip this field if the argument istrue
.
Mutations
Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well.
Just like in queries, if the mutation field returns an object type, you can ask for nested fields. This can be useful for fetching the new state of an object after an update.
mutation addNewEmployee($name: name!, $age: age!) {
createEmployee(name: $ep, age: $age) {
name
age
}
}// The send data will be something like
const empolyeeData = {
"name": "Dina",
"age": 26
}
Conclusion
When we talk about GraphQL, we’re either referring to the language itself or its rich ecosystem of tools. At its core, GraphQL is a typed query language that allows you to describe your data requirements in a declarative way.
we talked about how to query and mutate the data, in part two we will go deep with GraphQl schemas and types …
We have a series of articles about GraphQl:
- How to GraphQl, from Frontend perspective[Part I]
- How to GraphQl, from Frontend perspective[Part II] …In progress
Thank you for reading, if you have any comments let me know, please :)
That’s all for today see you soon in my next story …👋