Quick ramp-up with NodeJS
Tags: node, tutorial, beginners, webdev
Published: 2020-11-22 16:39:49

Last Friday I was keeping a presentation with my colleague about web development for #mimmitkoodaa (freely translated: women who code) audience. [Mimmitkoodaa](https://mimmitkoodaa.ohjelmistoebusiness.fi/in-english/) program is basically developed for advocating diversity and gender balance in the IT industry. This particular event called ThisIsNotAWebinar was targeted especially for people who are starting their career in IT either by studying it in the first place or transferring from another field of expertise.

I and my co-presenter are both full-stack developers so we divided the presentation so that she told about frontend development with [ReactJS](https://reactjs.org/) and I told about backend development with NodeJS. In case someone is now starting with [NodeJS](https://nodejs.org/), I'll show our example app from the presentation. It shows how to get easily started with backend development. In this example, we are creating a small todo-board app, where the user can add post-it notes, modify and remove them, and give them likes. In this post I will go through setting up the backend project, creating the base of the server, and one endpoint (GET) to get started. The rest of the endpoints, database setup, and the whole application code with a lot of comments, and with a fully functional ReactJs frontend is in [Gitlab](https://gitlab.com/vincit/mimmit-koodaa-2020/muistitaulu-sovellus)

Getting started with backend development is very easy. There's no need to have any boilerplate starter packs or anything, it's very easy to just start writing code. Here are the basic steps:
A) Install [NodeJS](https://nodejs.org/), LTS version is fine if you don't want to live on the edge
B) Create an empty folder for your project
C) In that folder, create file `index.js`
D) Insert some code into that file (we'll get back into that step)
E) Install dependencies with  the command `npm install` (more about that later)
F) Run by typing `node index.js` in your folder in the console of your choice (terminal, Powershell, or similar, depending on your platform)

That's it! Let's now take a closer look at step D, where we add the code into that `index.js` file. I have a small example app here:
```
const Koa = require('koa');
const port = 8000;
const app = new Koa();
app.listen(port, () => {
  console.log("App running in port: " + port);
});
```
You can do your server with pure Node, but if you are building a little bit bigger app than just Hello World, you probably want to include some kind of helper framework that provides routing for your endpoints. In this example, I have used [Koa](https://koajs.com/). It's a modern framework from the makers of [Express](https://expressjs.com/) if that's a more familiar name for someone. Let's break down the code line by line:

1) We take Koa into use by requiring it
2) We define the port number we want to use for our server
3) We create a Koa app object which acts as our server
4-6) The app object has a method called "listen", which starts the server. It takes the port we defined as a parameter

Next, we can move on to step E where we install dependencies. As we use Koa, that is now our dependency, so we run `npm install koa`. That will install the Koa module to be used in our app.

This is all we need so far to get the server running. At this point, if you run `node index.js` you should see your app printing `App running in port: 8000` in the console.

This application does not yet do anything. The next step is to add at least one endpoint. For simplicity, we are here using a more traditional [REST (Representational State Transfer)](https://en.wikipedia.org/wiki/REST) model for our interface. It operates on [HTTP (Hypertext Transfer Protocol)](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) standard methods `GET (for fetching resources), POST (for adding resources), PATCH (for modifying resources), DELETE (for deleting resources)`, and a few others. If you want to look into something more modern, e.g. [GraphQL](https://graphql.org/) is a good option. Here we have some new piece of code I added between the creation of the Koa app object (line 3) and starting the server (line 4):
```
var Router = require('koa-router');
var router = new Router();
router
  .get('/items', async (ctx, next) => {
    // TODO: add implementation here
  })
app.use(router.routes());
```
Let's once again go through it line by line.
1) We take the Koa-router module into use. This allows us to create routes for the application. Routes are used for identifying which resource we are getting, adding, deleting, or modifying.
2) We create a Koa router object, similar than we did with the Koa app object.
3-6) This will create our first endpoint. In this example, we have a generic resource called items. This endpoint will allow fetching of all items we have stored in our server.
7) The Koa app object has a method called "use". This allows adding some functionality called middleware. Middleware can react to the requests coming to the server. This line takes all the defined routes into use.

Next, we are going to implement the GET items endpoint. Following code needs a little bit more preparation. If we want to store some data in the backend, we'll need a database. Generally, you would create and use a proper database like [PostgreSQL](https://www.postgresql.org/), [MySQL](https://www.mysql.com/), or [MongoDB](https://www.mongodb.com/), or another similar one, but setting up any of those is beyond this post so we are using a temporary text file-based database module for Node called [node-persist](https://www.npmjs.com/package/node-persist). Node-persist is a key-value based storage that allows storing data temporarily. In the example code, we have set up the database to expire its data after one week. The setup for the database is done like this:
```
(async () => {
  await storage.init({
    dir: 'storage',
    expiredInterval: 1000 * 60 * 60 * 24 * 7
  });
})();

```
Addition to setting the expiration interval, we also define the folder for the database to use for storing our notes. Take a look at the whole [source code file](https://gitlab.com/vincit/mimmit-koodaa-2020/muistitaulu-sovellus/-/blob/master/server/index.js) to see where to put it. Also after using the Koa router and the node-persist database, before running our project again, we need to install new dependencies. Run "npm install koa-router node-persist". Let's now take a look at the implementation of a GET endpoint:
```
const ITEM_PREFIX = 'item_';
router
  .get('/items', async (ctx, next) => {
    let allPostIts = await storage.valuesWithKeyMatch(ITEM_PREFIX);
    ctx.response.body = JSON.stringify(allPostIts);
    return ctx.status = 200;
  })
```
Break up into lines of code:
1) We define ITEM_PREFIX. This is because node-persist is key-value based, and we need a way to identify each note item. Node-persist does not provide any help for using a running item counter to have keys for the items as a running number like ID property in a normal database. For this purpose, we have our own item counter which we also store in the database. Because we store both the items and the counter, we need to have the ITEM_PREFIX added to those IDs which refers to the actual note items. To get a closer look at how we have been saving the note items and the counter in the database, check endpoint POST items from the complete code file.
2-3) This is already familiar from the previous code example
4) This line fetches all items from the database whose key matches with our ITEM_PREFIX. This basically then fetches all the note items we have there and excludes the item counter itself.
5) Rest is easy, we just stringify the results for giving them to the frontend as a JSON string instead of a Javascript object.
6) The last thing is to return HTTP status 200 which means everything went OK.

This can look a little bit overwhelming at first sight if you are a beginner, but this is still much easier than to set up the frontend side of the project ;)
If you want to see your app up and running, you need to either set up the frontend from [Gitlab](https://gitlab.com/vincit/mimmit-koodaa-2020/muistitaulu-sovellus/-/tree/master/client) or you can poke around the API endpoints with [Hoppscotch](https://hoppscotch.io/) or [Postman](https://www.postman.com/). You'll find your notes by `GET http://localhost:8000/items`. By posting
`{"text": "Remember to buy milk!", "likes": "0"}` into `POST http://localhost:8000/items` you'll add a new item with text "Remember to buy milk!". If you created new item and it got ID 1, you can now add like by posting `POST http://localhost:8000/items/1/like` You can check further instructions from the manual of the API tool you decided to use if you are not yet familiar how to send requests using any of them. With that note, I hope you enjoyed this small ramp up guide.