A secure, production-ready CRUD (Create, Read, Update, Delete) REST API built with Node.js and Oracle Database, implementing modern security best practices.
- Complete CRUD Operations: Create, Read, Update, and Delete operations for user management
- Security Features:
- CORS protection
- Helmet for secure HTTP headers
- XSS and HTTP Parameter Pollution protection
- Rate limiting to prevent abuse
- Input validation and sanitization
- Structured error handling and logging
- Secure database queries
- Database Reliability:
- Connection pooling
- Timeout handling
- Graceful database shutdown
- Operational Features:
- Structured logging with Winston
- Graceful process shutdown
- Comprehensive error handling
- Health check endpoint
- Environment-based configuration
- Node.js (v14 or higher)
- Oracle Database (with Oracle Instant Client installed)
- npm (Node Package Manager)
-
Clone the repository
git clone <repository-url> cd nodejs-oracle-crud
-
Install dependencies:
npm install
-
Create a
.envfile in the root directory with the following variables:# Server configuration NODE_ENV=development PORT=3000 API_VERSION=v1 # CORS settings ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8080 # Database configuration DB_USER=your_username DB_PASSWORD=your_password DB_CONNECT_STRING=your_connection_string DB_POOL_MIN=2 DB_POOL_MAX=10 DB_POOL_INCREMENT=1 # Logging configuration LOG_LEVEL=info # Security settings RATE_LIMIT_WINDOW_MS=900000 RATE_LIMIT_MAX=100 -
Create the users table in your Oracle database:
CREATE TABLE users ( id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name VARCHAR2(100) NOT NULL, email VARCHAR2(100) NOT NULL UNIQUE, age NUMBER CHECK (age >= 0 AND age <= 120) );
Start the server in development mode:
npm run devStart the server in production mode:
npm startRun linting:
npm run lintPOST /api/users- Create a new userGET /api/users- Get all users (with pagination)GET /api/users/:id- Get user by IDPUT /api/users/:id- Update userDELETE /api/users/:id- Delete user
GET /health- Check system health
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "email": "john@example.com", "age": 30}'curl http://localhost:3000/api/users?page=1&limit=10curl http://localhost:3000/api/users/1curl -X PUT http://localhost:3000/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name": "John Smith", "email": "john.smith@example.com", "age": 31}'curl -X DELETE http://localhost:3000/api/users/1This application implements several security best practices:
- Input Validation: All inputs are validated and sanitized using express-validator.
- XSS Protection: Uses helmet and xss-clean to prevent cross-site scripting attacks.
- Rate Limiting: Prevents abuse through request rate limiting.
- CORS Protection: Configurable CORS settings to restrict domain access.
- HTTP Security Headers: Implements secure HTTP headers with helmet.
- Error Handling: Secure error handling that doesn't leak sensitive information.
- Security Logging: Comprehensive security event logging.
Logs are stored in the logs directory and include:
- Application logs (
combined.log) - Error logs (
error.log) - Exception logs (
exceptions.log) - Unhandled rejection logs (
rejections.log)
├── config/ # Configuration files
│ └── database.js # Database configuration
├── controllers/ # Route controllers
│ └── userController.js # User CRUD operations
├── middleware/ # Express middleware
│ ├── security.js # Security middleware
│ └── validator.js # Input validation
├── routes/ # Application routes
│ └── userRoutes.js # User routes
├── utils/ # Utility functions
│ └── logger.js # Logging configuration
├── logs/ # Application logs
├── .env # Environment variables
├── .gitignore # Git ignore file
├── package.json # Node.js dependencies
├── README.md # Project documentation
└── server.js # Application entry point
This project is licensed under the ISC License.
There are two steps to set up the database:
-
Open the VSCode extension and connect to your Oracle database with the following SYSDBA settings:
- Connection Type: Basic
- Authentication Type: Default
- Username: sys
- Role: SYSDBA
- Hostname: localhost
- Port: 1521
- Service name: FREEPDB1
-
Open the
database/setup.sqlfile in VSCode. -
Run the SQL script to:
- Create a dedicated application user (app_user)
- Create the necessary tables, triggers, indexes
- Add sample data
Once you've run the setup script, your application will connect using:
- Username: app_user
- Password: app_password
- Connect String: localhost:1521/FREEPDB1
You can override these values in your .env file:
DB_USER=app_user
DB_PASSWORD=app_password
DB_CONNECT_STRING=localhost:1521/FREEPDB1
CREATE TABLE users (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name VARCHAR2(100) NOT NULL,
email VARCHAR2(100) NOT NULL UNIQUE,
age NUMBER CHECK (age >= 0 AND age <= 120),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);A Postman collection and environment are included in the postman directory. To use them:
- Import
postman/Oracle_CRUD_API.postman_collection.jsoninto Postman. - Import
postman/Oracle_API_Environment.postman_environment.jsoninto Postman. - Select the "Oracle API Environment" environment.
- Start your application:
npm run dev - Run the requests in the collection to test each endpoint.
- Run the "Health Check" request to make sure the API is up.
- Run the "Create User" request to add a new user.
- Save the returned user ID as a Postman environment variable.
- Use that ID to test the "Get User by ID", "Update User", and "Delete User" endpoints.