Idiomatic JavaScript Backend. Part 1
Tags: javascript, node, backend
Published: 2018-08-31 20:24:12

---
title: Idiomatic JavaScript Backend. Part 1
published: true
description: Curated step by step tutorial about writing nodeJS app using ritley
tags: javascript, node, backend
---

Hi everyone! This part of series __Idiomatic JavaScript Backend__.

[Part 2/3](https://dev.to/k1r0s/idiomatic-javascript-backend-part-2-4lhe)
[Part 3/3](https://dev.to/k1r0s/idiomatic-javascript-backend-part-3-1eii)

### Important Information

For best experience please clone this repo: [https://github.com/k1r0s/ritley-tutorial](https://github.com/k1r0s/ritley-tutorial). It contains __git tags__ that you can use to travel through different commits to properly follow this tutorial :)

```
$ git tag

1.preparing-the-env
2.connecting-a-persistance-layer
3.improving-project-structure
4.creating-entity-models
5.handling-errors
6.creating-and-managing-sessions
7.separation-of-concerns
8.everybody-concern-scalability
```

Go to specific tag

```
$ git checkout 1.preparing-the-env
```

Go to latest commit

```
$ git checkout master
```


See differences between tags on folder `src`

```
$ git diff 1.preparing-the-env 2.connecting-a-persistance-layer src
```

___
# 0.What

Hi everyone! today's topic is about building an App with NodeJS.

What we're gonna do? We will build a service for allowing users to:

- create its own profile
- create a session
- list other users
- edit its own user

And…

We're going to use `cURL`!

Its not relevant to check, but you can click here to see the full [requirements](https://github.com/k1r0s/ritley-tutorial/blob/master/REQUIREMENTS.md) on what this app should fulfill.

Now I'm going to slowly build it from scratch!
___
# 1. Preparing the environment

Let's do our "Hello World" with [ritley](https://github.com/k1r0s/ritley) to get started:

```
.
├── .babelrc
├── package.json
└── src
    └── index.js
```

In this tutorial we're going to use [Babel](https://babeljs.io/). To do so with nodejs we need `babel-node` to run our app. So this is our package.json:

```json
{
  "name": "tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "babel-node src"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@ritley/core": "^0.3.3",
    "@ritley/standalone-adapter": "^0.2.0",
  },
  "devDependencies": {
    "@babel/core": "^7.0.0-beta.55",
    "@babel/node": "^7.0.0-beta.55",
    "@babel/plugin-proposal-class-properties": "^7.0.0-beta.55",
    "@babel/plugin-proposal-decorators": "^7.0.0-beta.55",
    "@babel/plugin-transform-async-to-generator": "^7.0.0-rc.1",
    "@babel/preset-env": "^7.0.0-beta.55"
  }
}
```

Why `@ritley/core` and `@ritley/standalone-adapter` ? :|

As __ritley__ is quite small, many features are separated on different packages. As core is indeed required,  standalone adapter too because we're going to run a node server by ourselves here. _If you're on serverless environments such as firebase you can keep going without it_.

This would be our `.babelrc`:
```json
{
  "presets": [["@babel/preset-env", {
    "targets": {
        "node": "current"
      }
    }]],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": false }],
    ["@babel/plugin-transform-async-to-generator"]
  ]
}
```

And our _hello world_ `src/index.js`:

```js
import { setAdapter, AbstractResource } from "@ritley/core";
import Adapter from "@ritley/standalone-adapter";

setAdapter(Adapter, {
  "port": 8080
});

class SessionResource extends AbstractResource {
  constructor() {
    super("/sessions");
  }

  get(req, res) {
    res.statusCode = 200;
    res.end("Hello from sessions!");
  }
}

class UserResource extends AbstractResource {
  constructor() {
    super("/users");
  }

  get(req, res) {
    res.statusCode = 200;
    res.end("Hello from users!");
  }
}

new SessionResource;
new UserResource;

```

In previous snippet we import `standalone-adapter` and we bind it to the core by calling `setAdapter(<adapter> [, <options>])`. This will create and bind a new [HttpServer](https://nodejs.org/api/http.html#http_class_http_server) to any `AbstractResource` subclass. [You can check how it works](https://github.com/k1r0s/ritley#how-it-works).

When building a ritley app you've to choose an adapter. That defines how requests are sent to resources.

__ritley__ uses [https://nodejs.org/api/http.html](https://nodejs.org/api/http.html) `(req, res)`api so probably you're quite familiar with it. 

Note that we've created two similar classes, we could do this instead:

```js
import { setAdapter, AbstractResource } from "@ritley/core";
import Adapter from "@ritley/standalone-adapter";

setAdapter(Adapter, {
  "port": 8080
});

class DefaultResource extends AbstractResource {
  get(req, res) {
    res.statusCode = 200;
    res.end(`Hello from ${this.$uri}`);
  }
}

new DefaultResource("/sessions");
new DefaultResource("/users");

```

Anyways we're going to keep it separated as both resources will start diverge quite soon.

now you can `$ npm start` and then run some curl commands to see if everything is working properly:

`$ curl localhost:8080/users`
`$ curl localhost:8080/sessions`

This is our first step!

___
# 2. Connecting a persistence layer

We need to have some kind of persistence layer. We're going to install [lowdb](https://github.com/typicode/lowdb) because we don't need too much overhead for now.

Everyone favorite part: _its time to install new dependencies!_:

`$ npm install lowdb shortid`

However we need to keep in mind that any dependency, whatever we attach to our project, should be easy to replace. That's we're going to wrap lowdb into an interface with "CRUD alike" methods to keep things extensible.

Lets continue by implement our `database.service.js` using __lowdb__:

```js
import low from "lowdb";
import FileAsync from "lowdb/adapters/FileAsync";
import config from "./database.config";
import shortid from "shortid";

export default class DataService {
  onConnected = undefined

  constructor() {
    this.onConnected = low(new FileAsync(config.path, {
      defaultValue: config.defaults
    }))
  }

  create(entity, newAttributes) {
    return this.onConnected.then(database =>
      database
      .get(entity)
      .push({ uid: shortid.generate(), ...newAttributes })
      .last()
      .write()
    )
  }
}

```

For now we only implement `create` method. That's fine now.

```
.
└── src
    ├── database.config.js
    ├── database.service.js
    ├── index.js
    └── lowdb.json
```

Our project is growing fast! We've created `database.config.js` too which contains important data that may be replaced quite often so we keep it here:

```js
export default {
  path: `${__dirname}/lowdb.json`,
  defaults: { sessions: [], users: [] }
};
```

__You can skip this paragraph if you've already used lowdb__. Basically you need to specify the actual path of the physic location of the database, since it doesn't need a service like other database engines. Hence lowdb is way simpler and fun to play with, though less powerful and should not be used to build enterprise projects. That's why I'm wrapping the whole lowdb implementation on a class that exposes crud methods, because its likely to be replaced anytime.

And now, we've changed our `src/index.js` to properly connect database to controllers:

```diff
@@ -1,5 +1,6 @@
 import { setAdapter, AbstractResource } from "@ritley/core";
 import Adapter from "@ritley/standalone-adapter";
+import DataService from "./database.service";
 
 setAdapter(Adapter, {
   "port": 8080
@@ -17,15 +18,18 @@ class SessionResource extends AbstractResource {
 }
 
 class UserResource extends AbstractResource {
   constructor() {
     super("/users");
+    this.database = new DataService;
   }
 
-  get(req, res) {
-    res.statusCode = 200;
-    res.end("Hello from users!");
+  post(req, res) {
+    this.database.create("users", { name: "Jimmy Jazz" }).then(user => {
+      res.statusCode = 200;
+      res.end(JSON.stringify(user));
+    });
   }
 }
 
 new SessionResource;
 new UserResource;

```

We've changed as well our get method to a __post__ to emulate a real case of creation request. By running this command we get back the newly created data!

`$ curl -X POST localhost:8080/users`

Check `src/lowdb.json` to see the changes!

Okay so, we just connected __lowdb__ and run our first insertion!

___
# 3. Improving the project structure

We need to organize a bit our project.

First we're going to arrange our folders like this:

```
// forthcoming examples will only show src/ folder
src/
├── config
│   ├── database.config.js
│   └── lowdb.json
├── index.js
├── resources
│   ├── session.resource.js
│   └── user.resource.js
└── services
    └── database.service.js
```

Now lets remove a bit of code from `src/index.js` in order to have only the following:

```js
import { setAdapter } from "@ritley/core";
import Adapter from "@ritley/standalone-adapter";

import SessionResource from "./resources/session.resource"
import UserResource from "./resources/user.resource"

setAdapter(Adapter, {
  "port": 8080
});

new SessionResource;
new UserResource;
```

So basically we moved our controllers (aka resources) to a separated folder called `resources`.

Next is to setup Dependency Injection on `src/resources/user.resource.js` to be able to inject an instance of our database service.

In order to do so we're going to install an extension package called `@ritley/decorators`:

`$ npm install @ritley/decorators`

Then, lets make a few changes on `src/services/database.service.js` to be exported as a singleton provider:

```diff
 import config from "../config/database.config";
+import { Provider } from "@ritley/decorators";

+@Provider.singleton
 export default class DataService {
   onConnected = undefined
```
By adding `@Provider.singleton` we will be able to construct only one instance every time the provider gets executed. That means all classes that declare it as a dependency __will share the same instance__.

Lets add it to `src/resources/user.resource.js`:

```diff
 import DataService from "../services/database.service";
+import { Dependency, ReqTransformBodySync } from "@ritley/decorators";
 
+@Dependency("database", DataService)
 export default class UserResource extends AbstractResource {
   constructor() {
     super("/users");
-    this.database = new DataService;
   }
 
+  @ReqTransformBodySync
   post(req, res) {
+    const payload = req.body.toJSON();
+    this.database.create("users", payload).then(user => {
-    this.database.create("users", { name: "Jimmy Jazz" }).then(user => {
       res.statusCode = 200;
```
`@Dependency` executes DataService (now its a provider) then receives an instance and assigns it as a named property __after class local constructor gets executed__.

So basically we removed complexity that involves service instantiation on controllers. I guess you're familiar with [these practices](https://en.wikipedia.org/wiki/Dependency_injection#Setter_injection).

You may noticed that we've also removed hardcoded payload and we've placed `@ReqTransformBodySync` on top of the post method.

This decorator allows to access request body or payload by __delaying method execution till its fully received__. Like [body-parser](https://www.npmjs.com/package/body-parser) does but more explicit because you don't need to bother yourself reading method contents to know that it requires payload to properly work, and its more pluggable since you can configure at __method level__.

Now try to execute this command:

`$ curl -d '{ "name": "Pier Paolo Pasolini" }' localhost:8080/users`

> -X POST is assumed if -d (payload) is provided.

You should reveive a HTTP 200 OK response with ur new user created! Check database contents :)

That's all for now folks! On next chapter on series we will see how ritley manages to link models with controllers, handle exceptions and manage sessions.

![ritley from metroid](https://thepracticaldev.s3.amazonaws.com/i/7q8l002pngb479ra00l3.jpeg)