 I'm Ramakrishna from Mindecle and today, let's talk about how GraphQL has affected front-end development. But before we begin, let me first ask you, as a front-end developer, what is the amount of time you actually get to write front-end, right? And by front-end, I mean, you know, actual UI components, like, selectable, right? So before you get to write HTML, JS, CSS, right, you have to get over a few complications. So one of the most important parts is you have to interact with the backend, right? It's not that simple. So let me show you what problems can occur and, you know, how GraphQL, adopting GraphQL, helped me in overcoming those problems. But first of all, what is GraphQL? So the docs say that it's a query language for your APIs, right? But it's not that clear, is it? It's all about connected data. So it's a graph. That's why GraphQL. So you traverse the data as you traverse a graph. Let's make it clear with the help of an example. But even before that, I'll be using some of the terms. So let's clear them out. Yeah. So this is one of the most important parts in GraphQL. This is the part which is publicly exposed as an API. And this is the schema which is used by the client. The client may be a web application or a mobile application, whatever. So resolvers have the duty of putting the data into the schemas. So resolvers connect with the actual backend, right? So GraphQL gives the ability to break your schema into small parts, which it calls as fragments. So we'll be discussing more about fragments a little while later. Directives give you a way which you can pass some more information to the GraphQL executor. For example, if for some reason you want to deprecate a field, you can just write at the rate deprecated in front of that field. And that field won't be publicly accessible in the documentation. And yeah. So these three parts, query, mutation, and subscriptions, these parts are the things that are publicly exposed. So querying is used for getting the data or reading the data. Mutations are used for making changes to the data. And subscriptions are used to subscribe to the data, similar to what we use in web sockets. So let's do a task. We have to get details of a Star Wars film. You have to get the details of its director. You have to show the extended details of the hero. So how do you do it using REST? So in REST, there are a bunch of APIs. So there may be an API for getting the film details, for getting the director details, for getting the characters by ID, and of course, the extended details if you want for the hero. So what do you do in GraphQL? First of all, you refer to the schema. So as you can see that there are some complex types here, like there's a type defined called film, character, and species. There are subfields for that type. So in GraphQL, everything should end with a scalar field. So by scalars, I mean string, integer, floats, et cetera. So some of the scalars fields are provided by GraphQL itself, and you can define your own custom scalars if you want some specific behavior, like, for example, date time. Then you write the query. So this is an interesting part. This is a single query in itself, and you can specify each and every field you want. I want the name release date of the film, the name of the director, name of the characters, and some extra information of the hero. I don't have to worry about the API calls now. So GraphQL has now introduced some new interesting features, like declarative way of implementation and strict typing. And some of these features have a direct impact. And some of them have a side effect. So let's first discuss the side effects that GraphQL has on the front-end ecosystem. So a little while ago, React came in, right? And it said that you should write your HTML and your JS in a single file, because, you know, that's what makes a pure component or a true component, right? And it made sense, because a UI interaction is not complete without its structure and, you know, the interactions, right? But it was not complete. So a couple of years later, some libraries came and said that, no, you should write the design as well in the component, like style components and emotion. It said that a design CSS should also be coupled with the component, and it also made sense, and it worked. But still, in my opinion, it's not a true component. So component is not complete unless and until it can specify its own data, right? So whenever you export a component, you export its HTML, its JS, and its CSS. But what about the data? It does not have any information, or it can't convey to its parent which data it requires, right? So how GraphQL has helped me in doing so? Fragments, right? So GraphQL gave me the ability to, you know, destructure or break my major type into smaller types. I have a director component, and I can define a fragment, which is director fields, and I can specify which fields I want or which fields this component wants. But still, this component still has no idea how to get those fields. This heavy lifting is done by the GraphQL server. It's a very declarative way in which this component has specified which fields it wants. So another thing was feature enablement. So in our organization, we follow trunk-based development. In trunk-based development, you create something and you merge it to master by the end of the day. So the problem comes that there are a lot of half-baked features which go into master. So what if you want to send a release, right? You would create a release branch, and you would not want to send those half-baked features to production. But the solution was here was that you cherry-picked those commits, right? But as a front-end developer, I do not want to spend my time cherry-picking those commits. Half of my time was going into it. And there were still some commits which are going into production because, as you know, the commits may have been wrong. So we decided to come up with something called feature enablement. We said that we should ship every code to production, right? And the environment will tell the code which features it wants enabled and which features it wants disabled, right? It worked well. It worked well for components which had only UI interactions. But there are also components which queried the data from the back-end, right? For example, this component, the director component. The director component is querying the director fields from the back-end, right? If I want to disable the director fields, I was able to disable the director component, but still the query was being sent. And that means more resources were being used. And maybe some error might have been creeping into the back-end systems. So we used the skip directive. So this disabled director fields was hooked up with the environment. And this was either true or false on the basis whether this field was required or not in that environment. So if this field is true, it means that the director fields would be skipped and no API calls were actually being made to query those director fields. And the component is made in such a way that if the field is not coming, the component won't be rendered. So this is the part which impressed me a lot about GraphQL. So let's say we have another task. We have to load a news section, right? It has a recommended section, and there are comments for every news. So we would call the first base API to fetch all the news. It would render the respective news section. Then we would lazy load all the comments and recommended section, et cetera. We'd render the respective components. And now make another call to fetch more lazy loaded components, right? And render the respective section. So this is a very simple process, right? It's a very linear approach, and it worked well using REST. But what if you want to change the lazy loading logic? Now, I wanted to make a blocking call to recommended section and lazy load everything else. Now, this meant a whole rewrite of the process. So GraphQL came up with something called differ. So in this query, you can see that if I want to differ some parts of my data, I can simply write at the rate differ, right? And create a big query and send it to the server. So in this case, the stories part which is not differed is a blocking call. And when it is resolved, it would be sent to the client. What about the rest of the data, right? The data is streamed to the component. So I have not written any part, any lazy loading part to manage the data which I want to lazy load. It's completely streamed to the client and it's completely configurable. If the product requirement comes that I have to lazy load some other parts of data, I can just write at the rate differ there. So this is a live example on the Apollo blog. It's implemented using at the rate differ. So the differ is actually in alpha phase right now. So it's expected to release soon. But still, this is now a complete change in the way we interact with the backend. Rest was stable. It was there for nearly 20 years. It's battle tested. Everyone uses it. And it's pretty standard, right? Is there really a need to change? So I think JavaScript, when it was first made, it was intended for static form validations and things like that. But now there are so much more complex experiences which the designers and the products want to give to the users. And JavaScript handles everything. So I think making a simple API call is not that simple anymore. Also, there is too much dynamic data, right? So maybe REST, which was designed in around 2000, is now maybe not able to scale up to the needs of complex frontends and dynamic data. So let's discuss some of the challenges which GraphQL helped me overcome, which I was finding trouble using REST, coupled systems. So as a front-end developer, we want to architect your app based on the UI interactions, not on the basis of these APIs, right? But more often than not, the backend gives you six APIs and you end up creating a component for each and every of those APIs. This should not be the case. As a front-end developer, architect your app based on the UI interactions only. The component should tell you which data does it require for that interaction. That's all. But coupling happens. You can't get away from it. How GraphQL solved it? Is it divided everything into two parts? So schema is made, maintained and consumed only by the product team, the front-end team and the design team, right? And the resolvers are mapped to the backend. This heavy lifting of mapping the resolvers and the schema is done by the GraphQL executor. GraphQL executor, for example, Apollo or Relay, right? There's clear separation of front-end and backend code. So if my design changes, I can simply update the schema. If the backend says that now I will revamp all the APIs, right? Just update the resolvers. There's no need to couple the systems now. Mocking. So whenever you start developing a new application or start developing a new project, you ideally have to wait for the backend to finish their development, right? And only then you can, you know, say that I'll start developing because before that there's no API ready. And, you know, they may be unstable. But still, there are timelines. So you end up creating mock data. So to, parallely, develop everything, you create a temporary replica of all the APIs, right? And you develop using those APIs. But still it's not scalable. So let's say there are 20 APIs. You won't be, you know, writing mock, mocking for each and every of those APIs for different structures, right? So the problem here is that it's not typed. I am not able to write a generic mocking framework which can, you know, scale for each and every API. For example, if there is a name field, I would not know whether that field would be a string, integer, float, etc. So GraphQL is inherently strictly typed. So all I need to do is to mock those scalars. So there are only n number of scalars which the backend can send, string, integer, or they may be custom. Let's say there are 30 scalars. So I mock the string type. And in my schema, every field which refers to that string is completely mocked. So this is, solution is provided out of the box by the Apollo server. Just pass in mock equal to true. And it mocks your entire schema just like that. So, yeah. This is one of the oldest problems in the book. So what happens is that backend creates generic APIs which are more or less bloated for front-end use cases. It happens when, you know, you use the same API for desktop and mobile. Mobile, you typically want to display lesser fields as compared to desktop. So you end up having fields which you don't require, right? So REST does not give you control. It was designed in such a way that, you know, the backend is modular and all, but it did not cater to the needs of the client. The GraphQL was made in such a way that the client had the control for querying what the client wanted and nothing else, right? Yeah. So this is, I think, a piece of software development that no one likes to do, right? And, yeah, including me. So I just want to write code. So the best part is it's self-documenting. So you write code and deploy it. And there are various tools available. You can attach middlewares and things like that. And you can play around with the schema. You can use GraphIQL. You can use GraphQL Playground. These are all open-source tools. And there are many more. So this is an example of the GraphQL Voyager. As you can see, the data is all connected. You can play around. There's descriptions. There are fields. There are types. And, yeah, no code is written explicitly for this. You just need to import GraphQL Voyager and that's it. Yeah. So where there is no documentation, there would be a breach of contract. And even if there is a documentation, there is no way you can, you know, possibly check whether you are querying the correct fields in REST, whether this field is available at the back end or not. There may be typos, right? So GraphQL is, again, strictly typed. There are lots of toolings available around GraphQL. There's an ESLint plugin which can run at build time to ensure that you are not querying anything which is, you know, not available at the server, right? And there are code gens available for generating typings, too, using TypeScript and Flow. This is only possible because of strict typing. So, yeah. So GraphQL enforced me to think in terms of front-end components. I can, you know, offload the heavy lifting of combining the front-end and back into the GraphQL server. So front-end is now a pure front-end for me. I got the power to, you know, get what I needed, nothing else. And, yeah, it's a completely decorative way. So now, as a component, a component does not need to know which API calls does it have to call. It just needs to specify the data. That's all. And, yeah, of course, self-documenting.