Express.js API with PostgreSQL DB integration that performs image processing and logs user's requests.
This project Intensivly Demonstrates:
- Error Handling
- Testing (Integration, End to End, and unit testing)
- Strict typing using TypeScript & ESLint
- Logging
- DB integration
- DB Migration
- Upload & Download
Tech Choice
- Availability: It is open source and free to use with any project
- Common: It is a relational, SQL database which is the most common type of database right now
- Popular and well-tested: Postgres is a viral database and a common choice among enterprise software
- Transferable: Because Postgres uses SQL, it is entirely transferable to working with a MySQL database or any other SQL database
- Strict: Maintain more error-prone code with
no-implicit-any
set to true. - Reduce Errors: Using ESLint for syntax errors.
- Maintenance: Log unexpected server errors.
- Local Environment & Setup
- Run Locally
- Usage Examples
- API Referance
- DB Connection
- Running Tests
- Running Scripts
- Lessons Learned
- Challenges
- Tech Stack
To run this project, you will need to have the following on your system:
- Node.js
- PostgreSQL - Docker image or locally installed.
There is
docker-compose.yml
already configured for you - DBeaver Community or your favorite SQL editor to monitor DB. Alternatively, you can use the psql terminal as documented here DB Connection
.env
file with the following environment variables:
POSTGRES_HOST=127.0.0.1
POSTGRES_USER=nsipapi
POSTGRES_DB=ipapi
POSTGRES_TEST_DB=ipapi_test
POSTGRES_PASSWORD=password123
ENV=dev
- Clone the project
git clone https://github.com/amjadelmahdy/image-processing-api.git
- Go to the project directory
cd image-processing-api
- Install packages
npm install
- Initiate PostgreSQL container
docker-compose up
- Run migrations
npx db-migrate up
- Start the server
npm run start
API could be used through Postman or frontend http://localhost:3000/
Both are solid ways to display the HTTP
Request & Response alongside the status code - message
When using Postman make sure to use form-data as follows:
Using DBeaver Community to query the DB
Tip
Starter Status: On-Hold
Unexpected Errors: Logged inside logs/file-log-error.log
Route | Method | Description |
---|---|---|
/ |
GET | Root - Home Page |
/image |
GET | Get an Image |
/download |
GET | Download an Image |
/optimize |
POST | Upload and Optimize an Image |
GET /
GET /image/${image_name}
Parameter | Type | Description |
---|---|---|
image_name |
string |
Required. Name of the image to fetch |
GET /download/${image_name}
Parameter | Type | Description |
---|---|---|
image_name |
string |
Required. Name of the image to fetch |
POST /optimize
Property | Type | Description |
---|---|---|
width |
number |
Resize width |
height |
number |
Resize height |
quality |
number |
Compression quality |
format |
string |
Convert format (png, jpeg, webp) |
rotate |
number |
Degrees of rotation |
blur |
number |
Sigma of the Gaussian mask |
hue |
number |
Degree of hue rotation |
saturation |
number |
Degree of saturation rotation |
grayscale |
boolean |
Convert to black and white |
text |
string |
Draw text on the image |
red |
number |
Red color tint |
green |
number |
Green color tint |
blue |
number |
Blue color tint |
Tip
- None of the properties are required, but you must provide at least one parameter inside
req.body
. - The file has to be uploaded.
Width
&Height
have to be provided together.- Properties should have the same type.
- Must align with the accepted values table below.
Property | Type | Max | Min |
---|---|---|---|
width |
number |
5000 | 1 |
height |
number |
5000 | 1 |
quality |
number |
100 | 1 |
format |
string |
(png, jpeg, webp) | |
rotate |
number |
360 | 1 |
blur |
number |
1000 | 1 |
hue |
number |
239 | 1 |
saturation |
number |
239 | 1 |
grayscale |
boolean |
true | |
text |
string |
20 characters | |
red |
number |
255 | 0 |
green |
number |
255 | 0 |
blue |
number |
255 | 0 |
Choose the way you're comfortable with
From navbar > Database > New Database Connection > PostgreSQL
- Connect to docker postgres-container bash using the following commands
docker ps
docker exec -it container_id bash
psql -h 127.0.0.1 -U nsipapi -d ipapi
- Now you can:
- List tables using
\dt
- List databases using
\l
- Connect to a database using
\c database_name
- Use the following query:
SELECT * FROM records;
To run tests, use the following command:
npm run test
Important
Ensure POSTGRES_TEST_DB=ipapi_test
, or change the name of the test-db in the test script inside package.json
.
"test": "db-migrate db:create test-db && db-migrate --env test up && cross-env ENV=test ts-node node_modules/jasmine/bin/jasmine && db-migrate db:drop test-db"
- Creates a test database with a provided name
- Sets the environment variable
ENV=test
to use the test configuration. - Run tests
- Drops the test database to ensure a clean environment for each test run.
Important
If the test fails, you might need to drop the test database using the following command: npx db-migrate db:drop test-db
Script | Description |
---|---|
build |
Compile the project to JavaScript |
start |
Start the built JavaScript project |
dev:start |
Start the TypeScript source project using ts-node & nodemon |
lint |
ESLint checks for syntax errors |
lint:fix |
ESLint checks and fixes syntax errors |
prettier |
Consistently organizes code using Prettier |
prettier:fix |
Run Prettier and ESLint fix together |
test |
Run tests before compiling using Jasmine and ts-node |
- ESLint and Prettier: Make them work together using
eslint-plugin-prettier
. - Compose Smaller Pieces: Build smaller components to reach the big picture.
- Jasmine Tests: Testing before compilation lacks support.
Tip
Solution: Use the test script ts-node node_modules/jasmine/bin/jasmine
to run Jasmine with ts-node instead of a separate package like jasmine-ts.
-
Middleware Testing: Difficulty with mocking HTTP requests with Jasmine
-
Uncaught Exceptions: Handling process.on "uncaughtException" at the app level rather than middleware.
- Pending requests: Modify and resubmit requests from the backend.
Server: Node, Express, PostgreSQL, Multer, Sharp, DB-Migrate, Cross-Env, Dotenv, Winston