As part of my 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. Borum Jot There are two main kinds of APIs. One is a , and this is used 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 , , or even . It is usually specified in the URL, even if it's not directly on the page. software and its documentation very programming languages frameworks ecosystems Thanks to , I learned that a 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: @mankms on Twitter REST API 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 . statusCode 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 , a hosting platform. Although Vercel is designed for JavaScript and React-type projects, the 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.). Vercel vercel-php Because I was deploying on Vercel, I needed to store all the 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. endpoints now.json now.json 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) api/ v1/ ? ? now.json composer.json 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. <?php header( ); header( ); echo json_encode([ => , => , => ]; ?> "HTTP/1.1 200 OK" "Content-Type: application/json; charset=UTF-8" "english" "Hello world!" "french" "Bonjour!" "german" "Guten tag!" Notice the header function calls, establishing the server response headers. The 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 file: 200 OK json_encode now.json { : { : { : } }, : [ { : , : } ] } "functions" "api/v1/*.php" "runtime" "vercel-php@0.3.1" "routes" "src" "/v1/greeting" "dest" "/v1/greeting.php" The 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 . functions routes dest src /v1/greeting.php /v1/greeting 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 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: include api v2 DRY api/ include/ Config.php SimpleRest.php DBHandler.php v1/ greeting.php now.json composer.json I copied the code from , expanding to fit to my API. SimpleRest another site 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. SimpleRest::setHttpHeaders(200) header() 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. mysqli_connect() $conn DBHandler 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. createNewUser() register.php public { ($ ->newUserValid($email)) { $query = ; $newBorumUserResult = $ ->executeQuery($query); (mysqli_affected_rows($dbc) == ) { # Query ran okay $accountId = $ ->executeQuery( ); $accountId = mysqli_fetch_array($accountId, MYSQLI_BOTH); $apikey = $ ->generateApiKey(); ($ ->apiKeyExistsInDatabase($apikey) != ) { $apikey = $ ->generateApiKey(); } $newBorumJotUserResult = $ ->executeQuery( ); (mysqli_affected_rows($dbc) == ) { # Query ran okay [ => , => ]; } } [ => [ => ], => ]; } { [ => [ => ], => ]; } } ( ) function createNewUser $firstname, $lastname, $email, $password if this "INSERT INTO firstborumdatabase.users (first_name, last_name, email, pass, registration_date) VALUES ('$firstname', '$lastname', '$email', SHA2('$password', 512), NOW()) " this if 1 this "SELECT id FROM firstborumdatabase.users ORDER BY registration_date DESC LIMIT 1" this // If the generated api key is taken, keep generating until a unique one is found while this true this // Insert the newly created Borum user into the Borum Jot `users` table this "INSERT INTO users (borum_user_id, time_created, api_key) VALUES ($accountId, NOW(), '$apikey')" if 1 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: : SimpleRest::handlePostParameterValidation( ); $newnoteres = $handler->createNote($_POST[ ]); SimpleRest::setHttpHeaders($newnoteres[ ]); echo json_encode($newnoteres); case 'POST' "name" 'name' "statusCode" The 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. $handler DBHandler statusCode 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! DBHandler 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 https://varuns.hashnode.dev/my-first-web-api-part-1