🔥 Build a simple API with Node JS for beginners 
Tags: beginners, node, javascript, webdev
Published: 2020-08-16 17:03:03

####  Why I am learning Node Js 
After making projects in Javascript like weather app with firebase, to do list, engaging in Javascript30 challenges etc. I wanted to learn more about javascript to a level of been comfortable in it and also learn some backend. I remember when I started learning css, it took me time to understand CSS selectors and BEM model. But when I started diving at SASS a CSS processor, I was able to connect the dots. Through learning SASS, I got better at CSS and I was able to understand the full power of Css.I love using nesting, mixin, imports and functions.It made learning Css fun. With this I decided to apply it to my Javascript journey, hence learning Node Js. By building my first small API with Node Js, I was able to understand callbacks, array methods and how functions like replace can be used in a real situation like creating & filling HTML templates. 

Everyone has a different way of learning and for me learning a Js framework helps me understand Js deeper and connect dots of how different things work together. Take a look at [Maximilian's view](https://www.youtube.com/watch?v=Gwup7MV_fXs) 
The point is get to know the best method that helps you learn and use it in your coding journey. What works for me, may not work for you and vice versa.😊 

## Node Js Introduction
#### What is Node JS
According to the [official website](https://nodejs.org/en/), Node Js is a javascript runtime that's built on chrome's V8 Javascript engine. <strong>Javascript runtime </strong> is where javascript code, that you have written is executed, when you run it. 😲

Don't get too lost, let me break it down for you. I am sure you have used html, css and javascript to create some functionality in your website. For example, creating a responsive navbar or used JS framework like React or Vue. The javascript code written is executed in the browser, in this case the browser is the javascript runtime. 
Hopefully everything is sinking in. 😏
Now you can also write javascript outside the browser, in a new environment without any browser restriction. This environment is called Node JS. So if we are not using the browser to execute our code, what are we gonna use? This is the work of [V8 engine](https://v8.dev/docs) built by Google runs the Javascript code.
Yaaaahh!!!, you can explain what is node Js to anyone. 

![git](https://i.ibb.co/fDKvf24/giphy.gif)


#### Why use Node JS?
+ Fast processing - With the help of V8 engine function are compiled at a high speed. Checkout the [performance speed](https://v8.dev/blog/10-years) of V8 engine.
+ Great for scalable data intensive applications
+ It is a single thread and has non blocking I/O (input/output) model 
+ It popular and has a lot of support. There is a big node js community to help you and the [official website](https://nodejs.org/en/) which clear documentation. Big companies like Netflix, Paypal, Uber and Ebay use it for their applications.

#### Cons
+ Not recommended for heavy server side processing. It's better to use Python or ruby. 
+ Callback hell in some situations.  

#### Node JS commands
+ .break    Sometimes you get stuck, this gets you out
+ .clear    Alias for .break
+ .editor   Enter editor mode
+ .exit     Exit the repl
+ .help     Print this help message
+ .load     Load JS from a file into the REPL session
+ .save     Save all evaluated commands in this REPL session to a file
+ Ctr + d   to exit node terminal

#### How to write your first code in Node JS
+ create a index.js file in your folder 
+ Write the following code
```js
const hello = 'Hello World';
console.log(hello);
```
+ Open your terminal and write 
```js
node index.js
```
####  Congratulations you just created your first line of code in Node JS

#### Node modules
A module is a set of functions. In node Js you can create or use the available built-in modules. Checkout this [list](https://www.w3schools.com/nodejs/ref_modules.asp) of built-in modules.

#### How to use modules
You have to use a function called require () and put the name of the module as the input. Remember to store it in a variable to make it easier to access in your code.
The fs module helps us to directly interact with the file system to read and write data.
```js
const fs = require('fs');
```
#### How to create and import your own modules
+ Create a folder and a js file and write your function.
```js
module.exports  = (card, product) => {
    let output = card.replace(/{%PRODUCT__NAME%}/g, product.productName);
    output = output.replace(/{%IMAGE%}/g, product.image);
    
    return output;
}
```
+ Import the file into your main js file 
```js
const templateReplace = require('./modules/templateReplace');
```
Amazing you just created your first module. I am proud of you.🔥
#### How to read files
Use Synchronous read file function, that reads the entire contents of a file. The input will be the path to your file and utf8 is the character encoding.
```js
const text = fs.readFileSync('./text/input.txt', 'utf8');
console.log(text); 

// in the terminal run node index.js(file with the code) and you will see the text as the output.
```
#### How to write files
Store your code in a variable. 
```js
const hello = 'Hello World! I am finally ready to learn Node!'
```
+ Use the file system module and the write file sync function that Synchronously writes data to a file or replacing the file if it already exist.
```js
//you have to specify the file path and the code you want to write

fs.writeFileSync('./txt/output.txt', hello);
```
Learn more about the [file system](https://nodejs.org/api/fs.html#fs_file_system) and how it's used.

#### Let's understand the difference between Synchronous and asynchronous coding
+ Synchronous coding is when code can only run if the previous code is executed. This can cause problems if you have code that takes too long to execute. \
It's even worse if you have a lot of user activity in your application. Simple functionality like signing up or logged in users, reading different feeds or posting an article, will take even longer. This is also called blocking method.
```js
const fs = require('fs');
const text = fs.readFileSync('./text/prac.md', 'utf8');
console.log(text); 
```

+ Asynchronous is when heavy code that take longer to execute is done at the background as the other code runs in the application. When the other code is done, it's called through a callback function that runs the result/output of the code. This is also called non-blocking.
In the example below, the read file function accepts a callback function to get the data. The data will run in the background and it will print the console log input first. When function is done getting the data, it will log it as an output. 
```js
const fs = require('fs');
fs.readFile('./text/prac.md', 'utf8', (err,data) => {
    console.log(data);
});
console.log('Asynchronous code');
```
Learn more about [blocking and non-blocking](https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/)

### How to make a simple API 
+ First, I started with sketching the design on a piece of paper
+ Used Figma to design high fidelity mockups and prototyping. Here is my [design in Figma](https://www.figma.com/file/GjfpAQHqs0y4HcDlpEib94/node-restaurant?node-id=0%3A1). (Hahah, the interface designer in me was so happy with the prototype 
😊 )
+ Went to Vscode to code out the HTML and Css of the project.

If you want to take a look at the files of the project you get them [on Github] (https://github.com/muchirijane/node-restaurant)

#### Page 1 of the project 
It has a list to food available to order.

<img src="https://i.ibb.co/hCvxHzW/screencapture-127-0-0-1-8000-overview-2020-08-16-15-41-52-1.png" alt="screencapture-127-0-0-1-8000-overview-2020-08-16-15-41-52-1" border="0">

#### Page 2 
A detailed view of the food and a step by step guide on how to cook them.

<img src="https://i.ibb.co/fNfqC0C/screencapture-127-0-0-1-8000-product-2020-08-16-16-53-10.png" alt="screencapture-127-0-0-1-8000-product-2020-08-16-16-53-10" border="0">

#### How to request data as a user with one API call.
+ Use the if statement to match the  request api url. 
```js
if(pathName === '/api') {}
```
+ Create a file system function that runs once to read the data. Hence you will use the sync file system function. When the application first runs, it will read the json data once and when the user enters the api route, it will send back the data upon request.\
It's a good practice to use dirname variable to locate the directory where the script is. \
To use the json data in html you have to use JSON.parse to convert the JSON string data to javascript and store it in a variable.
 
 ```js
 const data = fs.readFileSync(`${__dirname}/dev-data/data.json` 'utf-8');
 const objData = JSON.parse(data);
 ```
+ Send the data to the browser as a response by using res.end method.
+ Tell the browser that your data is JSON, use res.writeHead method.
```js
const pathName = req.url;

const data = fs.readFileSync(`${__dirname}/dev-data/data.json`, 'utf-8');
const objData =  JSON.parse(data);

const server = http.createServer((req, res) => {
    if(pathName === '/api') {
        res.writeHead(200, {'Content-Type': 'application/json'})
        res.end(data);     
    }else{
        res.writeHead(404, { 
            'Content-type' : 'text/html ,charset=utf-8',
            'my-own-header' : 'hello-world'
        });
        res.end('<h1>Page not found!</h1>');
    }
});
 
server.listen(8000, '127.0.0.1', () => {
    console.log('Server listening! 💣');
});
```
#### HTML templates
+ Start by replacing the text you want to add dynamically with data later on.
```html

<div class="product__detail-box">
    <p class="product__detail-text"><span class="product__detail-emoji">👨‍🍳</span>{%CHEF%}</p>
    <p class="product__detail-text"><span class="product__detail-emoji">⏲</span>{%TIME%}</p>
    <p class="product__detail-text"><span class="product__detail-emoji">📦</span>{%SERVERS%}</p>
    <p class="product__detail-text"><span class="product__detail-emoji">💰</span>{%PRICE%}</p>
</div>
```
+ For the links you with use the id number that you stored in the json data. Because the data is stored in an array it will be best to start with id = "0". Instead of using the # inside the href, you will add the api route and id number.
```html
<a href="/product?id={%ID%}" class="card__link">
    <p class="card__link-text"> More &rarr;</p>
</a>
```
#### Filing the templates
+ Make sure the templates are read during initialization of the application. You can use sync file system function which is a blocking method and store it in a variable. But because it will run only once when the application is running not when the createServer callback function is called.
```js
const templateOverview = fs.readFileSync(`${__dirname}/templates/template-overview.html`, 'utf8');
const templateCard = fs.readFileSync(`${__dirname}/templates/template-card.html`, 'utf8');
const templateProduct = fs.readFileSync(`${__dirname}/templates/template-product.html`, 'utf8');
```
+ In the createServer callback function tell the browser the type of information it's about to receive by using witeHead function.
+ Loop through the JSON data with map method that will return replaceTemplate function that has individual data from the json data array and the card template.
```js
if(pathname === '/' || pathName === '/overview' ){
     //tells the browser the type of information it's about to receive
    res.writeHead(200 , {'content-type' : 'text/html'});

    const cardHtml = objData.map( obj => replaceTemplate(tempCard,obj)).join('');
    const output = tempOverview.replace('{%PRODUCT_CARD%}', cardHtml);
    res.end(output);

    }
```
+ Inside the replaceTemplate function you can use replace method to replace the placeholder text with the data. 
+ You can use regular expression to make sure the placeholder text is selected globally through out your project.
```js
const replaceTemplate =  (card, product) => {
     let output = card.replace(/{%PRODUCT__NAME%}/g, product.productName);
    output = output.replace(/{%IMAGE%}/g, product.image);
    output = output.replace(/{%TIME%}/g, product.time);
    output = output.replace(/{%CHEF%}/g, product.Chef);
    output = output.replace(/{%SERVERS%}/g, product.servers);
    output = output.replace(/{%PRICE%}/g, product.price);
    output = output.replace(/{%ID%}/g, product.id);
    output = output.replace(/{%TITLE__ONE%}/g, product.titleOne);
    output = output.replace(/{%STEP__ONE%}/g, product.stepOne);
    output = output.replace(/{%TITLE__TWO%}/g, product.titleTwo);
    output = output.replace(/{%STEP__TWO%}/g, product.stepTwo);
    output = output.replace(/{%TITLE__THREE%}/g, product.titleThree);
    output = output.replace(/{%STEP__THREE%}/g, product.stepThree);
    output = output.replace(/{%TITLE__FOUR%}/g, product.titleFour);
    output = output.replace(/{%STEP__FOUR%}/g, product.stepFour);
    output = output.replace(/{%TITLE__FIVE%}/g, product.titleFive);
    output = output.replace(/{%STEP__FIVE%}/g, product.stepFive);


    if(!product.vegetarian) output = output.replace(/{%NOT__VEGETARIAN%}/g, 'not-vegetarian');
    return output;
}
```
+ For the url, you can use the url module. Then use url.parse method and pass req.url as an argument. As a result you will get a query object that tells you the id index. Adding true at the end will make the query output be an object.
```js
const {query, pathname} = url.parse(req.url, true);
```
```js
query: {id = "0"},
pathname : "/overview"
```
+ Use the query id to get the individual data for each element.
```js
const product = objData[query.id];
```
#### Result
<img src="https://i.ibb.co/26v41jG/day-32.gif" alt="day-32" border="0">

#### We are done
WOOOOOOO!!! This was a long post. But I hope It will help use build a simple API for yourself. 
When choosing a framework to learn, go for it and focus on the learning process. Don't be intimidated by others who have many languages under their belt. Remember to not, compare your beginning with someone's middle. 
Thank you for reading this far even if it was so long. As I learn more about node, I will continue positing.
This content/design/code is credited to [Jonas Udemy course - Node Bootcamp](https://www.udemy.com/course/nodejs-express-mongodb-bootcamp/)[The official Node Js docs](https://nodejs.org/dist/latest-v14.x/docs/api/)
 [W3School Node Js tutorial](https://www.w3schools.com/nodejs/default.asp)

<img src="https://i.ibb.co/ccKD0Rb/giphy.gif" alt="giphy" border="0"> 

#### Resources to learn Node Js
+ [The official Node Js docs](https://nodejs.org/dist/latest-v14.x/docs/api/)
+ [W3School Node Js tutorial](https://www.w3schools.com/nodejs/default.asp)
+ [Udemy Course by Andrew Mead] (https://www.udemy.com/course/the-complete-nodejs-developer-course-2/)
+ [Node Crash Course by Net Ninja on Youtube](https://www.youtube.com/playlist?list=PL4cUxeGkcC9jsz4LDYc6kv3ymONOKxwBU)
+ [Jonas Udemy course - Node Bootcamp](https://www.udemy.com/course/nodejs-express-mongodb-bootcamp/)