This blog is a part of a series on GraphQL where we will dive deep into GraphQL and its ecosystem one piece at a time
In the last blog post, we explored the various questions one might have when starting off or working with the GraphQL ecosystem and answered them. Now that justice has been done to clear the clouded thoughts you might have, let's dive into the next important step in this blog.
In this blog, we will start looking at how your architecture can look like when working with GraphQL and its ecosystem.
Your architecture hugely revolves around your usecase and you have to be very careful in getting it right and take proper consultation if needed from experts. While it is very important to get it right before you start, mistakes can happen, and with a lot of research happening these days, you can often find any revolution happen any day which can make your old way of thinking obsolete.
That is why, I would highly recommend you to Architect for Change and make your architecture as Modular as possible so that you have the flexibility to do incremental changes in the future if needed. Let's just talk about architecture in context with GraphQL here. We will explore more deeper into the rest of the architecture in an another blog post.
There are some things you would have to think of before starting your journey.
This list is incomplete. There are more questions like these which you might want to answer yourself and answering this can give you a lot of clarity as you start building your architecture.
The Ingress / Load Balancer
This is the first layer that any client would typically hit before making requests to your GraphQL service. This acts as the single entry point for all traffic (it can be regional as well depending on your usecase).
This would be the first thing you would have to setup before getting started and this is also the layer which handles things like SSL termination, caching (in case you have a CDN setup) and so on.
The API Gateway
The first thing would be the entry point of all your GraphQL requests. Since GraphQL exposes a single endpoint eg.
/graphql this becomes the single entry point for all your operations.
But, I highly wouldn't recommend directly exposing your service to client since it can be unsecure, difficult to manage things like rate-limiting, load balancing and so on.
Rather, it is always recommended to expose it via an API Gateway of your choice. Be it Ambassador, Kong, WSO2, Apigee or anything else for that matter. This can also act as sort of a kill switch or can also be used for things like filtering and moderating traffic whenever needed.
The GraphQL Gateway
As you evolve, you might end up having multiple services or might even move to the microservices world to enable scale. Now, this means multiple services with its own GraphQL schema, logic and so on.
But unlike REST, GraphQL exposes a single endpoint irrespective of the underlying services. This is where a Gateway plays a major role and comes in at the next layer of our architecture. The role of orchestrating or composing (both are different) multiple services and schemas together, delegating queries and mutations to the respective microservices and all of this without the client having to worry about the complexity underneath.
While you may choose to go for different architectures like Schema Stitching or Federation depending on your usecase, do remember that sometimes, this may be an overkill. You might not even need a GraphQL Gateway to start with if you are building something small and this can reduce a lot of complexity.
The GraphQL Service
The next thing to think of would be the GraphQL service itself (be it a monolith or microservice). Each service would be responsible for a part of the complete data graph as seen in Federated Implementation and this will make things easier to scale. Note that the way you implement it can be different as discussed (Schema Stitching or Federation).
You might also want to modularize your project structure and code within the service and this is applicable irrespective of whether you use a monolith or microservice to maintain clear separation of concerns, make everything composable and modular as possible.
While you can end up discovering your own way to do it (I initially went down this path), but what is the use of re-inventing the wheel when you have something like GraphQL Modules which can help you with this.
You might also want to get your tooling right to reduce as much work you do as possible. Be it linting and validation, code generation, testing, and so on so that you automate most of your workflow and you stay productive while working on any part of the service.
The Mode of Communication
Now that you have thought about the service(s), you might also want to think about the mode of communication in between them which is essential to pass data to and fro, synchronously and asynchronously. This also presents some questions which you might want to answer first before starting.
Again, all of these depend on your usecase and hence, there is no definite answer to this. But, try to go for a protocol which offers you less latency, great compatibility with built in support for things like compression, encryption and so on.
This matters cause while all the clients would communicate with the GraphQL endpoint you expose, you still would have to have some sort of efficient way to do inter-service communication.
Even if you are going to communicate between your service with GraphQL (which is what I do), you still have to decide how you transmit the GraphQL queries and mutations in between them.
Authentication & Control
Like we discussed in the previous blog post, there are various ways to do authentication and authorization. You might want to consider them as well while architecting cause this will decide how chatty your services will be when doing operations, how secure will it be, and so on. There are various ways as we spoke about, both stateful and stateless. While stateless would be better for scalability, you might want to choose what works best for you.
Depending on your usecase, you might also want to decide if you need something like persisted queries or not. This can prevent clients from sending queries which are not authorized, prevent huge amounts of GraphQL data from being passed over the wire, and so on.
And then comes the backend which you are going to use to store/retrieve data from. There are a huge number of options out there and to be honest, there is no one database which fits all usecases. And they even come with different variants — SQL, NoSQL, Search, Time Series and even Graph Databases. You can refer DBEngines for a complete list.
You might also want to look at how you minimize the amount of calls you make to the main database. Do you need caching and have it setup? Have you addressed the N+1 problem with Dataloader?
Now, there are a lot of other things you might want to have in your architecture like Hybrid Cloud support, CI/CD pipelines, caching and so on. We will probably explore them in future blog posts as we go along.
Remember to keep your stack as simple as possible and you can incrementally have them setup as you go along.
Deciding the “Right” Stack for “You”
Before I pick any tool or technology as part of my tech stack, I do ask a set of questions which help me better judge and make an informed decision on what I want. Probably it might help you too. This applies not just to the GraphQL ecosystem, but anything you choose for that matter.
While not all of these questions might have been addressed by the library or tool well, what I see is atleast the intent to address them in near-time.
While most of the things in this blog may not be related to GraphQL itself, these are some things which you need to keep in mind before starting your journey with GraphQL. In the next blog, I will show you how my GraphQL Tech Stack looks like as I use it to build Timecampus and we will dive deeper into each layer of the stack, one piece at a time.
Hope this was informative. Do let us know how you prefer to architect with GraphQL in the comments below and we will be happy to know more about it.
If you have any questions or are looking for help, feel free to reach out to me @techahoy anytime.
And if this helped, do share this across with your friends, do hang around and follow us for more like this every week. See you all soon.
Want to hear from us when there's something new? Sign up and stay up to date!Recent issues of our newsletter