- Express - NodeJs framework
- Storage - Supabase
- DB - Postgresql
- ORM - Prisma
- Authentication - JWT + refresh token
- Rate limiting & Cache - Redis - ioredis
- Transformation - Sharp
Base URL - https://ips-ollj.onrender.com/
Ensure you have the following installed:
- Node.js (Latest LTS version recommended)
- PostgreSQL
- Redis
-
Clone the repository
git clone https://github.com/yourusername/ips.git cd ips
-
Install dependencies
npm install
-
Set up environment variables
Create a
.env
file in the root directory and configure it with the following variables (replace placeholders with actual values):POSTGRES_USER="your_postgres_user" POSTGRES_PASSWORD="your_postgres_password" DATABASE_URL="postgresql://your_postgres_user:your_postgres_password@localhost:5432/your_database?schema=public" JWT_SECRET="your_jwt_secret" REFRESH_SECRET="your_refresh_secret" STORAGE_URL="https://your_supabase_url/storage/v1" API_KEY="your_supabase_api_key" SHARE_SECRET="your_share_secret"
-
Start PostgreSQL and Redis
Make sure both services are running:
sudo systemctl start postgresql redis-server
-
Run database migrations
npx prisma migrate dev --name init
-
Start the server
npm start
The server should now be running on
http://localhost:3000
(or the port specified in your environment variables).
- Signup/Login
- Upload image
- Retrieve image - LRU cache eviction policy
- List all images - paginated response
- Delete specific image
- Transform image [Limited feature ~ Beta]
- Resize
- Crop
- Rotate
- Flip
- Change format
- Apply filters
- Share specific image - generate a sharable link that can be
accessed without authentication
, expires after a certaintime period
. - Storage limit for each user -
store amount of storage used
in DB - Error handling and validation with unambiguous response & status code
GET /images/:id
GET /images?page=1&limit=10
POST /images
Request Body: Multipart form-data with image file
Response: Uploaded image details (URL, metadata).
POST /images/:id/transform
{
"transformations": {
"resize": {
"width": "number",
"height": "number"
},
"crop": {
"width": "number",
"height": "number",
"x": "number",
"y": "number"
},
"rotate": "number",
"format": "string",
"filters": {
"grayscale": "boolean",
"sepia": "boolean"
}
}
}
POST /auth/register
{
"username": "user1",
"password": "password123"
}
POST /auth/login
{
"username": "user1",
"password": "password123"
}
DELETE /images/:id
POST /images/:id/share
DELETE /images/:id/share
// return image that binds to specific shareid
GET /images/shared/:shareid;
DELETE /user // delete the user -> needs JWT token in header