1

I am developing a restAPI with nodejs, express and mysql. Now I have a app.js which is the starting point of the App.

Within app.js I initialize the UserController:

const router: express.Router = express.Router();
new UserController(router);

The UserController looks like this:

import { Request, Response, Router } from 'express';
import UserModel from '../model/user';

class UserController {

  constructor(private router: Router) {

    router.get('/users', async (req: Request, resp: Response) => {
      try {
        // const users = get Users with mysql
        // resp.status(200).send(users);
      } catch (error) {
        resp.send({
          msg: 'Not found',
          status: 404
        });
      }
    });

  }

}

export default UserController;

Now I would like to have a DatabaseController which handels everything around the Database like providing a Connection, closing it and so on:

class DatabaseController {

  constructor() {

  }

}

export default DatabaseController;

How can I achieve that I open the connection in the DatabaseController and let the UserController simply access it? Is that even possible without initializing the DatabaseController and giving the UserController a parameter "dbConnection"?

2
  • Sidenote: You shouldn’t use async code in a constructor Commented Apr 7, 2018 at 17:28
  • Where should I use it instead? They need to be initiated somewhere. Commented Apr 7, 2018 at 19:44

1 Answer 1

4

Yes it's possible. I'm not entirely familiar with typescript so some psuedo code below. Untested.

Somewhere in another file, configure your database connection and the service:

import { MyConnection } from 'my-db-package';

class DatabaseService {
  private connection: MyConnection

  constructor(db: MyConnection) {
    this.connection = db;
  }

  // Return the promise if any.
  // Don't want to handle the error here.
  // Let your controller handle the error
  async openConnection() {
    return this.connection.open()
  }

  async closeConnection() {
    return this.connection.close()
  }

  async getAllUsers() {
    return this.connection.query('SELECT * FROM USERS;')
  }

}

export default DatabaseService;

import { Database } from 'my-db-driver'
import { DatabaseService } from 'my-db-service'

// Don't actually connect here
// Just create the object so it's ready for connection.
const connection = new Database({
  // config
})

// Wire up the internal db connection
// Remember this is a singleton.
export default new DatabaseService(connection)

Next wire up your controller with the new database service:

import { Request, Response } from 'express';
import { DatabaseService } from './my-service'

class UserController {
  private dbService: DatabaseService;

  constructor(dbService: DatabaseService) {
    this.dbService = dbService;
  }

  async connect() {
    return this.dbService.openConnection()
  }

  async close() {
    return this.dbService.closeConnection()
  }

  async getAllUsers(req: Request, res: Response) {
    let users

    try {
      users = await this.dbService.getAllUsers();
    } catch (error) {
      // ...
    }

    res.json(users)
  }

}

export default UserController;

Then hook up your routes:

import { express } from 'express'
import { UserController } from 'user-controller'
import { DatabaseService } from 'database-service'

const userController = new UserController(DatabaseService);
const router: express.Router = express.Router();

router.get('/users', userController.getAllUsers)
// ...

export default router

Finally, hook up your routes with the main Express app:

import { express } from 'express'
import { userRoutes } from 'user-routes'

const app = express()

app.use(userRoutes)
// ..

Again, the above code is untested and likely unusable. It is meant to give you an example of one approach. You may find a better way to do it, but that's the gist of it.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.