Before you go, check out these stories!

Hackernoon logoWriting Your First REST API: A How-to Guide by@varunsingh

Writing Your First REST API: A How-to Guide

Author profile picture

@varunsinghVarun Singh

I'm a software developer, hacker, and avid reader interested in all things tech

As part of my Borum Jot project, I made a REST API for all my front-end platforms to create, retrieve, update, and delete (CRUD) data on the database. In this article, I'll discuss what exactly an API is and how I made my own REST API.

There are two main kinds of APIs.

One is a software and its documentation, and this is used very liberally. For example, the old JavaScript library jQuery has a documentation so developers know how to use it. This documentation web site is referred to as the jQuery API. Other examples are documentations for programming languages, frameworks, or even ecosystems. It is usually specified in the URL, even if it's not directly on the page.

Thanks to @mankms on Twitter, I learned that a REST API refers to sets of pages to which clients make HTTP requests, and they return back data, possibly querying a database, in a specific structure. I like to think of a REST API as part of a filtration system:

A REST API in a filtration system

This concept is called information hiding, and it is important for simplicity and security. But before I could begin hiding information, I had to obtain information. I began by choosing a language.

Choosing a Language and Content Type

I used PHP, a back-end language, for my API. A back-end language sits on the server and accesses data.

I used JSON, or JavaScript Object Notation, for the content type. It is used to represent data in nested objects. In my API, I sent JSON that looked like this:

    "statusCode": 200,
    "data": [
            "id": "10",
            "title": "Go to Grocery Store",
            "body": "Go to this grocery store",
            "user_id": "115",
            "completed": "1",
            "time_updated": "1038829292",
            "parent_id": "0",
            "priority": "0",
            "source": "task"

Once the client receives the above response and parses the JSON, it can retrieve the value of any property, such as


Host Configuration and File Structure

I now knew I was writing in PHP to make a REST API that sends JSON to a client (the front-end). Surprisingly, where I hosted was very important at this point. I deployed on Vercel, a hosting platform. Although Vercel is designed for JavaScript and React-type projects, the vercel-php runtime allows developers to host back-end PHP projects on a secure domain (as opposed to directly on the domain registrar, which may require configuring GitHub, paying for an SSL certificate, etc.).

Because I was deploying on Vercel, I needed to store all the endpoints in the api directory and configure the

file. The
file tells vercel-php which files were serverless functions. These serverless functions served as the API endpoints that sent the response data in JSON format.

Vercel Function Logs

In addition, I've seen APIs specify their version (e.g. v1). So far, this was my file structure (note the composer.json is for including PHP libraries)


What would go inside the v1 subdirectory?

Writing my First Endpoint

Finally, I could begin writing the code (the fun part)!

In its simplest form, a REST API is one PHP file that returns the JSON, such as one of the examples above, on every request.

header("HTTP/1.1 200 OK");
header("Content-Type: application/json; charset=UTF-8");
echo json_encode(["english" => "Hello world!", "french" => "Bonjour!", "german" => "Guten tag!"];

Notice the header function calls, establishing the server response headers. The

200 OK
is an HTTP Status Code that tells the client that everything ran okay and it can now access the data. The
turns a PHP Associative Array into JSON format. The API deploys through Vercel and has the following as its

    "functions": {
              "api/v1/*.php": {
                     "runtime": "vercel-php@0.3.1"
     "routes": [
         { "src": "/v1/greeting", "dest": "/v1/greeting.php" }


object specifies the directories that have API endpoints and will always have the same runtime property. The
array contains paths at the location of
that rewrite the url to
. In the above example,
simply becomes

Helper Classes and Added Complexity

The second level of complexity was to interact with the database. I created a separate folder called

and put it in the
directory in case I wanted to have a
. Remember, putting everything in one file still makes it an API, but I put database handling in a separate class to make my code DRY and modular. When I have more than one response object (such as a GET and POST request to the same endpoint, or multiple endpoints), I could call code I had already written. My modified file structure looked like this:


I copied the

code from another site, expanding to fit to my API.

For every response from this point, I had only to call

or another status code, replacing multiple
calls with one method call of my own class.

Database Interaction

First and foremost is a Config.php file for database interaction. I used the

call to connect with my database credentials to the MySQL database I host on GoDaddy. Next, I stored the PHP Connection object inside an instance variable named
in the
class in the constructor.

For every database-querying function, I wrote an instance method in the DBHandler class. Once my database, app, and API got larger, I expanded this into its own folder and namespace, but for now, I could keep everything in one class.

For instance, I wrote the

method for a POST request to the
endpoint. Below is the code of this method.

public function createNewUser($firstname, $lastname, $email, $password) {
     if ($this->newUserValid($email)) {
          $query = "INSERT INTO firstborumdatabase.users 
                (first_name, last_name, email, pass, registration_date) 
                VALUES ('$firstname', '$lastname', '$email', SHA2('$password',                   512), NOW())
$newBorumUserResult = $this->executeQuery($query);
 if (mysqli_affected_rows($dbc) == 1) { # Query ran okay
         $accountId = $this->executeQuery("SELECT id FROM firstborumdatabase.users ORDER BY registration_date DESC LIMIT 1");
         $accountId = mysqli_fetch_array($accountId, MYSQLI_BOTH);
        $apikey = $this->generateApiKey();
// If the generated api key is taken, keep generating until a unique one is found
while ($this->apiKeyExistsInDatabase($apikey) != true) {
$apikey = $this->generateApiKey();

// Insert the newly created Borum user into the Borum Jot `users` table

$newBorumJotUserResult = $this->executeQuery("INSERT INTO users (borum_user_id, time_created, api_key) VALUES ($accountId, NOW(), '$apikey')");
 if (mysqli_affected_rows($dbc) == 1) { # Query ran okay
 return [
     "ok" => true,
       "statusCode" => 200
return [
      "error" => [
            "message" => "The user could not be validated at this time"
 "statusCode" => 500
 } else {
       return [
               "error" => [
                    "message" => "User with that email already exists on Borum"
 "statusCode" => 500

And in the endpoint file, I would call it and my helper methods inside of one case of a switch statement that checks the request method:

case 'POST':
$newnoteres = $handler->createNote($_POST['name']);
echo json_encode($newnoteres);


variable instantiates a new
object (or a subclass of that). I put a
property in each JSON response so I could easily set the status code header.

And that's what I did for every new response that I needed to create - I made a new method that queried the database in a

class. If you know how to use PHP with MySQL, and you followed everything described above, you're ready to make your own REST API!

Don't I have to document it? What about unit tests? Stay tuned for Part 2, where I'll be covering all of this and more!

Previously published at


Join Hacker Noon

Create your free account to unlock your custom reading experience.