REST APIs for absolute beginners

tutorial

Sometimes I get requests on how the Lord of the Rings API works and I realize that its documentation might not be outstretched enough for absolute beginners. So here is what you maybe searched for or didn't dare to ask: The absolute beginner's guide to REST APIs using the example of The Lord of the Rings API.

Why you should learn about REST APIs

So maybe you just stumbled into web development, wrapped your head around some HTML and CSS and you have a basic idea of how the internet and web servers work. (No? Don't give up. I found a great intro here: https://roadmap.sh/guides/what-is-internet) Why would you learn about REST APIs? REST APIs are a great way to fetch data of all kinds and integrate them into your web project, no matter if just for fun or the next big startup that you are building. Many of those data stores are free of charge and open for you to work with them.

A definition of REST APIs

Many refer to them as "Web Services", which I would explain as a web application without a user frontend but still accessible through a web URL. They often provide a set of multiple sub URLs (also called "endpoints") that point to different subsets of the data store. The term REST is a short term for a special style the architecture of the API is based on. REST is the most common way to create an API (though GraphQL gains popularity the last years) and it's mostly for developers actually building the API to know those principles. For developers fetching data it's only important to know how the data is provided: a data format called JSON. A single JSON object could represent a single item of a data store, e.g. a character from the Lord of the Rings, which looks basically something like this:

    {
      "_id": "5cd99d4bde30eff6ebccfe19",
      "height": "Tall",
      "race": "Human",
      "gender": "Male",
      "birth": "TA 2948 ,Gondor",
      "spouse": "Elfhild",
      "death": "March 15 ,3019",
      "realm": "",
      "hair": "White with braids (book) Blonde (films)",
      "name": "Théoden",
      "wikiUrl": "http://lotr.wikia.com//wiki/Th%C3%A9oden"
    }

Not really pretty, right? But useful in many ways (We'll see..)!

A data subset that provides multiple items (e.g. multiple characters from the Lord of the Rings) is placed into an array and would look like these:

    [
     {
      "_id": "5cd96e05de30eff6ebcceb9f",
      "dialog": "What do you fear, my lady? ",
      "movie": "5cd95395de30eff6ebccde5b",
      "character": "5cd99d4bde30eff6ebccfbe6"
    }, {
      "_id": "5cd96e05de30eff6ebcceb9e",
      "dialog": "A cage.To stay behind bars until useand old age accept them.And all chance of valor has gonebeyond recall or desire.",
      "movie": "5cd95395de30eff6ebccde5b",
      "character": "5cdbdecb6dc0baeae48cfa59"
    },
   ]

How to access the data and go through authentication

There are many ways to connect to web URLs and the data behind them. The most common is to use a web browser like Chrome, Firefox or Safari. So what happens if you try to access https://the-one-api.dev/v2/book via browser? You actually send a GET request to the webserver storing the LotR API data, which then returns a JSON object of all three books of the trilogy to your browser.

If you read the APIs documentation (or already tried) you might have seen that the endpoint https://the-one-api.dev/v2/movie movie doesn't return any data, but just a HTTP status code 401 (Unauthorized). Most endpoints of the API are protected (for monitory & security reasons), that means - only available if the user provides authentication credentials.

So the first step for you to access all protected endpoints is registering a new user account (don't worry, it's free of charge). You will get a so-called access key - this is your personal key to the all protected data and should look something like this: xvi06TKLyJvBmrQC4yZv

The documentation says you have to add that access key as a bearer token to your GET request. But how are you able to add that during you browser's request? The answer is - you can't by just surfing to the desired endpoint. You'll have to add it programmatically (e.g. through a browser-side JavaScript script or a server-side Python script) or by using another type of client: e.g. a command-line tool for data like cURL or a more sophisticated software like Postman or Hoppscotch.

Let's try Hoppscotch (no need to install anything): Enter the desired protected API endpoint (e.g. https://the-one-api.dev/v2/movie) and the authorization header including your access key as a bearer token:

Hoppscotch Sample Request

Hurray! The status code 200 tells us that this has worked.

Doing something useful with REST API data

Using a client like Hoppscotch is actually a very common way to try out the different endpoints of a REST API. It's often the first step before integrating REST API data into your real app. After you have found out which endpoints are available, how the authentication mechanism works and which data they provide, you can switch into your application code and try to integrate this behaviour into your app.

Let's say we'd like to build a React app that fetches a random Lord of the Rings API quote, the matching character's data, processes it and creates a nice-looking quote representation.

Let's do

cd lotr-sample-app

At first we jump right into App.js and remove all the boilerplate. We create two local state variables for the quote text and the character.

const [character, setCharacter] = useState();

Let's use a nifty little useEffect hook to fetch all quotes on page loading. For simplicity, we use the built-in fetch library (don't forget to add your authorization header here as well!). After that, let's pick a random quote, but - oh no - the quote's character is only the character's id, so we have to create a second fetch request that will fetch all characters's data based on the id.

After some processing we are ready to put the quote and character data into the React state so we can use it in the return statement.

    const headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer xvi06TocPJvBmrQC4yZv'
    }

    const fetchData = async () => {
      const rawQuotes = await fetch('https://the-one-api.dev/v2/quote', {
        headers: headers
      })
      const quotes = await rawQuotes.json();
      const quote = quotes.docs[Math.floor(Math.random() * quotes?.docs?.length)];
      setQuote(quote.dialog)
      const rawCharacters = await fetch('https://the-one-api.dev/v2/character?_id=' + quote.character, { headers: headers })
      const characters = await rawCharacters.json();
      const character = characters.docs[0];
      setCharacter(character.name)
    };

    fetchData();
  }, []);

The return statement can be very simple including a blockquote and a cite element. Styling-wise, I'm a bit lazy and use this very nice-looking template by Joe Hastings. Copy and paste all the CSS into your index.css and you should be fine.

Get the code

You can have a look into all the code in this Github Repo.