You're seeing this because you're a teacher 🤓

🎯 Your main goal for this lesson

If a student can get a single piece of data rendered from an outside API, sparkling cider should be popped for everyone in the room. Mazel!

🧠 Things to keep in mind when teaching

Our previous lesson made a big leap to having students utilize JS in their pages. This lesson will take an even bigger leap as we ask them to start interacting with...the outside world. As has previously been the reminder here: keep your patience with them as they get frustrated by any number of logistical issues from your school's filter to CORS errors.

🚀 Lesson Plan

Activity One: 20 minutes

To help students get in the right frame of mind for how APIs work, we have to think back to our first module focusing on clients and servers and the request-response cycle. Use the attached documents and organize the students into two groups: the clients and the servers.

Students in the servers group will sit at the labeled desks while the clients will line up based on their own labels. The clients, when reaching the front of the line will hand their sheet of paper over the server who will then look up the requested information on their sheet of paper, write down the information, and hand it back to the client. The client will then repeat the process as many times as listed on their sheet before aggregating the data into one coherent piece of information.

This is going to take some time (it's supposed to - REST servers are SLOW!).

Discuss the activity with the class and help students to see the reason for lines and why they were only requesting one piece of information at a time.

Activity Two: 30 minutes

Lead students through the lesson and provide support as they complete the assignment.

Activity Three: 10 minutes

Take the formative assessment at the end of class. Work towards mastery.

Accessing APIs

By the end of this lesson, you'll be able to...

  • Write a fetch request to an outside API.
  • Parse JSON files returned by an API.
  • Traverse an endpoint of a REST URL.
  • Destructure an object based on needed properties.

Accessing APIs

As we saw in our previous lesson, with JavaScript we have a lot of power to access and manipulate the information displayed within the DOM. However, with outside sources, or APIs, we can use JavaScript's fetch capabilities to call those APIs and have data returned.

This connects to earlier modules when we discussed the request-response cycle. We're going to see it in full force now as we use outside APIs to consume data and render it within our applications. This is the modern paradigm of web development: front end sites and applications built to consume and render data from multiple outside sources. Soon, we'll learn about the jamstack and the suite of tools and frameworks that exist to make this process way easier than what you'll be learning in this lesson 😉

JSON

Let's begin by discussing an acronym that you'll come to know very well: JSON, or JavaScript Object Notation. JSON looks like an object, but it isn't. JSON is language independent, meaning it's not tied to JavaScript. It's simply a format for organizing data that can be consumed by front-end applications and server-side languages (including those that aren't JavaScript).

JSON will definitely look familiar

1{ 2 "data": { 3 "courses": [ 4 { 5 "id": 1, 6 "title": "Intro to Web Development", 7 "teacher": "Dominguez", 8 "teacherImg": "https://avatars.githubusercontent.com/u/24390149?v=4", 9 "roster": [ 10 "Bart Simpson", 11 "Milhouse Van Houten", 12 "Martin Prince", 13 "Nelson Muntz", 14 "Wendell Borton", 15 "Lewis Clark" 16 ], 17 "meetingDays": ["M", "T", "W", "Th", "F"], 18 "roomNumber": 742 19 }, 20 { 21 "id": 2, 22 "title": "Computational Algorithms", 23 "teacher": "Barnard", 24 "teacherImg": "https://avatars.githubusercontent.com/u/24390149?v=4", 25 "roster": [ 26 "Lisa Simpson", 27 "Ralph Wiggum", 28 "Allison Taylor", 29 "Janey Powell", 30 "Alex Whitney" 31 ], 32 "meetingDays": ["M", "T", "W", "Th", "F"], 33 "roomNumber": 19 34 } 35 ] 36 } 37}

In terms of syntax, notice that there are no backticks allowed. All strings are encapsulated by quotation marks.

Response-Request Cycle IRL

Most APIs will return information to us using JSON. There are some common patterns we can pick up and reuse to make sure we're retrieving and interacting with our data as needed. In the modern day, APIs typically fall under two categories: REST and GraphQL. We'll go into detail below about how to use REST APIs, but we won't be working with GraphQL until the end of this course.

REST APIs

REST APIs are by far the most popular and common you'll encounter. REST stands for representational state transfer. They typically operate with different endpoints, or addresses, you navigate to in order to ask for certain pieces of information.

As an example, we'll use the Rick and Morty API.

REST APIs will give you a base url to utilize: https://rickandmortyapi.com/api/

And from there, you simply get more specific with what you're searching for: /character/

We can make these requests using JavaScript's native fetch method. The example below is introducing a new concept that can be hard to wrap your head around: async code. In JavaScript, code doesn't run and complete line-by-line before beginning work on the next task. It's not synchronous. As such, if we have to wait on a request to an API, we have to tell our script to wait for the response before we do anything with it.

The solution to this is a pairing of async and await. We can prepend our function declarations with the keyword async; when we do this, we unlock the ability to use await in our function; each time an await keyword is used, the script essentially pauses - or keeps from moving to the next task - until this portion is complete.

1// Async function 2async function getPeoples() { 3 let response = await fetch(`https://rickandmortyapi.com/api/character/1`); // WAIT to set `response` equal to something until the fetch is returned 4 let data = await response.json(); // WAIT to set `data` equal to something until we have `response` transformed into `JSON` 5 console.log(data); 6} 7 8// Call the function 9getPeoples();

You can paste this code into your console and you'll actually get a response!

1{ 2 "id": 1, 3 "name": "Rick Sanchez", 4 "status": "Alive", 5 "species": "Human", 6 "type": "", 7 "gender": "Male", 8 "origin": { 9 "name": "Earth (C-137)", 10 "url": "https://rickandmortyapi.com/api/location/1" 11 }, 12 "location": { 13 "name": "Earth (Replacement Dimension)", 14 "url": "https://rickandmortyapi.com/api/location/20" 15 }, 16 "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg", 17 "episode": [ 18 "https://rickandmortyapi.com/api/episode/1", 19 "https://rickandmortyapi.com/api/episode/2", 20 "https://rickandmortyapi.com/api/episode/3", 21 "https://rickandmortyapi.com/api/episode/4", 22 "https://rickandmortyapi.com/api/episode/5", 23 "https://rickandmortyapi.com/api/episode/6", 24 "https://rickandmortyapi.com/api/episode/7", 25 "https://rickandmortyapi.com/api/episode/8", 26 "https://rickandmortyapi.com/api/episode/9", 27 "https://rickandmortyapi.com/api/episode/10", 28 "https://rickandmortyapi.com/api/episode/11", 29 "https://rickandmortyapi.com/api/episode/12", 30 "https://rickandmortyapi.com/api/episode/13", 31 "https://rickandmortyapi.com/api/episode/14", 32 "https://rickandmortyapi.com/api/episode/15", 33 "https://rickandmortyapi.com/api/episode/16", 34 "https://rickandmortyapi.com/api/episode/17", 35 "https://rickandmortyapi.com/api/episode/18", 36 "https://rickandmortyapi.com/api/episode/19", 37 "https://rickandmortyapi.com/api/episode/20", 38 "https://rickandmortyapi.com/api/episode/21", 39 "https://rickandmortyapi.com/api/episode/22", 40 "https://rickandmortyapi.com/api/episode/23", 41 "https://rickandmortyapi.com/api/episode/24", 42 "https://rickandmortyapi.com/api/episode/25", 43 "https://rickandmortyapi.com/api/episode/26", 44 "https://rickandmortyapi.com/api/episode/27", 45 "https://rickandmortyapi.com/api/episode/28", 46 "https://rickandmortyapi.com/api/episode/29", 47 "https://rickandmortyapi.com/api/episode/30", 48 "https://rickandmortyapi.com/api/episode/31", 49 "https://rickandmortyapi.com/api/episode/32", 50 "https://rickandmortyapi.com/api/episode/33", 51 "https://rickandmortyapi.com/api/episode/34", 52 "https://rickandmortyapi.com/api/episode/35", 53 "https://rickandmortyapi.com/api/episode/36", 54 "https://rickandmortyapi.com/api/episode/37", 55 "https://rickandmortyapi.com/api/episode/38", 56 "https://rickandmortyapi.com/api/episode/39", 57 "https://rickandmortyapi.com/api/episode/40", 58 "https://rickandmortyapi.com/api/episode/41" 59 ], 60 "url": "https://rickandmortyapi.com/api/character/1", 61 "created": "2017-11-04T18:48:46.250Z" 62}

REST APIs are kind of like lines at the store. Maybe you have one line that is only for ten items or less; maybe there's another only for cosmetics; and another for sports equipment. At each of these counters, people form lines - or queues waiting to request certain items. Based on availability, the clerk at the counter will respond with the items requested, but only the ones from that line.

Destructuring Responses

The response that our request gives us is...huge. What if we only wanted a few key pieces of information to insert into our page? Well, we have a great tool called destructuring that allows us to pull out certain items from this response. This will make it easier when start injecting information into our pages.

1async function getPeoples() { 2 let response = await fetch(`https://rickandmortyapi.com/api/character/1`); 3 let data = await response.json(); 4 let { name, status, image } = data; // This lets us take out the three items we may be most likely to use 5} 6 7// Call the function 8getPeoples();

Rendering Requests to the DOM

Just like in our previous lesson, we can take this content and inject it into the DOM. Before, we had a course object that was hardcoded. Here, we simply make our call to the API first and then use the response to populate the DOM.

1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 <link rel="stylesheet" href="../assets/main.css" /> 8 <title>Rick and Morty API</title> 9 </head> 10 <body> 11 <div> 12 <h1 id="name"></h1> 13 <small id="status"></small> 14 <img src="" alt="" /> 15 </div> 16 </body> 17 18 <script> 19 // Async function 20 async function getPeoples() { 21 // Make our request and get in a usable format 22 let response = await fetch(`https://rickandmortyapi.com/api/character/1`); 23 let data = await response.json(); 24 let { name, status, image } = data; 25 26 // Access DOM items 27 const charName = document.querySelector(`#name`); 28 const charStatus = document.querySelector(`#status`); 29 const charImage = document.querySelector(`img`); 30 31 // Manipulate them 32 charName.innerText = name; 33 charStatus.innerText = status; 34 charImage.src = image; 35 charImage.alt = `${name}'s picture`; 36 } 37 38 // Call the function 39 getPeoples(); 40 </script> 41</html>

Previous and Next Lessons:

Objects

Conditional Logic