- Table of Contents
- Node v14.16
- Express
- Fastify (optional)
- MongoDB NodeJS Driver
- Tedious (optional)
- dotenv
git clone [email protected]:waynecheah/auth-service.git
cd auth-service
cp .env.example .env
npm install
npm start
You should get
MongoDB on mongo-db connected
Server is listening on http://0.0.0.0:4000
In a browser, open http://localhost:4000.
cp .env.example .env
docker-compose build
docker run -it --rm \
--name setup-auth-service \
-e NODE_ENV=development \
-v "$(pwd)":/home/api \
--network my_app_net \
-p 4000:4000 \
auth-service:1.0.1 npm install
docker-compose up -d
You can automate the deployment of Auth Flow Service to Cloud Run by creating Cloud Build triggers at Google Cloud Platform. You can configure your triggers to build and deploy docker image whenever you update your source code and commit to the main branch.
- Enable billing for Cloud project
- Enable all required service APIs
- Creating GitHub App triggers
- Set environment variables according to
.env.example
- Double check if Google Cloud Build is authorized
- Checkout source code to main branch and push commit to Github
- Allowing public access to the APIs
The application follows the Uncle Bob "Clean Architecture" principles and project structure :
[auth-service]
└ [application] → Application services layer
└ [usecases] → Application business rules
└ index.js → Entry for all use cases
└ [domain] → Enterprise core business layer such as domain model objects (Aggregates, Entities, Value Objects) and repository interfaces
└ [infrastructure] → Frameworks, drivers and tools such as Database, the Web Framework, mailing/logging/glue code etc.
└ [config] → Application configuration files, modules and services
└ bootstrap.js → Bootstrap and initial all service dependency injection implementations by environment
└ [database] → Database ORMs middleware
└ mongodb.js → MongoDB connector
└ mssql.js → MS SQL connector
└ [repositories] → Implementation of domain repository interfaces
└ [mongodb] → MongoDB repositories
└ index.js → Entry for all MongoDB repositories
└ [mssql] → MS SQL repositories
└ index.js → Entry for all MS SQL repositories
└ [webserver] → Web server configuration (server, routes, plugins, etc.)
└ express.js → Express server definition
└ fastify.js → Fastify server definition
└ [interface] → Interface Adapters and formatters for use cases and entities to external agency such as Database or the Web
└ [controllers] → Server route definitions & handlers
└ index.js → Entry for all controllers
└ [node_modules] → NPM dependencies (auto generated with npm install)
└ [test] → Source folder for unit or functional tests
└ index.js → Main application entry point
The overriding rule that makes this architecture work is The Dependency Rule. This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle. That includes, functions, classes. variables, or any other named software entity.
Extracted from https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html#the-dependency-rule
Server, routes and plugins can be considered as "plumbery-code" that exposes the API to the external world, via an instance of server.
The role of the server is to intercept the HTTP request and match the corresponding route.
Routes are configuration objects whose responsibilities are to check the request format and params, and then to call the good controller (with the received request). They are registered as Plugins.
Plugins are configuration object that package an assembly of features (ex: authentication & security concerns, routes, pre-handlers, etc.) and are registered at the server startup.
Controllers are the entry points to the application context.
They have 3 main responsibilities :
- Extract the parameters (query or body) from the request
- Call the good Use Case (application layer)
- Return an HTTP response (with status code and serialized data)
A use case is a business logic unit.
It is a class that must have an execute
method which will be called by controllers.
It may have a constructor to define its dependencies (concrete implementations - a.k.a. adapters - of the port objects) or its execution context.
Be careful! A use case must have only one precise business responsibility!
A use case can call objects in the same layer (such as data repositories) or in the domain layer.
You need port 4000
to be free in order to boot up the application. Check if it's already in use and shut the application down before you npm start
again
By running the following command in terminal docker exec -it auth-flow-service sh
to see if something unusual is happening inside docker container