visit
Where do you keep your dad jokes? In a dadabase of course! Let's imagine that you are a site maintainer for the world's best dad joke database. Your app communicates with the database using a REST API that allows you to retrieve jokes and post ratings for those jokes. Visitors to your site can rate each joke they see via a simple user interface.
Recently you heard of a fancy new technology called GraphQL that provides the flexibility to request only the data that you need using a single API endpoint. It sounds neat, and you'd like to start using it in your app. But, you'd really prefer not to make any breaking changes to the existing REST API. Is it possible to support both the REST API and the GraphQL API in your app? You're about to find out!In this article we'll explore what it takes to implement a GraphQL API on top of an existing REST API. This strategy allows you to start using GraphQL in legacy portions of your app without breaking any existing contracts with functionality that may still rely on the original REST API.If you'd like to see the end result, you can find the and the . Don't forget to as well to groan at some jokes.You can test out our mock database by cloning the , running
npm install
, and then running npm start
. If you navigate to you'll see all of the jokes. Navigating to will display all the ratings./jokes API endpoint returns all the jokes when running the app locally
Wonderful! We can run our app's backend locally in the browser. Now let's get our API hosted on Heroku. First, we need to . After that, we can log in, create the app, push it to Heroku, and open the new app in our browser in four easy steps:# log in to your Heroku account
heroku login
# create the Heroku app
heroku create dad-joke-dadabase-rest-api
# deploy the code to Heroku
git push heroku master
# open the Heroku app on your machine
heroku open
/jokes API endpoint returns all the jokes when hosting the API on Heroku
The JavaScript is shown below. The key pieces that interact with the REST API are the two fetch requests. The first fetches all of the jokes from the database by hitting the
/jokes?_embed=ratings
endpoint. The second makes a POST request to the /ratings
endpoint to submit a new rating for each joke you rate.Dad joke "dadabase" user interface allows you to rate each joke
As you can see, we configure Apollo Server with type definitions (
typeDefs
), resolvers
, and dataSources
. The typeDefs
contain the for our GraphQL API. In it, we'll define types for our jokes and ratings as well as how to query and mutate them. The resolvers
tell the server how to handle various queries and mutations and how those link to our . And finally, the dataSources
outline how the GraphQL API relates to the REST API.Here are the type definitions for the
Joke
and Rating
types and how to query and mutate them:The jokes data source defines methods for calling the original REST API endpoint to create, read, update, and delete jokes from the database:The ratings data source looks nearly identical, but with "rating" substituted for "joke" in every instance. ( if you'd like to see the code for this.)Finally, we set up our resolvers to show how to use the data sources:With that, we have everything in place we need in order to start using our GraphQL API through Apollo Server. To get our new frontend and GraphQL API hosted on Heroku, we'll create and deploy a second app like so:# create the Heroku app
heroku create dad-joke-dadabase
# deploy the code to Heroku
git push heroku master
# open the Heroku app on your machine
heroku open
We can run the app locally now and verify that the user experience still works properly. In fact, from the user's point of view, nothing has changed at all. But if you look at the network requests in your browser's developer tools, you'll see that we're now fetching our jokes from the
/graphql
endpoint. Amazing!The Network tab shows a request is being made to the /graphql endpoint now
A quick test gives us some promising results. Once again, the user experience remains unchanged, but now we're fully using the
/graphql
endpoint for both our requests!Previously published at