Hey, hey, hey. It's an API!

A man driving that works for Alphabet (Google), drives a car and takes imagery for Google Maps.
We have found one of the agents...he's a Googler.

What the heck is an API?

APIs stand for, "Application Programming Interfaces". But really, what you need to know is that these API things hold lots of useful data for developers to use for their cool app idea, or for a website that allows people to obtain data about Mars Missions, searching the iTunes store, and a whole lot more.

What I Will Show You

The entire purpose of this blog post is that hopefully it can be useful for other developers who are fairly new.

There are lots of useful tutorials teaching you how to do fetch "GET" and "POST" requests out there. BUT, I have been unable to find one tutorial at the time of this writing dealing with fetch requests via nesting, and passing along JSON Web Token (JWT) authoriation.

And that is what we will be learning; while we use the Listen.moe API. We will use this API to login to our respective account, and get song data.

Create a Listen.moe Account

Alright, so first up, go ahead and create a Listen.moe account so that you can login to the API and get your JWT.

Our Variables

          
            const log = console.log;
  
            const credentials = {
              username: "myUsername",
              password: "myPassword"
            };
  
            var customHeaders = {
              "Content-Type": "application/json",
              Accept: "application/vnd.listen.v4+json"
            };
  
            var myToken = "";
          
        

Above we have our variables where console.log will be called instead via "log()".

We also have our username and password saved in a constant named, "credentials".

As for the, "customHeaders" variable name, it is where we include the type ("Content-Type":) of content the server will respond with, and what type of content our web browser is expecting to accept ("Accept":).

The myToken variable is a global variable, available throughout our script, that will be assigned an empty value for now. Later on it will then be reassigned the token value sent to us by the web server.

Our fetch Request

          
            //Login to Listen.moe
            fetch("https://listen.moe/api/login", {
              method: "POST",
              headers: customHeaders,
              body: JSON.stringify(credentials);
            })

            .then(response => {
              return response.json();
            })

            .then(result => {
              log(result);
            })

            .catch(error => {
              log(`ERROR: ${error}`);
            });
          
        

We pass in our endpoint url that we will be logging into. It is designated a "POST" request, that has our "customHeaders" that we defined earlier.

Moreover, we are passing into the body our account credentials and turning that JSON object into a string.

From there, we obtain the response from the server and return it as JSON data via the, "response.json()" method.

Now with our data parsed as JSON, we log it out to our console where we will be greeted with our JWT.

JSON Web Token from the Server

          
            .then(result => {

              log(result);

              sessionStorage.setItem("myToken", JSON.stringify(result.token));

              myToken = JSON.parse(sessionStorage.getItem("myToken"));

              customHeaders.Authorization = `Bearer ${myToken}`;

            });
          
        

We were able to login successfully!

Continuing from the point where we logged out our assigned token, we then save it locally via sessionStorage. Furthermore, we give it the key of "myToken".

Afterwards, we assign our myToken variable (not key) from the Our Variables Section that we created; the value of that sessionStorage value, but as JSON data.

Lastly, we then create an "Authorization" property on our "customHeaders" object. We do this since the API requires us to pass our JWT via the "Authorization" header.

Therefore, we do so and we follow the syntax, "Bearer ourAPIKey". But, we use template literals instead of string concatenation purely out of preference.

Nesting fetch Requests

          
            .then((result) => {

              log(result);

              sessionStorage.setItem("myToken", JSON.stringify(result.token));

              myToken = JSON.parse(sessionStorage.getItem("myToken"));

              customHeaders.Authorization = `Bearer ${myToken}`;

              return fetch("https://listen.moe/api/songs", {
                method: "GET",
                headers: customHeaders,
              })
              
              .then((response) => {
                return response.json();
              })
              
              .then((result) => {
                log(result);
              })
              
              .catch((error) => {
                log(error);
              });

          })
          
        

The final step is then to return a nested fetch statement where we GET a song list, and then log out that song list.

All we must do is follow the Fetch API pattern we have been using, but within the "result" .then() promise.

Take note of how the response, result, and error promises follow after and are within the same "result" .then() promise that the returning fetch statement is within.

Congrats!

You have just learned how to nest Fetch API calls, authorize yourself via JWT in the "Authorization" header, set header and body properties, how to specify GET and POST requests, and how to stringify and parse JSON data!

You've certainly leveled up!

What Our Code Looks Like

          
            //Login to Listen.moe
            fetch("https://listen.moe/api/login", {
              method: "POST",
              headers: customHeaders,
              body: JSON.stringify(credentials);
            })
            .then(response => {
              return response.json();
            })
            .then(result => {
              log(result);
              sessionStorage.setItem("myToken", JSON.stringify(result.token));
              myToken = JSON.parse(sessionStorage.getItem("myToken"));
              customHeaders.Authorization = `Bearer ${myToken}`;

              //Get Listen.moe song data
              return fetch("https://listen.moe/api/songs", {
                method: "GET",
                headers: customHeaders
              })
              .then(response => {
                return response.json();
              })
              .then(result => {
                log(result);
              })
              .catch(error => {
                log(`ERROR: ${error}`);
              })
            })
            .catch(error => {
              log(`ERROR: ${error}`);
            })
          
        

This is what are code should look like now that you have finished following this tutorial.

If not, then go ahead and make the necessary adjustments.

Summary

We have learned how to set request, header, and body properties, make subsequent requests via nested fetch requests, and how to use JSON Web Tokens.

You can also find the code for this on my Github. It will be there for any future reference.

Thank you for taking the time to read the article all the way to its end! I hope you found this article useful and have a great day!