This project is a robust REST API built using the NestJS framework, designed for scalability and maintainability. Key features include a modular, testable architecture; comprehensive unit and integration testing with Jest to ensure code quality; end-to-end testing using Supertest and Testcontainers for consistent application stack testing; and an integrated CI/CD pipeline with GitHub Actions to automate testing and deployment processes.
- Shows how to authenticate, issue and invalidate JWT tokens using Redis cache and without storing token in database
- Shows how to retrieve the account balance in a financial application
- Shows how to e2e test using Testcontainers to create isolated environments for testing the entire application flow from the user perspective
- Shows how to make automated deployment to Docker Hub using multi-stage builds and Github Actions
- Code organization: monorepo with Nx
- Backend: REST API, Node.js, NestJS Framework, TypeScript
- Database and cache: PostgreSQL, Redis, TypeORM
- Security: JWT and BCrypt
- Service-to-service communication with Axios
- Tests: Unit and integration testing (Jest), E2E Testing (SuperTest and Testcontainers), Code coverage (IstanbulJS)
- CI/CD: GitHub Actions, Docker Hub
- Documentation: OpenAPI/Swagger, Postman collections, Compodoc, Mermaid (diagram-as-code)
- Others: Docker (with multi-stage build), Docker Compose, ESLint, Webpack, winston
The project has two individual services:
- Auth Service: implements the authentication process with JWT tokens
- Financial Service: process and store financial data
stateDiagram-v2
direction LR
state "Auth Consumer" as auth_consumer_group {
state "API request" as auth_consumer_api_call
[*] --> auth_consumer_api_call
auth_consumer_api_call --> auth: login or refresh token
auth --> auth_consumer_api_call: access token
}
state "Financial Consumer" as financial_consumer_group {
state "API request" as financial_consumer_api_call
[*] --> financial_consumer_api_call
financial_consumer_api_call --> financial: request + access token
financial --> financial_consumer_api_call: financial data
}
state "Services" as service {
state "Auth Service REST API" as auth
state "Financial Service REST API" as financial
}
state "Infrastructure" as storage {
state "Auth Database" as auth_db
state "Redis" as redis
state "Financial Database" as financial_db
}
auth --> auth_db
auth --> redis
financial --> redis
financial --> financial_db
- Development: lint, unit and integration tests (Jest), adds a coverage report as github pull request comment
- Staging: e2e test (Supertest) using Testcontainers to replicate external dependencies
- Production: build all services, create Docker images, and deploy to Docker Hub
stateDiagram-v2
direction LR
classDef dev_style fill:#7f51ce
classDef staging_style fill:#e3942a
classDef prod_style fill:green
state "Development" as development_stage {
state "Code" as dev_code
state "Commit" as dev_commit
state "Pull Request" as dev_pr
[*] --> dev_code
dev_code --> dev_commit
dev_commit --> dev_pr
dev_pr --> [*]
}
development_stage:::dev_style
[*] --> development_stage
state "GitHub Actions • Development" as github_dev_stage {
state "Lint code" as lint
state "Unit test" as unit
state "Integration test" as integration
state "Coverage report" as coverage
[*] --> lint
lint --> unit
unit --> integration
integration --> coverage
coverage --> [*]
}
github_dev_stage:::dev_style
development_stage --> github_dev_stage
state "Staging" as staging_stage {
state "Pull Request" as staging_pr
[*] --> staging_pr
staging_pr --> [*]
}
staging_stage:::staging_style
github_dev_stage --> staging_stage
state "GitHub Actions • Staging" as github_staging_stage {
state "Setup Testcontainers" as testcontainers
state "e2e Tests" as e2e_tests
[*] --> testcontainers
testcontainers --> e2e_tests
e2e_tests --> [*]
}
github_staging_stage:::staging_style
staging_stage --> github_staging_stage
state "Production" as prod_stage {
state "Pull Request" as prod_pr
[*] --> prod_pr
prod_pr --> [*]
}
prod_stage:::prod_style
github_staging_stage --> prod_stage
state "GitHub Actions • Production" as github_prod_stage {
state "Build code" as build_code
state "Create Docker images" as docker_images
state "Deploy do DockerHub" as docker_hub
[*] --> build_code
build_code --> docker_images
docker_images --> docker_hub
docker_hub --> [*]
}
github_prod_stage:::prod_style
prod_stage --> github_prod_stage
github_prod_stage --> [*]