mr-use-case
TypeScript icon, indicating that this package has built-in type declarations

0.8.1 • Public • Published

Mr.UseCase

Node.js CI Tests

The perfect way to wrap your business logic fast and properly.

Mr.UseCase

Introduction

These use cases orchestrate the flow of data to and from the entities, and direct those entities to use their Critical Business Rules to achieve the goals of the use case.

📖 Clean Architecture book

The UseCase layer allows you to achieve significant benefits in the following parts of writing code:

  • Make development process clear for all participants
  • Speed up the development of production-ready projects
  • Avoid complexity
  • Reduce coupling

So, developers and use cases have to be friends🤝 forever at least for reasons outlined above.

Installation

Just one step.

npm i mr-use-case

And use it where you need it.

import { MrUseCase } from 'mr-use-case';

Localization

As well you have an option to localize errors through error builder customization:

import { MrUseCase } from 'mr-use-case';
import { ErrorsBuilder } from './errors.builder';

export function UseCase<T, R>() {
  return MrUseCase<T, R>({ errorsBuilder: ErrorsBuilder });
}

Read more about it on 🥞 Mr.Error page.

Overview

This section contains a simple use case that shows us an example of Mr.UseCase implementation. Let's take a quick look at the following piece of code:

import { MrUseCase } from 'mr-use-case';
import { User } from '$path';
import { isEmail } from '$path';

interface Request {
  email: string;
}

interface Response {
  user: User;
}

export class UserCreateCase extends MrUseCase<Request, Response>() {
  private position?: UserPosition;
  private positionValidated: UserPosition;

  // process

  async process() {
    await this.assignVariables();

    await this.validate(); // calls checks()

    const user = await User.create({
      email: this.request.email,
      positionId: this.positionValidated.id,
    });

    return { user };
  }

  // private

  protected async checks() {
    if (!this.request.email) {
      this.errors.add('email', 'presence');
    }

    if (!isEmail(this.request.email)) {
      this.errors.add('email', 'format');
    }

    if (!this.position) {
      this.errors.add('email', 'positionFind');

      return;
    }

    this.positionValidated = this.position;
  }

  private async assignVariables() {
    this.position = await findAvailablePosition();
  }

  private async findAvailablePosition() {
    // ...
  }
}

As you can see, the code is split into four parts:

  1. Assigning a variable area
  2. Validation
  3. Execution
  4. Packing response

Keep in mind that one use case must fullfil only one business purpose and give a straight answer about the success of the operation after the call.

Now let's see how we may use it in the positive scenario:

const email = 'example@example.com';
const { user } = await UserCreateCase.call({ email });

return user; // => created user

However, what happens if the passed value is not an email? Let's change our code and see.

const email = 'wrongemail';

try {
  const { user } = await UserCreateCase.call({ email });
} catch (err) {
  if (err instanceof MrError) {
    debug(err.errors.messages());

    return;
  }

  throw err;
}

In this scenario our use case throws an exception containing all errors that were caught by the validation process. You may read more about the errors format at 🥞 Mr.Error page.

Let's make a conclusion.

⚠️ At this moment you probably would like to see an integration of the module to something more ready to use. And specifically for this purpose 🐨 Mr.Koa boilerplate exists.

Conclusion

The use cases make your work much simpler, more structured and efficient. And Mr.UseCase pleasantly provides an interface to enjoy these advantages with no headache.

Give it a try!

Readme

Keywords

Package Sidebar

Install

npm i mr-use-case

Weekly Downloads

6

Version

0.8.1

License

ISC

Unpacked Size

11.7 kB

Total Files

4

Last publish

Collaborators

  • donivnpm