A simple Food delivery app in express & typescript using IoC principle (TDD approach) Stage-1.0.1

Tushar Roy Chowdhury
4 min readJun 9, 2022

Hello again !! This is the 2nd part of an extensive tutorial and better to check the 1st part to understand the flow of this one. So let’s continue where we have been left off. Before we create any controller, service, or repository we should create the entity first. So go to the modules folder & create a few folders/modules.

modules
- auth
- user
- entity
- user.entity.ts
- user-info.entity.ts
- restaurent
- entity
- restaurent.entity.ts

create those files in respective folders and also create enum in /shared folder.

We need to create tables in DB, so run the migration command.

// It will create migration file in /src/migrations folder
docker-compose -f docker-compose.dev.yml --env-file ./env/.env.dev run dev npm run typeorm:generate src/migrations/table-init
// Run files from migrations folder
docker-compose -f docker-compose.dev.yml --env-file ./env/.env.dev run dev npm run typeorm:run

It will create tables & columns in DB. If your application still running then run HTTP://localhost:8088 in your browser to open the pgadmin. Required passwords are in the env/.env.dev file.

N.B. If your DB is not created yet then please create a Postgres DB under db service (wrote in the docker-compose.dev.yml) manually.

// Create DB if DB is not created automatically. Here db is the service & fooddb is the DB name
docker-compose -f docker-compose.dev.yml --env-file env/.env.dev exec db createdb fooddb -U postgres

After creating those entity files let’s create the rest of the files where folders will be —

modules
- auth
- entity (Not required for auth module)
- controller
- dto
- interfaces
- repository
- service
- tests
// Repeat the approach for other folders/modules.

Now we should start creating files Lower-level to Top-level. In this case, repository. Because this one is directly connected with the database service file.

You must be saying where are these Exception classes. OK then create them first. In your server.ts file update with this code.

There is another one. Uncle Bob also said, “Keep your code DRY”. DRY = Don’t Repeat Yourself. That’s why we created a generic way of handling the errors. And of course, in the /shared folder create a folder, /errors & also update the shared/enum.ts file —

Now update the shared/enum.ts file

...
export enum HttpStatusCode {
OK = 200,
CREATED = 201,
ACCEPTED = 202,
NO_CONTENT = 204,
BAD_REQUEST = 400,
NOT_FOUND = 404,
FORBIDDEN = 403,
UNAUTHORIZED = 401,
METHOD_NOT_ALLOWED = 405,
REQUEST_TIMEOUT = 408,
CONFLICT = 409,
INTERNAL_SERVER = 500,
}

Now create the auth.service.ts & interfaces/IAuth.service.ts files —

Before we create a controller, let’s create DTO files —

DTO stands for Data Transfer Object. It is a design pattern & we call it when we need to use such objects that encapsulate & aggregate data for transfer. And class-validator for validating the payload before send to the service layer.

Now create controller/auth.controller.ts & a middleware to handle error responses, middlewares/dto-validation.middleware.ts

Till now whatever we did, don’t you think we need to inject the controller & service? Yes of course —

Look at line-9 of the container.core.ts file, we created an index.controller.ts at the top of the modules where we can all our controllers.

Now as we promised that we are going to use the TDD approach. So we will create every test file under the tests folder. Before creating any test file, we need to create some faker files under the root of the application’s tests folder. Files are, supertest.utils.ts, faker.service.ts & generate.ts

Now, start with the repository first. Create tests/auth.repository.spec.ts, auth.service.spec.ts & auth.controller.spec.ts file—

I have added the full code. So I hope you have a little bit of knowledge of jest & supertest. And if you are interested to contribute, you can add more crucial tests. Now do the TDD approach —

npm test -- auth.repository.spec.ts (test other files by changing the file name)

Now we got the knowledge of how we are arranging the project, I am not going elaborate on the code piece by piece. Let’s add all the user module files

  • controller/user.controller.ts
  • interfaces/IUser.repository.ts & IUser.service.ts
  • repository/user.repository.ts

And also update core/type.core.ts & container.core.ts

// update types.core.ts
export const TYPES = {
...
IUserRepository: Symbol.for('IUserRepository'),
IUserService: Symbol.for('IUserService'),
};
// update container.core.ts
/* User Module bind */
container.bind<IUserRepository>(TYPES.IUserRepository).to(UserRepository);
container.bind<IUserService>(TYPES.IUserService).to(UserService);

Now create all the necessary test files to the /tests folder —

Now run the following command in the respective folder to do the TDD.

npm test -- user.controller.spec.ts (test other files by changing the name)

YES!! there is too much code. Next, we will be going to add token-based user authentication using JWT(JSON Web Token). So it will more interesting.
This is the GitHub Repo Branch.

Thanks.Bye for now.

--

--

Tushar Roy Chowdhury

I am a passionate programmer and always keep eye on new technologies and scrutinize them until getting into shape.