Skip to content

Newsletter sending project built following clean architecture principles

License

Notifications You must be signed in to change notification settings

Lukasveiga/newsletter-sender-clean-arch

Repository files navigation

✉️ NewsLetter sender + TypeScript + Clean Architecture

Overview:

Email delivery project containing the content of a newsletter, developed using Node.js and Typescript. The entire project adheres to the Clean Architecture designed by Robert C. Martin.

What are the advantages of building a project following this architecture?

The primary objective of Clean Architecture is the separation of concerns, achieved by dividing the software into distinct layers. Each layer includes at least one for business rules and another for interfaces. This approach results in a system that is:

  • Independent of Frameworks
  • Testable
  • Independent of UI
  • Independent of Database
  • Independent of any external agency



Code Architecture:

  • Entities Layer:
    • User Entity
  • Usecases Layer:
    • Subscribe user on newsletter
    • Send newsletter to subscribed users
    • Unsubscribe user of newsletter
    • In memory user repository
  • Presenters Layer:
    • Subscribe user controller
    • Send newsletter controller
    • Unsubscribe user controller
  • Infra Layer:
    • Email Service (nodemailer)
    • Html Compiler Service (handlebars)
    • Repository (mongodb)
  • Main Layer:
    • Express configuration
    • Factory
    • Middlewares
    • Routes

Test Coverage:


Containerizing the application:

To build the project image, a dockerfile with the multisage concept was used. Multistage builds make use of one Dockerfile with multiple FROM instructions. Each of these FROM instructions is a new build stage that can COPY artifacts from the previous stages.

There are two main reasons for why you’d want to use multi-stage builds:

  • They allow you to run build steps in parallel, making your build pipeline faster and more efficient.
  • They allow you to create a final image with a smaller footprint, containing only what's needed to run your program.

- Let's break down each line of the Dockerfile:

FROM node:18-bullseye-slim AS builder

Here we are using the official Node.js 18 image with slim version as the base image.
AS builder: Assigns a name to the build stage. This allows using multiple stages in a single Dockerfile.

WORKDIR /usr/src/app

Set the working directory inside the container.

COPY --chown=node:node package*.json ./

Copy package.json and package-lock.json to the working directory.
--chown=node:node: Sets ownership of the copied files to the specified user and group. This is a security best practice to avoid running processes as root.

COPY . .

Copy all files from the host to the container's working directory.

RUN npm run build

Runs the build script defined in the package.json. This likely compiles/transpiles the source code into a distributable form.

Second stage:

FROM node:18-bullseye-slim

Starts a new build stage using the same base image.

ENV NODE_ENV dev

Sets the environment variable NODE_ENV to 'dev'. This can be overridden during container runtime if needed.

USER node

Switches to a non-root user. This is a security best practice to minimize the impact of security vulnerabilities.

WORKDIR /usr/src/app

Sets the working directory for subsequent instructions in this stage.

COPY package*.json ./

Copies package.json and package-lock.json from the host to the container.

COPY .env ./

Copies .env file from the host to the container.

RUN npm ci --production

Installs only production dependencies, skipping development dependencies.

COPY --from=builder /usr/src/app/dist ./dist

Copies the compiled/transpiled application from the previous build stage into the current stage.

EXPOSE 3030

Exposes port 3030 for incoming connections. Note that this doesn't actually publish the port; it's just a documentation of intended port usage.

CMD ["node", "dist/main/server.js"]

Specifies the default command to run when the container starts. In this case, it runs the Node.js application server from the compiled output.


Build image and run docker container:

  • Build docker image:
docker build -t devlukas/newsletter-sender:1.0 .
  • Run docker container:
docker run -p 3030:3030 devlukas/newsletter-sender:1.0

Next features to be implemented:

  • Unsubscribe link into de the email;
  • Add a weekly email schedule (example: node-cron)

Contact Information:

About

Newsletter sending project built following clean architecture principles

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages