Learn to Code via Tutorials on Repl.it

← Back to all posts
Create Our Own APIs in NodeJS (Accessed with Python)
LeonDoesCode (275)

Whoa!

Yep, we are now going to make our own API using NodeJS! So cool, isn't it? Now that we know how to access them, let's see how to create them. It will further help us when it comes to using other APIs later on. Let's get cracking!

Languages

As I said before, we will be using NodeJS to create the API. Why NodeJS? Well, we haven't covered much NodeJS yet, and this is also what a lot of other APIs use. So we get to understand the backend even better.

To use the API, we will be using Python, just like always. So don't worry, there is still some Python in this one.

Creating the API

Okay, so we will need to require our packages like always. We will be using only one external package called express, that's it:

const fs = require('fs');
const app = require('express')();

So we have express for the server stuff, and fs to access the test.json file we will be making.

Here is that test.json file that we will be using with our API:

{
  "users":{
    "0":{
      "karma":142,
      "name":"john doe",
      "roles":["hacker"]
    },
    "1":{
      "karma":16,
      "name":"jane doe",
      "roles":[]
    },
    "2":{
      "karma":98,
      "name":"steve crow",
      "roles":["moderator", "hacker"]
    }
  },

  "posts":{
    "0":{
      "userid":1,
      "karma":3,
      "title":"Events in NodeJS",
      "contents":"## What Are Events?\nEvents are..."
    },
    "1":{
      "userid":1,
      "karma":1,
      "title":"Callbacks in NodeJS",
      "contents":"## What Are Callbacks?\nCallbacks allow..."
    }
  }
}

All we are doing is making two separate objects called users and posts. We then populate users with some template users and some details about them. We then do the same thing for posts. Pretty self explanatory once you have a quick look.

Back to the main file!

Let's load the test.json file we just made, which is pretty easy using the fs package:

/* Test Data */
let test;
// Get json data
fs.readFile('test.json', 'utf8', (err, data) => {
  // If there was an error, throw it
  if(err) throw err;
  // Or set test to the json
  test = JSON.parse(data);
});

As you can see, we make our test variable. Then we read the test.json file, if there is an error, then we throw it. Otherwise, the test variable is set to the data. Now we can move onto something pretty cool.

Instead of making an API which we have to update when we add a new thing to the JSON file, we are going to make what I (and maybe others) call a Dynamic API. This will update as we update the JSON file, which is pretty cool. Let's do it!

/* Dynamic API */
app.get("/:type/:id", (req, res) => {
  // Get the id from the url as specified in the get function
  let id = req.params.id;
  // Get the type from the url as specified in the get function
  let type = req.params.type;
  // Get the type with that id
  let data = test[type][id];
  // If the type doesn't exist, make an object with error inside
  if(!data) data = {"error":"Post doesn't exist!"};
  // Respond, using json, the type object
  res.json(data);
});

For this, we add a new route to the app using app.get(). This route is /:type/:id. But what does this mean? The /s mean sub directories like normal, but the :type and :id are variables from the url. In this case, if we were talking about the url repl.it/users/6345, users would be :type, and 6345 would be :id. Simple!

So we get the params type and id using req.params, an put those in their respective variables. Then we make a variable called data which will get the data of test[type][id]. This will get the data from test where the first key is type and the second key is id. E.g test["users"][0] or test["posts"][1]. We then check to see if the data exists, if not, we change it to be equal to an error so that the user of the API knows what's going on.

Lastly, we respond in JSON the data we just got.

Whoa, that was quite the explanation. This allows you to add other fields such as repls into the JSON file. Inside the new repls, you might make it so each id is a name instead of a number. All this is up to you.

Now that we have done that, all we have to do is set the express server to listen:

/* App Listen */
// Get port
const port = process.env.port || 5000;
// Set app to listen on port
app.listen(port, () => {
  // Show that the server is running
  console.log(`Server running on port ${port}.`);
});

I set it to listen on the port in the .env file, or if it doesn't exist then 5000. Then I make it print to the console that it is running and the port it is running on. If you run your file, you should get a page in the top right. It will say something like Cannot GET '/'. This is because there are no routes for the root page which is what you will load into by default. But don't worry.

Open that page in a new tab, and in the url, add /users/1. You should then see some JSON for that user from the test.json file. Pretty cool.

Using Our API

Now that we have made our API, let's test it out in another language to make sure it works. Python sounds like a great choice to me. So let's do what we always do when we use APIs, import our modules:

import urllib.request
import json

Since we have done this before, I won't be explaining it this time. You can have a look at this tutorial or this one to see how it works, or for more information.

We will be using json as we respond to our API calls with JSON, just like Wikipedia's API.

# Get our api endpoint url
url = "https://api.leondoescode.repl.co/"

# Set our two different api routes, users and posts
users = f"{url}users/"
posts = f"{url}posts/"

# Get the userid and postid we want to get from our api
userid = input("User Id: ")
postid = input("Post Id: ")

# Add our ids onto the routes and open the new urls, read and decode them
userres = urllib.request.urlopen(users + userid).read().decode()
postres = urllib.request.urlopen(posts + postid).read().decode()

# Since we get json, we can load it using the json module
userres = json.loads(userres)
postres = json.loads(postres)

print(userres)
print()
print(postres)

Now we set our url as our API's endpoint, which is the root directory. Then we specify the urls for users and posts, which we then get ids for from the user. These ids get added to the urls and open, read and decoded. They are then json.loads() to get the data into a Python Data Type. Lastly, we print the user and post JSON.

When you run this, you'll see you need to input two ids. 0 will always return a result, as both the users and posts have users and posts in them. But higher numbers my return the error inside the JSON instead of data. This is so that the user can check that there was no error, and if there was, can deal with that error.

Conclusion

APIs aren't to hard to make. I recommend making one so that you understand how the things you work with really work. Try changing the way the test.json file is laid out, and how the API works. Maybe you can make the API's endpoint https://api.leondoescode.repl.co/api/ so that you can still host a website, while having an API for it. Have fun messing around with the code!

Hope you have a great day!

P.S
If you have any suggestions for tutorials, leave them in the comments and I'll be sure to have a look. If you like one in the comments, then give it an up vote to show that you want to see it. It makes my life so much more easier. Thanks in advance!

Commentshotnewtop
LukeShomper (7)

Showing how much Memory a script is using.