DEV Community

Prashanth Krishnamurthy
Prashanth Krishnamurthy

Posted on • Originally published at techformist.com on

What is GraphQL and why I should use it?

Why do I use GraphQL? Also, the case for not using GraphQL.

You must have seen the previous post where I waxed eloquent about how I mess up my Rest APIs. There was no way I would be satisfied doing that to a single technology stack.

Ergo, GraphQL.

What is the need for GraphQL?

Google GraphQL and refer docs- there are smarter people with better answers than me.

But, since the Internet can be a scary place and I love to write about things that I am not an expert in - here's a gist about what I think.

Back to the story..

GraphQL is the SQL for APIs.

Before you say .. 'ah.. I now know everything!', read on.

You see - most of the transactions on the web involve fetching some data or the other.

Clients need to be authenticated, authorised and then request data for those transactions to happen. Servers, which supply the data, will comply with client requests based on pre-defined rules.

Rest is an architectural style that allows you to standardize and streamline client-server requests. You can control resources (accounts, contacts etc.) and the operations (GET, STORE etc.).

So far so good. You may even think that you reached a Nirvana state with what has been described so far, but imagine what would happen if you start a series of requests -

You: Give me contacts
Server: Here are 100 contacts with 501 fields per contact

You: Give me contacts and activities for each contact
Server: Here are 1000 contacts and 1 million activities per contact

You: Give me contact detail
Server: Here you go - 1000 fields of the contact
You: Give me address for the same contact
Server: Oh God, you again? Here's the address. And, can you please stop this madness?
Enter fullscreen mode Exit fullscreen mode

You will see such examples in the real world - the problems described are referred as 'over-fetching' (getting more data than I need) and 'under-fetching' (getting less data than I need).

The properties of over-fetching -

  • server fetches more data from database (or may query for related entities that are not always required)
  • more data is pushed through the pipe
  • client gets more data than required and has to process data to selectively pick and display data.

And, those for under-fetching -

  • client does not require all data in one-go, requests for related entities or fields
  • additional network requests and more needless traffic
  • more time to render UI with complete data

The back & forth between server and client frustrates the server - as seen in above conversation, and more importantly, impacts client-side performance.

The multiple back & forth requests make Rest "chatty".

Ergo, GraphQL.

(I assure you - Matrix has very little to do with me using 'ergo' all the time.)

But really, why do I use GraphQL?

I certainly do not use GraphQL because it -

  • is the in-thing in web development today
  • is revered by everyone who say there is nothing more wonderful
  • is typed, and that makes it so magical
  • provides a really good looking IDE that makes it so easy to develop the queries
  • makes services so easy to code (all it needs is a gesture and all the little thingies arrange themselves in perfect harmony)
  • drastically reduces chatty network traffic and improves the speed to 'burn rubber' levels even before ignition is turned on
  • uses in-built security rules that makes it so easy to provide role-based authorization
  • is loved equally by server and client tech stacks
  • specifies a good abstraction layer for databases
  • has subscriptions and those are so so amazing
  • is developed by Facebook. I happen to adore Zuckerberg

Or, I may be using GraphQL for a couple of points mentioned above and that is embarrassing to admit (or downright stupid).

The primary reasons for me to use GraphQL are -

  • it reduces work on the server-side (surprise, surprise!?). I do not have to write APIs for each and every request, or over-engineer APIs imagining all possible scenarios. Since most of my services are data-heavy, I particularly like the fact that I don't need to maintain a dozen end-points
  • development iterations are easier on client. I can make adjustments to client code to fetch more or less data
  • pass only the required data b/w client and server

But, on the other hand -

  • GraphQL makes it harder to code server-side services (that is just me, not the fault of GraphQL per se).
  • I also find it harder to control the queries that clients request while they snicker in the background (the developers of the said client, not client-users. Since I am the only developer in many of my applications, I snicker to myself about myself. I need help!).

I find it easier to just enable standard Rest pattern to start with (scaffolded most of the time). Then, I start enabling GraphQL services for specific transactions and go from there.

Err.. what are you even talking about?

Let's see a few examples.

If I need to get a specific contact, I would do the following transaction in REST -

GET https://api.com/contact

Enter fullscreen mode Exit fullscreen mode

The response will be -

data: {
  contacts: [
    {
      planet: "earth",
      name: "Rama",
      age: 42
    },
    {
      planet: "mercury",
      name: "Kris",
      age: 21
    },
    {
      planet: "mars",
      name: "Joe",
      age: 63
    }
  ];
}
Enter fullscreen mode Exit fullscreen mode

I can do the following in GraphQL and send it as a POST request to server -

query {
  contacts(name: "Rama") {
    name
    age
  }
}
Enter fullscreen mode Exit fullscreen mode

The response will be like so -

data: {
  contacts: [
    {
      name: "Rama",
      age: 42
    }
  ];
}
Enter fullscreen mode Exit fullscreen mode

The responses in the two transactions speak for themselves!

What are GraphQL operations? And, why should I care?

No matter what we do in the client-server world - we are trying to do one simple thing -

Share data and business logic b/w server and client

One can query, insert, update or delete data and can initiate those transactions from client. This can either happen -

  • with the server not caring about the "state" of the client. i.e., client sends request (with authentication incl. as part of request if required), and server answers the call
  • server keeps client interests in mind, has an open channel with the client, and keeps track of data so that clients get changes as they happen

GraphQL builds a layer on top of a database to assist you to transmit data in both cases.

Query

GraphQL queries help you to fetch only the records and attributes you need - we have seen examples earlier.

You can also include different entities (think 'tables' as an analogy) in the request. Use GraphQL to fetch records with specified relationships, rather than making separate requests for distinct entities.

Mutation

GraphQL mutations are used to insert/change data.

mutation createContact {
  addContact(name: "Joe", age: 100) {
    id
  }
}
Enter fullscreen mode Exit fullscreen mode

The above query provides instruction to use a mutation called createContact that in turn uses addContact to add a contact record with name Joe and age 100.

Subscription

Subscriptions establish a channel between server and client. Clients can subscribe to record updates and get notified (through a simple notification, or by actual 'push' of the data from server) whenever there are changes.

Subscriptions use 'web sockets' under the hood. This is a battle-tested piece of technology that enables real-time data updates to client.

For example - clients can use the below subscription to get the list of contacts who won the lottery.

subscription listenWonLottery {
  wonLottery {
    name
    deals
  }
}
Enter fullscreen mode Exit fullscreen mode

Let's see the flow -

  1. Clients subscribe to contacts
  2. One or more of the contacts get updated in the database when they win lottery
  3. On database update, a notification gets triggered to clients
  4. The notification contains contact's name and deals associated with contact
  5. Client can thereon show a popup with contact name and show flying balloons for effect

What are the different components required to implement GraphQL?

GraphQL is just the language for API and runtime for executing them queries. It is not hardwired to database and does not specify how the database operations need to be executed.

The different components that implement GraphQL stack are below. These components are not part of GraphQL specifications but are just part of the stack that support transactions using GraphQL.

Server

The implementation/tech stack decides how GraphQL is incorporated in the transaction. Server receives GraphQL requests from clients, establishes connection to database, converts graph queries to a language understood by database, fetches results and sends the responses back to clients.

A server may also include the functions expected from a "normal" server -

  • apply business logic to data
  • listen to supported types of requests on specified network ports
  • takes care of all the supporting infrastructure required to serve requests to clients.
Database

Stores data and maintains atomicity, consistency etc. etc. for data. It is a glorified file system that supports individual transactions and does not mess up the data just because the network went kaput, or your client decided to play a game.

Client

Can be a browser, mobile app or anything that requests data from server and consumes server response to do "something". We create GraphQL queries, mutations etc. and send them over in a simple POST request.

What are the terms that I should be familiar about?

Schema

A schema is the building block of GraphQL. It is described using a language that we can understand - it can be any language, but a simple option aptly named "Schema Definition Language" is used in the standard implementation.

Consider the below example -

type Contact {
  name: String
  deal: Deal
}

type Deal {
  description: String
  value: String
}
Enter fullscreen mode Exit fullscreen mode

The schema definition helps a client-side developer to see and understand the relationships b/w data entities, and thereon construct a GraphQL query.

Resolvers

A resolver is a function that returns data in the shape specified by schema.

For e.g. -

const resolvers = {
  Query: {
    contact(root, args) {
      return contacts.filter(contact => contact.id === args.id)[0];
    },
    deals(root, args) {
      return deals.filter(deal => deal.id === args.id)[0];
    }
  },

  Contact: {
    deals: contact => {
      return deals.filter(deal => deal.contactId === contact.id);
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

We use a resolver to write queries, mutations and subscriptions.

Object type / fields

In the GraphQL query outlined above -

  • Object type is 'Contact' and 'Deal'
  • Fields are name, description, and value

This is so cool that I slept through the article. Give it to me straight - should I use GraphQL?

Not everywhere.

Use GraphQL when you need to fetch a lot of data having varying shapes / many relationships. Use GraphQL to simplify the data passed between client and server.

At the same time -

  1. Remember that plain Rest API implementations are simpler
  2. Even in data-heavy applications, I do not see a big advantage of applying GraphQL everywhere (except architectural uniformity/ standardization, maybe). For e.g. if you have narrow relationships between entities that do not require related data views all the time
  3. Keep track of how clients use GraphQL - crazy queries can lead to performance issues

Why do I find Rest services simpler?

  1. Endpoint setup is simple on the server. Expose an API or two, and use an ORM to fetch/update data in one or two steps - no sight of fields and related entities anywhere unless you want to deal with them
  2. In addition to the previous point, or supplementing it, is the fact that the tooling is amazing - the technology is so old and supported so well that most of the time it just requires a couple of clicks (or lines of code) to fully set up
  3. I control queries in the back-end - easier control on who accesses the data and how. I also find it easier to solve potential performance issues since I control filters and sort on the server
  4. But all said and done, I may be finding Rest easier since I have spent so much time with it :)

Ok, I am in. Where should I start?

I find the following technology stacks easy to follow and useful to learn for the long run. The recommendations are skewed towards Vue since I use Vue all the time and strongly believe that Vue is easier on beginners.

Enable GraphQL server-side

It is a good idea to create a server on your own and see GraphQL flow in the back-end for real.

Category Recommended Remarks
I know SQL and understand DBs PostGraphile Refer this
I want to learn more of serverless AppSync Sign up for 1-year limited free servers on Amazon AppSync
I want to learn GraphQL using a CMS StrapiJS In beta, but good for production
I want to experiment with static sites + GraphQL Gridsome New, but promising.
I know PHP Laravel + Lighthouse
I am looking forward to a long-term relationship NestJS Good server capabilities + good GraphQL
I am a master Guide me towards enlightenment, maybe What are you even doing here?
Use GraphQL on the client

Also see: create a simple to-do with Svelte + GraphQL

Finis

It ends here :)

Top comments (9)

Collapse
 
tehmas profile image
Asad Raheem

Thanks for the article.

How are you defining data-heavy applications? Is it an application that is receiving/processing/sending millions of data points per second or is it actually the one with a highly normalized database schema?

Collapse
 
prashanth1k profile image
Prashanth Krishnamurthy

That's a good question.

I am referring to high no. of data points = high no. of fields / highly normalized schema.

Sorry for not being clear.

Collapse
 
tehmas profile image
Asad Raheem • Edited

Thanks for clearing out.

It would be great if you can elaborate on the following point as well:

Remember that plain Rest API implementations are simpler

Thread Thread
 
prashanth1k profile image
Prashanth Krishnamurthy

I intended to recommend GraphQL for databases that have many fields and/or relationships.

"..
Since most of my services are data-heavy, I particularly like the fact that I don't need to maintain a dozen end-points".

GraphQL enables selective retrieval and that (for me) is a big plus.

Obviously I am not a good communicator :p

I would like to answer your second question in more detail and have updated the post!

Thanks for the great questions.

Collapse
 
u_cancall_me_rj profile image
RJ-1998

I don't know why everybody thinks that Graphql can only be used in case of web development API. There can be more useful things you can do with Graphql. One of the things that I see is that it's a "query language" like SQL. You can query a big amount of data just like SQL does on a large database. Consider this, suppose you have a json data of about 13M lines,what would you do with that? Well, use Graphql and seperate the necessary data out, and apply Machine learning to that data!

Collapse
 
prashanth1k profile image
Prashanth Krishnamurthy

Agreed. We will see more such applications as the tooling support becomes more prevalent.

Collapse
 
aliendreamer profile image
Teodor Stefanov

Аnother useless writeup for Graphql.. I mean I had to learn it recently. And it is overenginered too complex and tries to do something js is not good and not supposed to do. In rest api I can open a route to give you your contract by id and it is easy.
While in graphql I have to write schema! then I have to write types. Then I have to write the actual query. Not to mention I have to hack it a bit to use more then one query or mutations in one react component for example. And if I want to mutate this contract I have to write a mutation. And if I do it with rest api I just have to open a put request endpoint and that is.

Collapse
 
prashanth1k profile image
Prashanth Krishnamurthy

I am sorry you feel that way (about the writeup not about GraphQL 😁).

GraphQL solves some specific issues but is obviously not a tool to be applied everywhere.

Writing schemas and doing elaborate setup can be minimized by using tools like TypeORM, Prisma, or using a tech-stack like Hasura or PostGraphile.

Collapse
 
theuserll profile image
L.L.

Great article! Well explained for a beginner like me. Thanks a lot :)