Objective: Create a simple RESTful API using Node.js and TypeScript that simulates a basic loan application process for car and personal finance.
- Setup:
- Initialize a new Node.js project with TypeScript.
- Use Express.js or any other Node.js framework for handling HTTP requests.
- Database:
- A simple in-memory data structure (e.g., an array or object) is used to store loan application data. No need to integrate a real database.
- API Endpoints:
- Create the following endpoints:
- GET /loans : Retrieve a list of all loan applications.
- GET /loans/:id : Retrieve a single loan application by its ID.
- POST /loans : Submit a new loan application.
- The application should include basic information such as the applicant's name, loan amount, loan type (car or personal), income, and interest rate.
- Calculate the monthly payment based on the loan amount, interest rate, and a fixed loan term (e.g., 5 years for car loans, 3 years for personal loans). Use the provided calculateMonthlyPayment function for this calculation. Include the calculated monthly payment in the response.
- PUT /loans/:id : Update an existing loan application by its ID.
- DELETE /loans/:id : Delete an existing loan application by its ID.
- Ensure that the API responds with appropriate status codes and messages.
- Create the following endpoints:
- Validation:
- Add validation for the loan application data (e.g., required fields, data types, loan amount limits).
- Testing:
- Write unit tests for your API endpoints using a testing framework of your choice (e.g., Jest, Mocha).
- Documentation:
- Provide a README file with clear instructions on how to set up and run your project, as well as how to run the tests.
Here the list of the frameworks/libraries used in this project:
To effectively execute this project on your machine, kindly follow the instructions provided below.
Below are the requirements to run the project:
- Install NVM for Windows. This is a quick way to easily install different versions of NodeJS depending on your needs.
- Install NPM
npm i npm@latest -g
- Install Nodemon
npm i nodemon -g
- Install Docker Desktop for Windows or Docker for Linux. This is optional if you want to use Docker otherwise, you will have to install Redis manually.
- If Docker can't be installed then, you must install Redis since this project uses this for storage.
- Install Git to clone the project on your local machine.
The following steps are essential for running this project on your local machine. Please ensure that you have fulfilled the preceding instructions to ensure the functionality of the project. O
-
Open up terminal and go to the directory you want to install the project.
-
Clone the project repository
git clone [email protected]:kuiamenhmartin/driva-api.git
-
Install NPM packages. The project uses Node v18.16.1.
npm install
-
Create a copy of
.env-sample
and rename it to.env
. Make sure you provide the necessary values for#REDIS
section while you can leave the other variable values as is.# ENV NODE_ENV=development PORT=4000 # LOGGER LOGGER_SERVICE=loan-api LOG_ENABLE_INFO=true LOG_ENABLE_WARN=true LOG_ENABLE_DEBUG=true LOG_ENABLE_VERBOSE=true LOG_ENABLE_ERROR=true # REDIS REDIS_HOST='127.0.0.1' REDIS_PORT=6709 REDIS_PASSWORD= REDIS_USERNAME= REDIS_DB=0
-
(Optional if
step#6
will be followed) If you will be using Docker. Make sure it is already started then, create a copy ofdocker-compose-example.yml
and rename it todocker-compose.yml
. Run the command below to run your docker service.docker-compose up -d
-
(Optional if
step#5
will be followed) StartRedis
on your local machine and make sure you update the#REDIS
section in.env
file with the needed credentials. -
Run command. The default PORT used is
4000
but you can change it in the .env
file.npm run dev:watch
-
Once everything is configured, you can now run the command below to fire up the Loan API.
npm run start
-
Then access it through
http://localhost:4000/
-
Run integrated test coverage
npm run coverage
The REST API for this project is listed below.
POST /api/loans
curl --location 'localhost:4000/api/loans' \
--header 'Content-Type: application/json' \
--data '{
"firstName": "John",
"lastName": "Doe",
"loanAmount": 50000,
"income": 35000,
"interestRate": 13.54,
"loanType":"PERSONAL"
}'
{
"status": 200,
"success": true,
"message": "New Loan Application successfully created!",
"data": {
"id": "5514f659e8b897abdd5101caad96d7b0",
"firstName": "John",
"lastName": "Doe",
"loanAmount": 50000,
"income": 35000,
"interestRate": 13.54444,
"loanType": "PERSONAL",
"monthlyPayment": 1697.83
}
}
GET /api/loans
curl --location 'localhost:4000/api/loans'
{
"status": 200,
"success": true,
"message": "Loan Applications successfully retrieved!",
"data": [
{
"id": "4ce0b16be027ec66bd0d92f006f6ee6d",
"firstName": "John",
"lastName": "Doe",
"loanAmount": 15000,
"income": 1000,
"interestRate": 14.75,
"loanType": "CAR"
},
{
"id": "538dfc6b119370d7033ce02afbf5d16a",
"firstName": "Jane",
"lastName": "Smith",
"loanAmount": 25000,
"income": 15000,
"interestRate": 15.25,
"loanType": "PERSONAL"
}
]
}
GET /api/loans/:id
curl --location 'localhost:4000/api/loans/4ce0b16be027ec66bd0d92f006f6ee6d'
{
"status": 200,
"success": true,
"message": "Loan application successfully retrieved!",
"data": {
"id": "4ce0b16be027ec66bd0d92f006f6ee6d",
"firstName": "John",
"lastName": "Doe",
"loanAmount": 15000,
"income": 1000,
"interestRate": 14.75,
"loanType": "CAR"
}
}
PUT /api/loans/:id
curl --location --request PUT 'localhost:4000/api/loans/4ce0b16be027ec66bd0d92f006f6ee6d' \
--header 'Content-Type: application/json' \
--data '{
"id": "4ce0b16be027ec66bd0d92f006f6ee6d",
"firstName": "John",
"lastName": "Doe",
"loanAmount": 25000,
"income": 1700,
"interestRate": 13,
"loanType": "PERSONAL"
}'
{
"status": 200,
"success": true,
"message": "Loan application '4ce0b16be027ec66bd0d92f006f6ee6d' successfully updated!"
}
DELETE /api/loans/:id
curl --location --request DELETE 'localhost:4000/api/loans/85d96cf662fcc875e31e50264d2e1d9c'
{
"status": 200,
"success": true,
"message": "Loan application '85d96cf662fcc875e31e50264d2e1d9c' successfully deleted!"
}
GET /api/loans/:id
curl --location 'localhost:4000/api/loans/4ce0b16be027ec66bd0d92f006f6ee62'
{
"status": 404,
"success": false,
"message": "Unknown loan application '4ce0b16be027ec66bd0d92f006f6ee62'",
"code": "NOT_FOUND"
}
POST /api/loans
curl --location 'localhost:4000/api/loans' \
--header 'Content-Type: application/json' \
--data '{
"firstName": "John",
"lastName": "Doe",
"loanAmount": 50000,
"income": 35000,
"interestRate": 13.54,
"loanType":"MORTGAGE"
}'
{
"status": 400,
"success": false,
"message": "Please check your inputs",
"data": [
{
"type": "field",
"value": "MORTGAGE",
"msg": "loanType must be one of the following CAR | PERSONAL",
"path": "loanType",
"location": "body"
}
],
"code": "BAD_REQUEST"
}
GET /api/loans/:id
curl --location 'localhost:4000/api/loans/4ce0b16be027ec66bd0d92f006f6ee'
{
"status": 400,
"success": false,
"message": "Please check your inputs",
"data": [
{
"type": "field",
"value": "4ce0b16be027ec66bd0d92f006f6ee",
"msg": "Loan Application Id must be a valid hexadecimal of length 32",
"path": "id",
"location": "params"
}
],
"code": "BAD_REQUEST"
}