Giter VIP home page Giter VIP logo

santiq / bulletproof-nodejs Goto Github PK

View Code? Open in Web Editor NEW
5.4K 112.0 1.2K 974 KB

Implementation of a bulletproof node.js API ๐Ÿ›ก๏ธ

Home Page: https://softwareontheroad.com/ideal-nodejs-project-structure/

License: MIT License

JavaScript 21.63% TypeScript 76.31% Shell 1.29% Dockerfile 0.77%
nodejs node javascript typescript boilerplate express mongodb mongoose typedi agendajs

bulletproof-nodejs's People

Contributors

basarat avatar captdaylight avatar deluxateer avatar dependabot[bot] avatar diomalta avatar eliancordoba avatar gineremanuel avatar gusinacio avatar hosseinnedaee avatar jackson-elfers avatar jakemraz avatar joserfelix avatar kuzmrom7 avatar lakshitaverma avatar mrailton avatar nisarhassan12 avatar norflin321 avatar noticemaker avatar orozcoadrian avatar praneshasp avatar radomirperisic avatar santiq avatar sayyidyofa avatar simbig avatar tahsinature avatar ukmadlz avatar wanderrful avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bulletproof-nodejs's Issues

TS error Logger.error

src/subscribers/user.ts:29:14 - error TS2339: Property 'error' does not exist on type 'unknown'


import { Container } from 'typedi';

const Logger = Container.get('logger');
Logger.error(`๐Ÿ”ฅ Error on event ${events.user.signIn}: %o`, e);

But if I do the next code - everything is fine

import Logger from '../loaders/logger';
Logger.error(`๐Ÿ”ฅ Error on event ${events.user.signIn}: %o`, e);

As I can see. typedi do not see levels in Container.
How can I fix this ?

await userRecord.save(); can not save data to mongodb

Hi, i found that call save() not work when I'd like to save data to database.

code as follows:

 const userRecord = await this.userModel.create({
                ...userDTO,
                salt,
                password: hashedPwd,
            });

            // save to database
            await userRecord.save();

endpoint api works well, and return

{
    "user": {
        "role": "user",
        "_id": "5ed08b923de44903c4ad5320",
        "name": "admin",
        "email": "404398jiwerewtwr34235kjgelg",
        "createdAt": "2020-05-29T04:12:02.662Z",
        "updatedAt": "2020-05-29T04:12:02.662Z",
        "__v": 0
    },
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZWQwOGI5MjNkZTQ0OTAzYzRhZDUzMjAiLCJyb2xlIjoidXNlciIsIm5hbWUiOiJhZG1pbiIsImV4cCI6MTU5MDcyNTUyMi42NzYsImlhdCI6MTU5MDcyNTUyMn0.oy4IP3sZ6sga12-yjXZN9sr03fx4V3c-KFWF_Jq_OWM"
}

but in my mongodb docker container,
I search users by users.find({}),
error comes out as follows:

2020-05-29T04:07:49.242+0000 E  QUERY    [js] uncaught exception: ReferenceError: users is not defined :

Any help will be appreciated.
BTW, this architecture is good, but seems not suitable for small project. :(
It takes several hours for me to figure out how it works.

Thanks

Model not getting injected while unit/integration test

Hello , I am facing issue for getting injected model instance in test case
here is the detail

I have test file called
inventory.service.test.ts

import { Container } from 'typedi';
import InventoryService from '../../../src/services/inventory';
import { random } from '../../util';
import express from 'express';
import loaders from '../../../src/loaders';
import Inventory from '../../../src/models/inventory';
import startServer from '../../../src/server';

let body;
beforeAll(async done => {
  // const expressApp = express();
  // await loaders({ expressApp });
  await startServer();
  body = random.inventory();
  done();
});

describe('Inventory Service', () => {
  it('should add inventory', async () => {
    const InventoryModel: typeof Inventory = Container.get('InventoryModel');
    const Logger = Container.get('logger');
    const inventoryService = new InventoryService(InventoryModel, Logger);
    const { inventory } = await inventoryService.addInventory(body);
    expect(inventory).toBeDefined();
    expect(inventory.id).toBeDefined();
    expect(inventory.title).toBe(body.title);
  });
});

when I do like above, all test cases passes.

now I am trying to start up the server in global.setup.ts file, not in beforeAll of each test case file

so I am doing like that in jest.config.ts file

// A path to a module which exports an async function that is triggered once before all test suites
  globalSetup : "./tests/jest/globalSetup.ts",

// A path to a module which exports an async function that is triggered once after all test suites
  globalTeardown : "./tests/jest/globalTearDown.ts",

and I have added 2 files

globalSetup.ts

import startServer from '../../src/server'
const globalSetup = async () => {
    await startServer();
}

export default globalSetup;

and in globalTearDown.ts


const globalTearDown = async () => {
    // will close down that server instance
}

export default globalTearDown 

when I do test now it is throwing an error like below

_ServiceNotFoundError: Service "InventoryModel" was not found, looks like it was not registered in the container. Register it by calling Container.set("InventoryModel", ...) before using service._

Question: How to write a unit test for service layer

I'm trying to write unit tests for service layer bu failing to create mock dependencies, mock Models mock EventDispatcher. Can anyone write an example unit test or at least show me the way to write them? Just one simple test example would help me progress so much, I can take it from there and write other tests by taking it as a reference. Thanks!

found 21 vulnerabilities (15 moderate, 6 high)

fixed 0 of 21 vulnerabilities in 863967 scanned packages
  13 vulnerabilities required manual review and could not be updated
  2 package updates for 8 vulnerabilities involved breaking changes
  (use `npm audit fix --force` to install breaking changes; or refer to `npm audit` for steps to fix these manually)

Question: How to handle multiple exceptions throwed by Services?

I read your article and checked your pattern and I was surprised that my architecture is very similar to yours. But I not found one thing I am searching for quite for a while:

How to handle more errors from Service? For example I have Service User with method activateUser. This method recieve activation token and based on token's validity (user not already active, token exists, token not expired, user exists) I activate user or not.

The problem is that there is lot of things what can go wrong and throwing just one type of error is not good for clients. I am using i18n so I am translating keys to texts inside my controller.

Should I just throw those keys from my Service?

Now I am just trying to have every service method to do one thing so I can throw 1 error. But then I am moving too much stuff into controller:

  1. Does user exists?
    If not throw not exists error
  2. Is user already active?
    If not throw already active error
  3. Is token not expired?
    If not throw token expired error
  4. Does database update failed?
    If not throw error while saving error

This is just example and I have much more of this trough project, where I have controller full of one-time-use services because I need to return different error messages for each one of them.

Hope you understand my frustration and have some more expirience what you can share :)

Events and jobs

Hey,

Thank you for this repo. 2 questions for you:

Where do you use the events?
Where do you put the line between a job and an event?

Imports with *

Hi!
Why are imports constantly used with "*" ?

import * as express from 'express';

Maybe I will add to the config ?

"esModuleInterop": true

And fix import on project?

Problem in winston instance with typescript

Problem

When the logger is instance by decorators it works fine with this.logger.error() the ts recognizes the methods.
image

But calling through a container typescript does not understand that there are methods(error, info and debug).
image

This is error what typescript return
image

Dependency Injection in tests

Hey @santiq

First of all thank you so much for your articles and boilerplate code, you're a true inspiration and a great teacher.

Sorry to bother you if you're busy right now, I'm having some trouble with the dependency injection while testing the authentication process.

I get an error telling me the logger/userModel/eventDispatcher instances injected in the AuthenticationService constructor are undefined, the call stack traces back my users.ts route.

That just seems to happen If I instantiate the AuthenticationService in my test before calling the route, instantiation can either be by TypeDi container or by calling the AuthenticationService directly.


Here's the route I'm testing:

users.ts

import { Router, Request, Response, NextFunction } from 'express';
import { celebrate, Segments } from 'celebrate';
import User, { userJoiSchema } from '../../models/user';
import { IUserDTO } from '../../interfaces';
import { Container } from 'typedi';
import AuthenticationService from './../../services/authentication';

const route = Router();

export default (app: Router) => {
  app.use('/users', route);

  route.post(
    '/',
    celebrate({
      [Segments.BODY]: userJoiSchema.registration,
    }),

    async (req: Request, res: Response, next: NextFunction) => {
      const logger = Container.get<Utils.Logger>('logger');

      try {
        const userDTO: IUserDTO = req.body;

        const userInDB = await User.findOne({
          email: userDTO.email,
        });

        if (userInDB) return next({ status: 200, message: 'User already exists' });

        const authenticationService = Container.get(AuthenticationService);
        const { user, token } = await authenticationService.Register(userDTO);

        res.status(201).json({
          user,
          token,
        });
      } catch (error) {
        logger.error('๐Ÿ”ฅ error: %o', error);
        return next(error);
      }
    },
  );
};

As you can see nothing is dramatically different from your own auth route.
The authenticationService is also the same, I just changed some method names for personal clarity.


Here's the actual test trimmed down to isolate what's wrong

auth.test.ts

import request from 'supertest';
import http from 'http';
import User from '../../models/user';
import factory from '../../Utils/factory';

describe('Auth Test', () => {
  let server: http.Server;

  beforeAll(async (done) => {
    server = await require('../../app').default; //Exporting the server promise from app.ts

    done();
  });

  afterAll(async (done) => {
    server.close();
    await User.deleteMany({});

    done();
  });

  it('should return 201 if request is valid', async (done) => {
    const userDTO = factory.userDTO.build();
    const res = await request(server).post('/users').send(userDTO);

    expect(res.status).toBe(201);

    done();
  });
});

So this test passes without any problems:
image


And here's the same test but with a simple instantiation of the AuthenticationService:

auth.test.ts

import request from 'supertest';
import http from 'http';
import User from '../../models/user';
import factory from '../../Utils/factory';
import Container from 'typedi';
import AuthenticationService from '../../services/authentication';
import LoggerInstance from '../../loaders/logger';
import { mock } from 'jest-mock-extended';
import { EventDispatcherInterface } from '../../interfaces';

describe('Auth Test', () => {
  let server: http.Server;

  beforeAll(async (done) => {
    server = await require('../../app').default;

    done();
  });

  afterAll(async (done) => {
    server.close();
    await User.deleteMany({});

    done();
  });

  it('should return 201 if request is valid', async (done) => {
    const authenticationService = new AuthenticationService(
      User,
      LoggerInstance,
      mock<EventDispatcherInterface>(),
    );

    // You can also instantiate it by container, it returns the same error
    // const authenticationService = Container.get(AuthenticationService);

    const userDTO = factory.userDTO.build();
    const res = await request(server).post('/users').send(userDTO);

    expect(res.status).toBe(201);

    done();
  });
});

Here's the error:

crep-error


So I'm hoping to get some clarity in this because some of my other tests depend on the authService to register a user before using supertest to call the route.

Thank you for your time.

How would you test an express route with this app.ts structure ?

I've tried cutting the startServer() method with an expressApp() one that I can export:

export async function expressApp() {
  const app = express();
  await require('./loaders').default({ expressApp: app });
  return app;
}

async function startServer() {
  const app = await expressApp();
 ...
}

And in my test I try using it like I would normally do:

import request from 'supertest';
import { expressApp } from '../src/app';

describe('Analyze Movements', () => {
  test('succeeds list of analyze movements', async () => {
    const response = await request(expressApp)
      .get(`/analyze`)
      .expect(200);
    let body = response.body;
    expect(body.length).toBeGreaterThan(1);
  });
}

But I'm getting a SyntaxError: SyntaxError: Unexpected identifier queries.js:1 ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import moment from 'moment';

I suspect this is a problem related with the fact that my expressApp() method is async but I can't figure it out..

Error: write EPIPE

Error: write EPIPE
    at WriteWrap.afterWrite (net.js:868:14)
[nodemon] app crashed - waiting for file changes before starting...

Question: Form/Input Validation in Controller or Service Layer?

Hi Santiq,

Good Day!

Great work! I've been learning on this pattern and applying on a test project. But now I'm struggling about which layer should the form/input validation located at. I saw your example that you place the validation in the express middleware, but isn't these validation considered as business logic? Which mean shouldn't we place the validation at the service layer? Hope you can help me to understand on this part.

Thanks.

Issue while (unit test) mocking container.get service

Hello santiq,

I am back again:-)!. Hey i am having issues in unit testing container.get(service), checkout the below code.

import * as _ from 'lodash';
import {Service, Inject, Container} from 'typedi';
import OTPService from '../otp/index';

@Service()
export default class DevicechangeService {
  constructor(@Inject('devicechangeModel')private devicechangeModel, @Inject('otpModel')private otpModel, @Inject('logger')private logger,) {}

  /**
   *
   * Service to change the device
   *
   * @method deviceChange
   * @param {number} accountId
   * @param {string} deviceId
   * @param {number} mobile
   * @return {object} resolves after sending otp
   */

  public async deviceChange(accountId : number, deviceId : string, newdeviceId : string, created : number, mobile : number,) : Promise < any > {
    try {
      await this
        .devicechangeModel
        .addDeviceChangeDetails(accountId);

       let OTPServiceInstance = Container.get(OTPService);


      await this
        .otpModel
        .updateOTPtoInactiveForModule('DEVICE_CHANGE', accountId);
      //get the new otp

        //get the user details
        //send the otp
        let result = await OTPServiceInstance.sendOTP(serviceprovider, mobile, otpMessage, isd);
        if (result instanceof Object) {
          return result;
        }
        return true;
      } else {
        return {
          field: 421,
          message: errorCode('account').getMessage(421)
        };
      }
    } catch (e) {
      throw e;
    }
  }
}

Here i am not able to set mock class for OTPService, so not able to alter container.get(OTPService) from the above code.

I have tried below but still it does'nt come inside mocked service.

@Service()
class OTPService {
  public generateOTP : any = jest
    .fn()
    .mockImplementation(async(accountId : number, deviceId : string, status : string) => new Promise((resolve : any) => {
      console.log('calls here')
      resolve({})
    }),);
  public sendOTP : any = jest
    .fn()
    .mockImplementation(async(serviceprovider : string, mobile : number, otpMessage : string, isd : number) => new Promise((resolve : any) => resolve({})),);
}

describe('Account', () => {
  beforeEach(done => {
    Container.set(OTPService, new OTPService());
    done();
  });
  describe('#deviceChange', () => {
    it('check everyting cool', async done => {
      let logger = {};
      let otpModel = {
        updateOTPtoInactiveForModule: jest
          .fn()
          .mockImplementation(async(deviceChange : string, accountId : number) => new Promise((resolve : any) => resolve(true))),
        getUserPhoneService: jest
          .fn()
          .mockResolvedValue(true)
      };
      let devicechangeModel = {
        addDeviceChangeDetails: jest
          .fn()
          .mockResolvedValue(true),
        updateDeviceChangeToInactive: jest
          .fn()
          .mockResolvedValue(true)
      };
      // Container.set('OTPService', new OTPService());
      let DeviceChangeServiceInstance = new DeviceChangeService(devicechangeModel, otpModel, logger);
      let deviceChangeStatus = DeviceChangeServiceInstance.deviceChange(accountId, deviceId, newdeviceId, created, mobile);
    });
  });
});

Guys any idea how to solve this...

Constructs explanation

Greetings,

Would you mind explain/comment the following construct, which I'm not familiar with :

public async SignUp(userInputDTO: IUserInputDTO): Promise<{ user: IUser; token: string }>
export default ({ mongoConnection, models }: { mongoConnection; models: { name: string; model: any }[] })
export default mongoose.model<IUser & mongoose.Document>('User', User);

Do they require a special package ? Where can I find a documentation ?
Thank you

where are all the "beautiful" unit tests?

In your injector you proclaim:

`/**

  • WTF is going on here?
  • We are injecting the mongoose models into the DI container.
  • I know this is controversial but will provide a lot of flexibility at the time
  • of writing unit tests, just go and check how beautiful they are!
    */
    `

And yet there are no tests.

How to call the service locator and declare services ? Should I use the `new` keyword ?

Hello Santiago,

Hey i am using your nice code structure to build my new application, i am new to typescript and typedi. I am stuck at injecting database connections at model
I am using postgresql database

Below file path i am adding postgres db connection

bulletproof-nodejs/src/loaders/dependencyInjector.ts
Container.set('db', db);

and in models folder

import { Service, Inject, Container } from 'typedi';
import { Pool } from 'pg';

class Status {

  @Inject('db')
  private db1;
  constructor() {
  }

  public async getApiStatus(): Promise<string> {
    console.log(this.db1); // **not working**
    let pool: Pool = Container.get('db');  // **working fine**
    //console.log(this.pool);
    return new Promise<string>((resolve, reject) => {
      pool.query('select * from status;', (error, results) => {
        if (error) {
          throw error;
        }
        console.log(results.rows);
      });

      resolve('success');
    });
  }
}

export default new Status();

I wanted to somehow inject the database into the model using @Inject.. and without adding container.get('db') at each methods and access the database using this.db1 Could you please give me some hints to achieve this.

How to add GraphQL?

Hi, thanks for your repo and article! I'd really like to understand how and where graphql schemas and resolvers can be embedded into this scaffold structure.

Thanks!

Error: mailgun is not a function

I installed the app and run npm run start then got this error:

error:   ๐Ÿ”ฅ Error on dependency injector loader: { TypeError: mailgun is not a function
    at Object.exports.default (/var/www/html/bulletproof-nodejs/src/loaders/dependencyInjector.ts:17:34)
    at Object.exports.default (/var/www/html/bulletproof-nodejs/src/loaders/index.ts:28:52)
    at process._tickCallback (internal/process/next_tick.js:68:7)
  [stack]:
   'TypeError: mailgun is not a function\n    at Object.exports.default (/var/www/html/bulletproof-nodejs/src/loaders/dependencyInjector.ts:17:34)\n    at Object.exports.default (/var/www/html/bulletproof-nodejs/src/loaders/index.ts:28:52)\n    at process._tickCallback (internal/process/next_tick.js:68:7)',
  [message]: 'mailgun is not a function' }
(node:21788) UnhandledPromiseRejectionWarning: TypeError: mailgun is not a function
    at Object.exports.default (/var/www/html/bulletproof-nodejs/src/loaders/dependencyInjector.ts:17:34)
    at Object.exports.default (/var/www/html/bulletproof-nodejs/src/loaders/index.ts:28:52)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:21788) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:21788) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

but after I made this change in dependencyInjector.js file, the error fixed:
import * as mailgun from 'mailgun-js'; to import mailgun from 'mailgun-js';

If you agree with this solution I can submit a PR.

but I why this error just show for me?!

Add agenda typescript implementation

Before the question, Thanks for the boilerplate it has been a breeze to use.

Is there any plan to implement agenda with typescript since it has a DefinetlyTyped type definitions available?

Catch error when usign celebate liblary

Hello, in your routes you have such file as auth.ts
And we're using celebrate library to check if all data from front-end in the right format.

route.post(
    '/signup',
    celebrate({
      body: Joi.object({
        name: Joi.string().required(),
        email: Joi.string().required(),
        password: Joi.string().required(),
      }),
    }),

If my name is number or another different type (not string) I have a response from the server like this.

{
    "errors": {}
}

I would like to see response something like this

{
    "errors": {"Wrong json data type"}
}

How can I do this ?

Thank you!

Error: Cannot find module 'argon2' (npm)

Hello santiq and team,

I am trying to install the bulletproofNJS. I am stuck in powershell with trying to install argon2 via npm. I am getting the error msg after the failed install:

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms\x64\PlatformToolsets\v140\Toolset.targets(36,5): error MSB8036: The Windows SDK version 8.1 was not found. Install the required version of Windows SDK or change the SDK version in the project property pages or by right-clicking the solution and selecting "Retarget solution". [C:\Users[user]\Documents\bulletproof\bulletproof-nodejs-master\node_modules\argon2\build\libargon2.vcxproj]

I have already installed python27 and also configured the env variables. I need some help with the Windows SDK.

Kind Regards and thx

SendWelcomeEmail is not async

Maybe it's not very important, but I understand that even if SendWelcomeEmail() is declared as an async function

public async SendWelcomeEmail(email) {

in reality it's not:

this.emailClient.messages().send(data);
return { delivered: 1, status: 'ok' };

In order to be async, and effectively return only when the email has been set (or in case of error), we would require something like:

return new Promise((resolve, reject) => this.emailClient.messages().send(data, function (error, body) {
  if (error) {
    reject ({ delivered: 0, status: 'error', error });
  } else {
    resolve ({ delivered: 1, status: 'ok' });
  }
});

Build the API and get output in build folder

Sorry, I am new to the NodeJS and don't have the proper idea to build the NodeJS API.

My question is that how can we build this "bulletproof-nodejs"?

I went through the "Package.json" file and found command to build this "npm run build".

But the above command is taking too much time in hours and not giving the typescripts transpiled files in "outDir": "./build".

The reason to build the project is to "Want to add new routes and services and those newly added routes and service methods should be available in output directory javascript/transpiled files".
Currently, this is not working and not getting newly added routes and service methods in the output/build folder.

Please help, thanks in advance.....

Issue with Jest and Supertest

I am trying to use Jest and Supertest to test my endpoint.

I added server variable and module.export = server in app.ts, so supertest can retrieve the server to perform testing. However, I found the server is return before the dependency injection is ready. which cause an error TypeError: Cannot read property 'address' of null.

Could you please provide a sample of how to adopt jest and supertest with your design?

Socket.io implementation

Hello! I was wondering what would be the correct way to implement socket.io in this project, any ideas?

Question: How to handle other environments?

Hi~. You said that "Put a .env file, that must never be committed" in your article.
Then how do you handle other environments like production, test, etc??

If each branch has different .env and not committed, then how do other members know .env info? and how do you deploy them?

How could you prevent controller callback methods from becoming too big?

Hello! I've been following this pattern for my personal project, but I am reaching a point where I think that the controller layer (the express routes) is getting a bit too big, below is an example from one of your articles.

export default (app) => {
  app.get('/user/search-location', (req, res, next) => {
    try {
      const { lat, lng } = req.query;
      Logger.silly('Invoking user service to search by location')
      const users = UserService.SearchUserByLocation(lat, lng);
      return res.json(users).status(200);
    } catch(e) {
      Logger.warn('We fail!')
      return next(e);
    }
  })
}

Say, I need this endpoint to do A LOT and it's fairly complicated. It needs too query different tables, databases and each service that this calls relies on a previous service. Not to mention all the logging I need to do.

Would make it sense to separate the callback method to maybe a controller directory, and if so how would that look like?

Should I have another service that handles all the complicated parts.

Or should I separate it all into middlewares?

Basically, if my controller method callback is looking big, what steps should I take to reduce or separate it?

What would be a good practice for redis/mysql?

Hey! I'm kinda new to nodeJs (in fact, to almost every Javascript framework). I was looking for a clean architecture and I'm impressed by this one.

This might not be a proper question but wth.

I'm trying to implement a this architecture but with MySQL and Redis as cache. Should I create a loader for each one? I'm not using agenda, so what would be the proper way inject the connections?

(I'm sorry for my english, it's way too late here :P)

Thanks man

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.