MCPcopy Index your code
hub / github.com/afteracademy/nodejs-backend-architecture-typescript

github.com/afteracademy/nodejs-backend-architecture-typescript @2.0.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release 2.0.3 ↗ · + Follow
180 symbols 354 edges 76 files 2 documented · 1% updated 4d ago2.0.3 · 2024-01-05★ 3,0618 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Node.js Backend Architecture Typescript Project

A complete project to build a blogging platform like Medium, and FreeCodeCamp

Docker Compose CI

Note: This is the latest (version 2) of the project. If you are using version 1 then checkout the branch version-1

<img src="https://raw.githubusercontent.com/janishar/nodejs-backend-architecture-typescript/master/addons/github_assets/cover-nodejs-backend.png">

Project Highlights

  1. Node.js
  2. Express.js
  3. Typescript
  4. Mongoose
  5. Redis
  6. Mongodb
  7. Joi
  8. Unit Tests & Integration Tests
  9. Docker
  10. JWT

About The Project

This project is designed for a production ready environment. It can handle the scale and complexity of a very demanding application. This project is being used by companies like MindOrks, AfterAcademy, and CuriousJr. Apps/Websites having 10+ million usebase.

It is suitable for Web Apps, Mobile Apps, and other API services.

About The Author

You can connect with me here: * Janishar Ali * Twitter * YouTube Channel

Project Instructions

We will learn and build the backend application for a blogging platform. The main focus will be to create a maintainable and highly testable architecture.

Following are the features of this project: * This backend is written in Typescript: The type safety at build time and having intellisense for it in the IDE like vscode is unparalleled to productivity. I have found production bug reduced to a significant amount since most of the code vulnerabilities are identified during the build phase itself. * Separation of concern principle: Each component has been given a particular role. The role of the components is mutually exclusive. This makes the project easy to be unit tested. * Feature encapsulation: The files or components that are related to a particular feature have been grouped unless those components are required in multiple features. This enhances the ability to share code across projects. * Centralised Error handling: I have created a framework where all the errors are handled centrally. This reduces the ambiguity in the development when the project grows larger. * Centralised Response handling: Similar to Error handling we have a response handling framework. This makes it very convenient to apply a common API response pattern. * Mongodb is used through Mongoose: Mongodb fits very well to the node.js application. Being NoSQL, fast, and scalable makes it ideal for modern web applications. * Redis Memcache: I have used the redis server for caching the items which does not change frequently. It will boost the performance of our system. * Async execution: I have used async/await for the promises and made sure to use the non-blocking version of all the functions with few exceptions. * Docker compose has been configured: I have created the Dockerfile to provide the easy deployability without any setup and configurations. * Unit test is favored: The tests have been written to test the functions and routes without the need of the database server. Integration tests has also been done but the unit test is favored. * A pure backend project: I have experienced that when a backend is developed clubbed with a frontend then in the future it becomes really difficult to scale. We would want to create a separate backend project that servers many websites and mobile apps.

I have also open source a complete blogging website working on this backend project: Goto Repository The repository [React.js Isomorphic Web Application Architecture] has a complete React.js web application implemented for a blogging platform which is using this project as its API server.

3RE Architecture: Router, RouteHandler, ResponseHandler, ErrorHandler

<img src="https://raw.githubusercontent.com/janishar/nodejs-backend-architecture-typescript/master/addons/github_assets/3RE.png">

Project Outline: Blogging Platform

<img src="https://raw.githubusercontent.com/janishar/nodejs-backend-architecture-typescript/master/addons/github_assets/project-outline.png">

Request-Response Handling Schematic Diagram

<img src="https://raw.githubusercontent.com/janishar/nodejs-backend-architecture-typescript/master/addons/github_assets/api-structure.png">

Learn the concepts used in this project

You can find the complete API documentation here

How to build and run this project

  • Install using Docker Compose [Recommended Method]
    • Clone this repo.
    • Make a copy of .env.example file to .env.
    • Make a copy of keys/private.pem.example file to keys/private.pem.
    • Make a copy of keys/public.pem.example file to keys/public.pem.
    • Make a copy of tests/.env.test.example file to tests/.env.test.
    • Install Docker and Docker Compose. Find Instructions Here.
    • Execute docker-compose up -d in terminal from the repo directory.
    • You will be able to access the api from http://localhost:3000
    • Run Tests: docker exec -t app npm test
    • If having any issue then make sure 3000 port is not occupied else provide a different port in .env file.
    • If having any issue then make sure 27017 port is not occupied else provide a different port in .env file.
  • Run The Tests
    • Install node.js and npm on your local machine.
    • From the root of the project executes in terminal npm install.
    • Use the latest version of node on the local machine if the build fails.
    • To run the tests execute npm test.
  • Install Without Docker [2nd Method]

    • Install MongoDB on your local.
    • Do steps 1 to 5 as listed for Install using Docker Compose.
    • Do steps 1 to 3 as listed for Run The Tests.
    • Create users in MongoDB and seed the data taking reference from the addons/init-mongo.js
    • Change the DB_HOST to localhost in .env and tests/.env.test files.
    • Execute npm start and You will be able to access the API from http://localhost:3000
    • To run the tests execute npm test.
  • Postman APIs Here: addons/postman

## Learn Backend Development From Our Videos * Introduction to Web Backend Development for Beginners * Backend System Design for Startups * Practical Javascript for Beginners

## Project Directory Structure ├── .vscode │ ├── settings.json │ ├── tasks.json │ └── launch.json ├── .templates ├── src │ ├── server.ts │ ├── app.ts │ ├── config.ts │ ├── auth │ │ ├── apikey.ts │ │ ├── authUtils.ts │ │ ├── authentication.ts │ │ ├── authorization.ts │ │ └── schema.ts │ ├── core │ │ ├── ApiError.ts │ │ ├── ApiResponse.ts │ │ ├── JWT.ts │ │ ├── Logger.ts │ │ └── utils.ts │ ├── cache │ │   ├── index.ts │ │   ├── keys.ts │ │   ├── query.ts │ │   └── repository │ │   ├── BlogCache.ts │ │   └── BlogsCache.ts │ ├── database │ │ ├── index.ts │ │ ├── model │ │ │ ├── ApiKey.ts │ │ │ ├── Blog.ts │ │ │ ├── Keystore.ts │ │ │ ├── Role.ts │ │ │ └── User.ts │ │ └── repository │ │ ├── ApiKeyRepo.ts │ │ ├── BlogRepo.ts │ │ ├── KeystoreRepo.ts │ │ ├── RoleRepo.ts │ │ └── UserRepo.ts │ ├── helpers │ │ ├── asyncHandler.ts │ │ ├── permission.ts │ │ ├── role.ts │ │ ├── security.ts │ │ ├── utils.ts │ │ └── validator.ts │ ├── routes │ │ ├── access │ │ │ ├── credential.ts │ │ │ ├── login.ts │ │ │ ├── logout.ts │ │ │ ├── schema.ts │ │ │ ├── signup.ts │ │ │ ├── token.ts │ │ │ └── utils.ts │ │ ├── blog │ │ │ ├── editor.ts │ │ │ ├── index.ts │ │ │ ├── schema.ts │ │ │ └── writer.ts │ │   ├── blogs │ │   │   ├── index.ts │ │   │   └── schema.ts │ │ ├── index.ts │ │ └── profile │ │ ├── schema.ts │ │ └── user.ts │ └── types │ └── app-request.d.ts ├── tests │ ├── auth │ │ ├── apikey │ │ │ ├── mock.ts │ │ │ └── unit.test.ts │ │ ├── authUtils │ │ │ ├── mock.ts │ │ │ └── unit.test.ts │ │ ├── authentication │ │ │ ├── mock.ts │ │ │ └── unit.test.ts │ │ └── authorization │ │ ├── mock.ts │ │ └── unit.test.ts │ ├── core │ │ └── jwt │ │ ├── mock.ts │ │ └── unit.test.ts │ ├── cache │ │ └── mock.ts │ ├── database │ │ └── mock.ts │ ├── routes │ │ ├── access │ │ │ ├── login │ │ │ │ ├── integration.test.ts │ │ │ │ ├── mock.ts │ │ │ │ └── unit.test.ts │ │ │ └── signup │ │ │ ├── mock.ts │ │ │ └── unit.test.ts │ │ └── blog │ │ ├── index │ │ │ ├── mock.ts │ │ │ └── unit.test.ts │ │ └── writer │ │ ├── mock.ts │ │ └── unit.test.ts │ ├── .env.test │ └── setup.ts ├── addons │ └── init-mongo.js ├── keys │ ├── private.pem │ └── public.pem ├── .env ├── .gitignore ├── .dockerignore ├── .eslintrc ├── .eslintignore ├── .prettierrc ├── .prettierignore ├── .travis.yml ├── Dockerfile ├── docker-compose.yml ├── package-lock.json ├── package.json ├── jest.config.js └── tsconfig.json

## Directory Traversal for Signup API call /src → server.ts → app.ts → /routes/index.ts → /auth/apikey.ts → schema.ts → /helpers/validator.ts → asyncHandler.ts → /routes/access/signup.ts → schema.ts → /helpers/validator.ts → asyncHandler.ts → /database/repository/UserRepo.ts → /database/model/User.ts → /core/ApiResponses.ts

## API Examples * Signup * Method and Headers POST /signup/basic HTTP/1.1 Host: localhost:3000 x-api-key: GCMUDiuY5a7WvyUNt9n3QztToSHzK7Uj Content-Type: application/json * Request Body json { "name" : "Janishar Ali", "email": "ali@github.com", "password": "changeit", "profilePicUrl": "https://avatars1.githubusercontent.com/u/11065002?s=460&u=1e8e42bda7e6f579a2b216767b2ed986619bbf78&v=4" } * Response Body: 200 json { "statusCode": "10000", "message": "Signup Successful", "data": { "user": { "_id": "63a19e5ba2730d1599d46c0b", "name": "Janishar Ali", "roles": [ { "_id": "63a197b39e07f859826e6626", "code": "LEARNER", "status": true } ], "profilePicUrl": "https://avatars1.githubusercontent.com/u/11065002?s=460&u=1e8e42bda7e6f579a2b216767b2ed986619bbf78&v=4" }, "tokens": { "accessToken": "some_token", "refreshToken": "some_token" } } } * Response Body: 400 json { "statusCode": "10001", "message": "Bad Parameters" } * Profile Private * Method and Headers GET /profile/my HTTP/1.1 Host: localhost:3000 x-api-key: GCMUDiuY5a7WvyUNt9n3QztToSHzK7Uj Content-Type: application/json Authorization: Bearer <your_token_received_from_signup_or_login> * Response Body: 200 json { "statusCode": "10000", "message": "success", "data": { "name": "Janishar Ali Anwar", "profilePicUrl": "https://avatars1.githubusercontent.com/u/11065002?s=460&u=1e8e42bda7e6f579a2b216767b2ed986619bbf78&v=4", "roles": [ { "_id": "5e7b8acad7aded2407e078d7", "code": "LEARNER" }, { "_id": "5e7b8c22d347fc2407c564a6", "code": "WRITER" }, { "_id": "5e7b8c2ad347fc2407c564a7", "code": "EDITOR" } ] } }

Find this project useful ? :heart:

  • Support it by clicking the :star: button on the upper right of this page. :v:

License

``` Copyright (C) 2024 JANISHAR ALI ANWAR

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by app

Extension points exported contracts — how you extend this code

PublicRequest (Interface)
(no doc)
src/types/app-request.d.ts
User (Interface)
(no doc)
src/database/model/User.ts
RoleRequest (Interface)
(no doc)
src/types/app-request.d.ts
Blog (Interface)
(no doc)
src/database/model/Blog.ts
ProtectedRequest (Interface)
(no doc)
src/types/app-request.d.ts
Keystore (Interface)
(no doc)
src/database/model/Keystore.ts
Tokens (Interface)
(no doc)
src/types/app-request.d.ts
Role (Interface)
(no doc)
src/database/model/Role.ts

Core symbols most depended-on inside this repo

send
called by 68
src/core/ApiResponse.ts
addHeaders
called by 28
tests/auth/authentication/mock.ts
addAuthHeaders
called by 27
tests/auth/authentication/mock.ts
findDetailedBlogs
called by 6
src/database/repository/BlogRepo.ts
validateTokenData
called by 6
src/auth/authUtils.ts
createTokens
called by 4
src/auth/authUtils.ts
JoiObjectId
called by 4
src/helpers/validator.ts
getDynamicKey
called by 3
src/cache/keys.ts

Shape

Function 91
Class 44
Method 25
Enum 11
Interface 9

Languages

TypeScript100%

Modules by API surface

src/core/ApiResponse.ts41 symbols
src/core/ApiError.ts34 symbols
src/database/repository/BlogRepo.ts20 symbols
src/cache/query.ts19 symbols
src/database/repository/UserRepo.ts9 symbols
src/core/JWT.ts8 symbols
src/database/repository/KeystoreRepo.ts5 symbols
src/cache/repository/BlogCache.ts5 symbols
src/types/app-request.d.ts4 symbols
src/helpers/validator.ts4 symbols
src/cache/repository/BlogsCache.ts3 symbols
src/cache/keys.ts3 symbols

Dependencies from manifests, versioned

@types/bcrypt5.0.2 · 1×
@types/cookie-parser1.4.6 · 1×
@types/cors2.8.17 · 1×
@types/express4.17.21 · 1×
@types/jest29.5.11 · 1×
@types/jsonwebtoken9.0.5 · 1×
@types/lodash4.14.202 · 1×
@types/morgan1.9.9 · 1×
@types/multer1.4.11 · 1×
@types/newrelic9.14.3 · 1×
@types/newrelic__winston-enricher0.1.5 · 1×
@types/node20.10.6 · 1×

Datastores touched

(mongodb)Database · 1 repos

For agents

$ claude mcp add nodejs-backend-architecture-typescript \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact