2. Exploring our data
3m
You're currently on an older version of this course. View course changelog.

Now we know more about the journey a takes from client to server and back. Let's use this newfound knowledge for our Catstronauts app.

First, let's ask ourselves a few questions:

  • Where is our data stored, and how is it structured?
  • Is that structure different from our client app's needs and schema?
  • How can our functions access that data?

The data that retrieve can come from all kinds of places: a database, a third-party API, webhooks, and so on. These are called data sources. The beauty of is that you can mix any number of to create an API that serves the needs of your client app.

Hand-drawn illustration depicting a GraphQL server retrieving data from data sources such as a database, REST API and a web hook

Where is our data stored?

We'll be using a REST API located at https://odyssey-lift-off-rest-api.herokuapp.com/.

Screenshot of the documentation for the Catstronauts REST API

Looking at the API documentation, it looks like there are 6 endpoints available:

GET /tracks
GET /track/:id
PATCH /track/:id
GET /track/:id/modules
GET /author/:id
GET /module/:id

How is our data structured?

The next question we need to figure out is how our data is structured in our REST API. This impacts how we'll need to retrieve and transform that data to match the in our schema.

For our current feature of displaying tracks on the homepage, let's start with the /tracks endpoint. To test this endpoint from the REST API documentation, we can click Try it out and then Execute.

Screenshot identifying the Try it out button for the tracks endpoint of the Catstronauts REST API
Screenshot identifying the Execute button for the tracks endpoint of the Catstronauts REST API

We get a JSON response back:

[
{
"id": "c_0",
"thumbnail": "https://res.cloudinary.com/apollographql/image/upload/v1730818804/odyssey/lift-off-api/nebula_cat_djkt9r_nzifdj.jpg",
"topic": "Cat-stronomy",
"authorId": "cat-1",
"title": "Cat-stronomy, an introduction",
"description": "Curious to learn what Cat-stronomy is all about? Explore the planetary and celestial alignments and how they have affected our space missions.",
"numberOfViews": 0,
"createdAt": "2018-09-10T07:13:53.020Z",
"length": 2377,
"modulesCount": 10,
"modules": ["l_0", "l_1", "l_2", "l_3", "l_4", "l_5", "l_6", "l_7", "l_8", "l_9"]
},
{...},
]

The response includes an array of tracks, which is a good start. Let's see in more detail what matches, referring back to the Track type in our :

type Track {
id: ID!
title: String!
author: Author!
thumbnail: String
length: Int
modulesCount: Int
}

The array includes properties that we need in our homepage Track Card:

  • id
  • thumbnail
  • title
  • modulesCount
  • length

The array also includes a bunch of stuff we don't need for now:

  • topic
  • description
  • numberOfViews
  • createdAt
  • modules

It's okay that the array includes that we don't need. Our functions will take care of filtering the data properties to match only what the asks for.

Which of these are true about data sources?

Notably, the array doesn't include the author information we need, such as name and photo. However, it does include an authorId. We can provide this to the /author/:id endpoint, which takes an ID parameter and returns the details of that author.

{
"id": "cat-1",
"name": "Henri, le Chat Noir",
"photo": "https://images.unsplash.com/photo-1442291928580-fb5d0856a8f1?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzA0OH0"
}

Looking at the Author type in our schema, we get everything we need:

type Author {
id: ID!
name: String!
photo: String
}

We'll need to call this /author/:id endpoint for each track in the array that we received in the previous call. Then we'll need to stitch the results together so that we end up with the shape of the data that our , and our , is expecting.

What is the name of the author with id cat-9?

We know our data is provided by a REST API and how that API's data is structured. Next, we'll find out how our functions can access that API.

Previous

Share your questions and comments about this lesson

Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.