Idiomatic JavaScript Backend. Part 3
Tags: javascript, node, backend
Published: 2018-09-02 00:33:05

---
title: Idiomatic JavaScript Backend. Part 3
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 1/3](https://dev.to/k1r0s/idiomatic-javascript-backend-part-1-4g0b)
[Part 2/3](https://dev.to/k1r0s/idiomatic-javascript-backend-part-2-4lhe)

### 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
```
___
# 6. Creating and managing sessions

ritley doesn't offer an orthodox way to handle sessions.

The End!

Not kidding.. yeah, well but what ritley does best is to provide you tools to drop behaviors and requirements from method to method, modules and even projects.

Now, for the rest of the [requirements](https://github.com/k1r0s/ritley-tutorial/blob/master/REQUIREMENTS.md) such as showing a list of users or updating an user need clients to allow creating sessions by using its credentials.

Hence lets create a couple of users if you don't have any!

`$ curl -d '{ "name": "Randell Kovalsky", "mail": "rk@foo.b", "pass": "asd123"}' localhost:8080/users`

Create few users by using previous command, lets say 3 or 4 users its enough.

Now, remember about `src/resources/session.resource.js`? time to add a feature:

```js
import { AbstractResource } from "@ritley/core";
import SessionModel, { SessionInvalidCredentialsError } from "../models/session.model";

import {
  Default,
  MethodNotAllowed,
  Created,
  Throws,
  Unauthorized,
  BadRequest,
  Dependency,
  ReqTransformBodyAsync
} from "@ritley/decorators";


@Dependency("sessionModel", SessionModel)
export default class SessionResource extends AbstractResource {
  @Default(MethodNotAllowed) get() {}
  @Default(MethodNotAllowed) put() {}
  @Default(MethodNotAllowed) delete() {}

  constructor() {
    super("/sessions");
  }

  @Throws(SyntaxError, BadRequest)
  @Throws(SessionInvalidCredentialsError, Unauthorized)
  @Default(Created)
  @ReqTransformBodyAsync
  async post(req) {
    const body = await req.body;
    const payload = body.toJSON();
    const user = await this.sessionModel.validateCredentials(payload);
    return this.sessionModel.upsertSession(user);
  }
}
```
Lets review the requirements along with previous snippet:

- post method should create a session by identifying the client through user credentials
- validateCredentials just return the user from the database by comparing mail and password (encrypted).
- upsertSession method creates or updates the session. It always receive an user and returns a session with an expiration date of +30 minutes.
- get, put and delete methods must be explicitly rejected with HTTP 405
- file proper responses on each case: success, wrong json on payload, wrong credentials, errors during session creation.

You probably realized about we duplicated code on parsing payload from `src/resources/user.resource.js`. This is just temporal, we'll fix later on.

And we've added a dependency by the name of `sessionModel` where specific non-transporter-layer logic should be placed such as creating, updating, managing expiration, credential validation... I'm not going to paste but you can check the [code here](https://github.com/k1r0s/ritley-tutorial/commit/038234f2b00851bf0509f2910b88b9e5a85bbd59#diff-cf4f3ffbea6a6329c14f3b4ae92264c5).

So now, running the project again and executing this command on the term:

`$ curl -d '{ "mail": "<mail>", "pass": "<pass>"}' localhost:8080/sessions`

Now the server answers you with something like this:

`{"uid":"TjVNZy8yk","expiration":1535293179182,"userUid":"xqR16Gi7w"}`

Well, here sessions are very simple and unorthodox. Successful authentication is a json with the `uid` of the session, an expiration timestamp and the associated user's uid as `userUid`.

As defined on [requirements](https://github.com/k1r0s/ritley-tutorial/blob/master/REQUIREMENTS.md) to use that newly created session the client should provide a header `-H "x-session: <session_uid>"` on every call that requires a session.

For instance if we would list all registered users on the app we should do this:

`$ curl -H "x-session: TjVNZy8yk" localhost:8080/users`

Now we have to modify our `src/resources/user.resource.js` to fulfill __GET__ call:

```diff
 import { AbstractResource } from "@ritley/core";
 import UserModel, { UserValidationError, UserMailInUseError } from "../models/user.model";
+import SessionModel, { SessionNotCreatedError, SessionExpiredError } from "../models/session.model";
 
 import {
   Dependency,
   ReqTransformBodyAsync,
   Default,
   Throws,
   BadRequest,
   Conflict,
   Created
+  Ok,
+  Unauthorized
 } from "@ritley/decorators"; 

 @Dependency("userModel", UserModel)
+@Dependency("sessionModel", SessionModel)
 export default class UserResource extends AbstractResource {
   constructor() {
     super("/users");
@@ -23,11 +26,21 @@ export default class UserResource extends AbstractResource {
   @Throws(UserMailInUseError, Conflict)
   @Default(Created)
   @ReqTransformBodyAsync
   async post(req) {
     const body = await req.body;
     const payload = body.toJSON();
     await this.userModel.validate(payload);
     await this.userModel.isUnique(payload);
     return this.userModel.create(payload);
   }
+
+  @Throws(SessionNotCreatedError, Unauthorized)
+  @Throws(SessionExpiredError, Unauthorized)
+  @Default(Ok)
+  async get(req) {
+    const uid = req.headers["x-session"];
+    const session = await this.sessionModel.sessionExists({ uid });
+    await this.sessionModel.revalidate(session);
+    return this.userModel.searchBy();
+  }
 }
```

As you can see we've just added `get` method.

Now users are able to:

- create users and define credentials
- create a session using credentials
- list users using a session

Although there are some issues here:

- `user.resource.js` contains code that handles calls from sessionModel which is not explicitly related. though is relation is implicit by business rules. Se need to address that relationship more implicit. Because now involves mixing different domain concerns.

- Also, sessions management may involve errors that aren't related to users too.

- Next development cycles may include new resources, lets say /cities or something are we going to copy and paste code in order to manage sessions, payload parsing and all its error specific handling? (many people actually do)

___
# 7. Separation of concerns

How to address the problem with replication? 
 
Old school OOP programmers will try to group shared behaviors on upper classes and then, place specific behaviors as a subclasses but that's hard to scale, too many strong relationships, complex code bases.

On the other hand FP programmers will create a pipe of middlewares (req, res, next) that doesn't allow too much for building abstractions that can become something known as __middleware hell__. Functions are monoliths, to a certain point, in general, it doesn't scale quite well due to wrong encapsulation and side-effects problems.

I'm not here to argue against paradigms, I'm just trying to generally assess enterprise wide used solutions such as Spring, .NET and expressJS by its coding banner.

My point is that every paradigm or technique is good, but it doesn't make sense to use it to solve all problems like previous frameworks did.

__Both paradigms defined above doesn't avoid you to explicitly call them and hence deal with duplication at some point__. Completely get rid of duplication is impossible though but, problem with duplication isn't solely the amount of code that you have to paste all across your code base... is about dealing with lines of code that involve calls, assignments, sending arguments... more code, more to read, track, test, maintain, etc. By reading some method's code how you can tell if all code placed is related to the main concern? for instance:

```
increasePrice(amount) {
  ...requiredStuff1(amount)
  ...callAnotherService(this)
  ...etc
  this.price += amount;
  ...logThatPriceCorrectlyIncreases(this.price)
}
```
How many times you read some piece of code and then asked: __What this code is really doing?__, haven't you?

Lets try to decouple shared behaviors into something more portable and declarative.

Going back to our project, lets illustrate this by coding what I think is the solution to this problem: both `src/resource/user.resource.js` and `src/resource/session.resource.js` need to receive body payload, actually the do it by using `@ReqTransformBodyAsync`, but we still need to actually parse the body string to JSON and handle errors if any.

Would be nice if `@ReqTransformBodyAsync` solve the entire problem, right? __then we would be able to put our wonderful decorator on every single method that needs that chunk of behavior when we actually need it.__ We don't want to call `app.use()`.

Of course `@ritley/decorators` doesn't know what kind of stuff we need to do regarding on error handling, every project is different, you may need to call a Logger, who knows. It only provides request buffer concatenation which is the most basic that a library can do for you!

But, it allows you to __extend decorators__. Lets create a file on `src/decorators/req-body-json.decorator.js`:

```js
import { beforeMethod } from "kaop-ts";

import {
  BadRequest,
  ReqTransformBodyAsync
} from "@ritley/decorators";

function parseRequestBody(meta) {
  const [req, res] = meta.args;
  req.body.then(body => {
    try {
      const payload = body.toJSON();
      meta.commit(payload);
    } catch (e) {
      BadRequest(res, e.message);
    }
  })
}

export default beforeMethod(
  ...ReqTransformBodyAsync.advices(),
  parseRequestBody
)

```
![wat-decorators](https://cdn-images-1.medium.com/max/600/0*ju1bVBvFGchlK2YF)

Well, first we need to understand what `@ReqTransformBodyAsync` actually do:

> creates a promise that will resolve when Request payload will be fully received and it assigns it to `req.body`.

We're just extending this decorator by adding a behavior right after first one concludes.

Hence this new decorator contains the behavior of `@ReqTransformBodyAsync` and our custom function that basically tries to parse request payload into a json, if there is an error it will file a HTTP 400 Bad Request, if succeeds __it will execute the method that is decorating with an additional parameter which resolves to the json's payload.__

Don't panic if this sounds like Spanish for you. Let me show you this:

```diff
 import { AbstractResource } from "@ritley/core";
 import SessionModel, { SessionInvalidCredentialsError } from "../models/session.model";
+import ParseReqBody from "../decorators/req-body-json.decorator";
 
 import {
   Default,
@@ -7,9 +8,7 @@ import {
   Created,
   Throws,
   Unauthorized,
   BadRequest,
   Dependency,
-  ReqTransformBodyAsync
} from "@ritley/decorators";
 
 
@@ -25,14 +24,10 @@ export default class SessionResource extends AbstractResource {
     super(SessionResource.URI);
   }
 
-  @Throws(SyntaxError, BadRequest)
   @Throws(SessionInvalidCredentialsError, Unauthorized)
   @Default(Created)
-  @ReqTransformBodyAsync
+  @ParseReqBody
-  async post(req) {
+  async post(req, res, payload) {
-    const body = await req.body;
-    const payload = body.toJSON();
     const user = await this.sessionModel.validateCredentials(payload);
     return this.sessionModel.upsertSession(user);
   }
 }
```

That means both `src/resources/user.resource.js` and `src/resources/session.resource.js` will use it, so we can get rid of `SyntaxError` check too.

Now payload requirement is defined outside of the method code, like a dependency, but rather than a service, __you're injecting a behavior__. This is like middlewares on steroids.

Wonder that you can declare `@ResolveUploadedFile("/path/:filename")` on top of some method and, in the background, receive a request with a `multiplart/form-data` payload (a file), save the file into a predefined route, etc, and after all execute the method that you decorated like if nothing really happened? _Yes, we can_.

Lets create a decorator called `@ValidateSession` to clean up our `src/resources/user.resource.js` from non-related user domain:

```diff
 import { AbstractResource } from "@ritley/core";
 import UserModel, { UserValidationError, UserMailInUseError } from "../models/user.model";
-import SessionModel, { SessionNotCreatedError, SessionExpiredError } from "../models/session.model";
+import ParseReqBody from "../decorators/req-body-json.decorator";
+import ValidateSession from "../decorators/validate-session.decorator";
 
 import {
   Dependency,
   Default,
   Throws,
   BadRequest,
   Conflict,
   Created,
   Ok,
-  ReqTransformBodyAsync,
-  Unauthorized
 } from "@ritley/decorators";
 
 @Dependency("userModel", UserModel)
-@Dependency("sessionModel", SessionModel)
 export default class UserResource extends AbstractResource {
   constructor() {
     super("/users");
   }
 
-  @Throws(SyntaxError, BadRequest)
   @Throws(UserValidationError, BadRequest)
   @Throws(UserMailInUseError, Conflict)
   @Default(Created)
-  @ReqTransformBodyAsync
+  @ParseReqBody
-  async post(req) {
+  async post(req, res, payload) {
-    const body = await req.body;
-    const payload = body.toJSON();
     await this.userModel.validate(payload);
     await this.userModel.isUnique(payload);
     return this.userModel.create(payload);
   }
 
-  @Throws(SessionNotCreatedError, Unauthorized)
-  @Throws(SessionExpiredError, Unauthorized)
   @Default(Ok)
+  @ValidateSession
-  async get(req) {
+  get(req) {
-    const uid = req.headers["x-session"];
-    const session = await this.sessionModel.sessionExists({ uid });
-    await this.sessionModel.revalidate(session);
     return this.userModel.searchBy();
   }
 }

```

And now, remember that code related with the session management? We moved this to a proper separate location. We've created another folder:

```
src/
├── config
│   ├── database.config.js
│   └── lowdb.json
├── decorators
│   ├── req-body-json.decorator.js
│   └── validate-session.decorator.js
├── index.js
├── models
│   ├── session.model.js
│   └── user.model.js
├── resources
│   ├── session.resource.js
│   └── user.resource.js
└── services
    ├── database.service.js
    └── encrypt.service.js
```

To recap, session and user `resources` both share payload management, so we've created a decorator that encapsulates required behavior to parse req body and then we've defined on both resources. We did similar with session requirement since next feature _edit users_ will rely on it. 

So, as you can see, ritley provides OO standards in order to deal with basic architecture and separation of concerns but enhances it with FP extensions as middleware decorators that can be plugged before a method, after a method, if method throws an error. So that's pretty neat. 

___
# 8. Everybody's concern, scalability

Do I need to explain you how to write scalable apps? If you are still here you might know a few tips on this. Isn't solely a matter of which tools you choose, it certainly impact but most of times is all about decisions that you did… or indeed the framework did.

__ritley__ only took decisions on http/transport layer. That means you are the only one to blame on other concerns. it scares right? Some might see it as a _redemption_.

As you saw on previous parts during this tutorial, plain, __simple__, well understood architectures empowers developers to write better code.

Now we need to add the last feature, user edition. Lets add a PUT method handler on `src/resources/user.resource.js`:

```js
@Throws(UserInsufficientPermError, Forbidden)
@Default(Ok)
@ValidateSession
@ParseReqBody
@ReqTransformQuery
put(req, res, session, payload) {
  return this.userModel.putUser(req.query.uid, session.userUid, payload);
}
```
> Have you noticed that request payload will not be parsed if user doesn't have a valid session? decorator order does matter :D, simply because it goes before [top-to-down]. 

That's all we've to do on our http layer.

Note that, we are calling `putUser` on `src/models/user.model.js`. Lets see whats new here:

```diff
@@ -43,6 +43,14 @@ export default class UserModel {
     }
   }
 
+  isAllowedToEdit(requestedUserUid, currentUserUid) {
+    if(requestedUserUid === currentUserUid) {
+      return Promise.resolve();
+    } else {
+      return Promise.reject(new UserInsufficientPermError);
+    }
+  }
+
   update(uid, { mail, name }) {
     return this.database.update("users", { uid }, { mail, name });
   }
@@ -50,6 +58,10 @@ export default class UserModel {
   postUser(payload) {
     return this.validate(payload).then(() => this.isUnique(payload).then(() => this.create(payload)));
   }
+
+  putUser(requestedUserUid, currentUserUid, payload) {
+    return this.isAllowedToEdit(requestedUserUid, currentUserUid).then(() => this.update(requestedUserUid, payload));
+  }
 }
 
 export class UserValidationError extends Error {
@@ -63,3 +75,9 @@ export class UserMailInUseError extends Error {
     super("mail is already taken, try another one")
   }
 }
+
+export class UserInsufficientPermError extends Error {
+  constructor() {
+    super("you don't have permissions to perform this action")
+  }
+}
```

That means an user can only update its own profile.

Lets try this by running a curl command:

`$ curl -X PUT -H "x-session: <session_uid>" -d '{ "name": "Jean-Luc Godard"}' localhost:8080/users?uid=<target_user_uid>`

You get back either a verbose error or newly updated user.

You may noticed to handle querystring parameters and access req.query we've added `@ReqTransformQuery` on `put` method. Now you may be asking: "_Do I have to add a decorator for every single case?_". If you're building a more complex application you probably need to define a more complex class base, instead of pile 7 decorators per method you might extend your resources from `MyAbstractResource` rather of generic ritley's `AbstractResource`. You may need to build a framework on top of this LMAO.

This chapter is completed. Now users can change their names! (...)

Some tips on scalable software:

__As always, try to scale horizontaly__, avoid more than two levels of inheritance on classes, remember that you can extend decorators that fit best your case, etc.

For instance previous feature we just added on edit users only involved additions on the commit, we didn't change previous code. __Thats the gold rule for scalability__.

Any chunk of code non-related to any feature should be easy to extend, but not suited for modification.

You should not try to abstract your business logic since you don't even known whats going next. As a programmer you need to represent business logic as it is and deal with infrastructure code with abstraction and modular approaches. That is what defines software quality.

For example our specific decorators that target session management defines a closed design which can be easily extended since most of business logic is defined on models and decorator it self only provides the glue to attach it into classes. 

Common problems related with scalability like huge code changes of unrelated domains are due to bad/closed design _when you cannot access this service from here because there is another service that is doing nasty stuff on the background_.. most likely due to miss placed responsibility. 

Your job is always to keep concerns on separated layers.

___
# 9. Conclusion

__ritley__ its a very simple concept. It was created 9 months ago but completely rewrited to be released as OSS. The basic concept is to provide common patterns on transport layer without wrapping nodejs documentation. In fact it only dispatch request to the proper handler by mapping your classes, hence [its quite fast](https://github.com/k1r0s/ritley/tree/master/benchmark), well tested, and easy to master since you don't need to learn anything that you probably known if you're a casual node developer. 

Library core is less than 80 lines (at the time I'm writing this) and likely will remain quite simple. Though library extension `@ritley/decorators` is about 200 lines. Even though is still small in comparison to other frameworks.

Congratulations comrade. Did you enjoy the article? let me know your thoughts down below or lets chat on [twitter](https://twitter.com/k1r0s) :) thank you ❤

Did you like the idea about the library? [Do you want to contribute](https://github.com/k1r0s/ritley)? I'm always open to new ideas!

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