GraphQL wrapper for REST API

Apr 04, 2020

A reflection on using Apollo Server to make a GraphQL server for a REST API

With some time off given to us by Lambda School in wake of COVID-19, I spent last week learning GraphQL. This week, I made a GraphQL wrapper for PokeAPI to make a better version of my previous Pokedex with the existing REST API.

TL;DR check out the GitHub repo here or the GraphQL playground here

Motivation

If you know me, you know that I've been a Pokémon fan since I got my first GameBoy Color when I was 7. When I first learned React, I decided I was going to make a Pokédex as a side project because I didn't really like a lot of the options out there on the internet. I was excited when our redux project was to use whatever public REST API we wanted to make an app using redux. I found PokeAPI and became painfully aware of the limitations and frustrations associated with REST when there is a lot of interconnected data. Hitting endpoints just to find the endpoint I actually needed made my app much slower than I was happy with and I knew that GraphQL would be a better option for this use case. Unfortunately, I didn't know how to make a GraphQL server and Lambda School does not include it in the current curriculum...

With the craziness happening in the world as the COVID-19 pandemic continues, Lambda School gave everyone 2 weeks off while we all adjust and figure out our schedules and coping mechanisms for the next several weeks. Personally, my schedule wasn't impacted much as a stay-at-home mom of an 19 month old, so I decided to take advantage of this unexpected free time to learn GraphQL! My previous experience with GraphQL was limited to whatever I had gleaned from working with Gatsby on my personal site and some other personal side projects.

Learning GraphQL

I was unsure where to start for learning how to make a GraphQL server. I already understood how queries, schemas, and types work from my experiences with Gatsby, but I was at a bit of a loss with anything beyond that. My Lambda School Team Lead directed me to The Net Ninja's tutorial, so I started there. I completed that tutorial through to the end, while making changes along the way. React hooks didn't exist yet at the time the tutorial was made, so I refactored the project to use React hooks, particularly Apollo's useQuery and useMutation hooks. At the end of the tutorial, I had created a Node GraphQL server using express and mongoose to connect with a MongoDB database. On the front end, I used Apollo Client to connect React with my express server. The finished result was a basic site in which the user can create a book list and see the titles and authors of the books already in their list. However, as I neared the end of the tutorial, I realized that this method was probably an older, albeit still perfectly functional, way of creating a GraphQL server. For the sake of the learning experience, I stuck through it to the end as it helped me have a better understanding of what's going on under the hood a little bit more. As such, I didn't flesh out the booklist project to include more queries, mutations, and deletions, so I didn't bother deploying it. If you want to see my code, here's the GitHub repo.

Creating a GraphQL wrapper for REST

Now that I had a MUCH better grasp on using GraphQL, I dove headfirst into making my GraphQL wrapper for PokéAPI. Since this is a public REST API, I only have access to do queries, but no mutations or deletions. So that cut down on the complexity of the project. And thankfully I had already done a lot of the leg work in my previous redux project when I used PokéAPI, so I didn't have to reinvent the wheel when figuring out how to get all of the data in the shape that I wanted for my GraphQL schema. I defined my schema with the shape that I wanted to have the data for my front-end client. I used apollo-server to set up my server and apollo-datasource-rest for my queries to the REST API to take advantage of the caching, error handling, and deduplication that apollo-datasource-rest does under the hood. That way I could abstract out my resolvers for all of my fields to avoid overfetching. This also helped solve a previous issue I had (before I abstracted out all of the resolvers) with an infinite loop because of connected type relationships. I plan on breaking out my RESTDataSource component into smaller ones to make it more readable, but I'll come back to that when I get my client-side Pokédex app finished up. You can check out the server repo here and the deployed GraphQL playground here.

Plans for the client app

With my GraphQL server up and running, I am currently working on a Pokédex PWA built with Gatsby. Since Pokémon data doesn't really change, I am fetching all of the data and dynamically creating the pages for each Pokémon with all of their necessary data at build time. That way, when the app is fully deployed, the pages will all load incredibly quickly. So far, I have the queries running and pages being created great! Just working on the logic to display the correct data in the right places. I would like to use Theme UI for my styling and Framer Motion for my transitions and animations since I've only dipped my toes into them previously. I'm very excited about this project, so look for a future blog post when I have the front end completed! :)