Implementing GraphQL API In The Browser
This September, I gave a talk at WebExpo Prague explaining why and how we used GraphQL to reduce data fetching and improve the UI of the Showmax Video on Demand platform. I’ve put together some more technical details in this article so you can try it yourself.
Implementing Front-End GraphQL
We are using React as a view framework and we really like its component model that provides just the right amount of encapsulation so that while working on a particular part of the app we don’t have to keep the entire application in our brain’s RAM. Moreover we extend the “component” approach to our CSS styling solution — we use JSS to co-locate the components and their corresponding CSS styles while eliminating the problem of CSS class names clashes.
So when we first heard of GraphQL we immediately recognized an opportunity to extend the “co-location” approach even further by keeping the GraphQL queries/fragments close to the components that use them:
The example above uses Apollo GraphQL Client and its React integration. Besides the query co-location, by utilizing the power of GraphQL, ApolloClient provides some other cool features to your frontend app for free:
- Normalized model caching
- Optimistic UI updates
- Data resolving during server-side rendering
- Realtime subscriptions
Considering all this, we decided that we want to use GraphQL for our React app. But of course we didn’t have a GraphQL backend. So we started developing our GraphQL schema as a separate package that we were going to use in the client app as a data fetching layer.
Client-side GraphQL schema
One of the greatest traits of GraphQL is that it doesn’t dictate which communication protocol to use or how to resolve data in your schema. In other words, you don’t have to send your queries over HTTP and/or retrieve data for a response from a database. This is how your schema can look like if you want to use it from the browser:
In the root Query definition we declared one field, movieById, of type Movie. The trick that allows us to use this schema in the browser is in the resolve method. This method is used by the GraphQL executor to resolve data for a query in runtime. Because, as I mentioned above, there are no limitations on how you can implement it, you can use the browser’s fetch API to resolve data from your existing REST backend service.
All that is left to do to complete the integration for the app, is to configure your GraphQL client library of choice to use the locally imported schema instead of calling an HTTP /graphql endpoint. This is how such a configuration works for ApolloClient:
It’s just a matter of overriding the default implementation of the networkInterface and you can start leveraging the awesome API that GraphQL and Apollo provide in your application. Below, we use the movieById query that we defined in one of the previous steps to fetch Movie data in our MovieDetailPage component. The result is declarative and easily readable! Moreover, you can use a GraphQL query to generate propTypes for your components, specify different fetch policies which define how the cache is used in resolving data, enable auto-polling for a query, and so much more.
Try it yourself!
GraphQL definitely has some pros and cons, but I believe it has a good chance to replace REST as the de facto standard API paradigm. If you are as excited about it as we are, you might want to try to use it in your organization. My main message is : “Don’t be afraid to try!”
GraphQL is extremely well designed, so it allows teams to gradually adopt it while minimizing the disruption it poses to other colleagues’ work. I hope this article will help you on your way towards building great APIs in a modern way!
If you want to see more, We’ve created a GitHub repo that implements a working example of the client-side GraphQL setup that we covered in this article.
Watch the video
You can see the original talk at SlidesLive as synchronized slides and video, YouTube (video only), Slideshare (slides only). Let us know what you think at firstname.lastname@example.org.