This project demonstrates the use of caching to optimize read-heavy operations by using Redis as a cache layer and PostgreSQL as the primary database. The example involves a simple user profile system where user data can be fetched and updated. Redis is used to cache user profiles for faster retrieval.
Before you begin, ensure you have the following installed:
- Node.js (v14 or higher)
- PostgreSQL
- Redis
- Postman or Curl (for API testing)
git clone https://github.com/your-repo/user-caching-app.git
cd user-caching-app
npm install
CREATE DATABASE userdb;
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100)
);
INSERT INTO users (name, email) VALUES
('John Doe', 'john@example.com'),
('Jane Smith', 'jane@example.com');
const pgPool = new Pool({
user: 'your_pg_user',
host: 'localhost',
database: 'userdb',
password: 'your_pg_password',
port: 5432
});
Ensure that Redis is running locally. If Redis is installed, you can start it by running:
bash redis-server
Start the Node.js server:
bash node index.js
the server will start on port 3000.
Endpoint:
bash GET /user/:id
Description: Fetches the user profile by ID. If the user profile is cached, it returns the cached data. Otherwise, it fetches from PostgreSQL, caches the result, and returns it.
Example Request:
bash curl http://localhost:3000/user/1
Example Response (Cache Miss, Fetched from PostgreSQL):
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
Example Response (Cache Hit, Fetched from Redis):
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
Endpoint:
bash PUT /user/:id
Description: Updates the user profile by ID. After updating the database, it invalidates the cached data for the user.
Example Request:
bash curl -X PUT http://localhost:3000/user/1 -H "Content-Type: application/json" -d '{"name": "John Updated", "email": "johnnew@example.com"}'
Example Response:
{
"id": 1,
"name": "John Updated",
"email": "johnnew@example.com"
}
If a user profile is already cached in Redis, the server returns the cached data, avoiding a PostgreSQL query. This reduces latency and improves performance for repeated read requests.
If the user profile is not found in Redis (cache miss), the server fetches the data from PostgreSQL, caches the result in Redis for 1 hour, and then returns the data.
When a user profile is updated, the corresponding cache entry is deleted from Redis. The updated data will be fetched from PostgreSQL and cached again on the next read request.
First request (cache miss, fetched from PostgreSQL):
bash curl http://localhost:3000/user/1
Second request (cache hit, fetched from Redis):
bash curl http://localhost:3000/user/1
Update the profile for user with ID 1:
bash curl -X PUT http://localhost:3000/user/1 -H "Content-Type: application/json" -d '{"name": "John Updated", "email": "johnnew@example.com"}'
The cache will be invalidated, and the profile will be updated in PostgreSQL.
``` bash
curl http://localhost:3000/user/1
```
This error occurs if the Redis client is used after it has been closed. To resolve this, make sure that the Redis client is properly initialized and connected before usage. Ensure the following in your index.js file:
redisClient.connect().catch(console.error);
Ensure Redis is running locally. You can check Redis status by running:
bash redis-cli ping
If Redis is running, the response will be PONG.
Ensure that your PostgreSQL server is running and your database credentials are correct. If you encounter connection errors, verify your database credentials and ensure that PostgreSQL is accessible on localhost:5432.
- Get User by ID: Fetches a user profile from PostgreSQL, with caching implemented for faster reads.
- Paginated User List: Retrieves users in a paginated manner, with cached pages for faster subsequent requests.
- Update User: Updates a user profile and invalidates the cache for paginated user lists.
- Search Users: Allows searching for users by name or email, with caching for search results.
- Rate Limiting: Limits the number of API requests to prevent abuse.
- Post New User: Allows posting a new user to the database.
- IP Address Retrieval: Correctly handles the retrieval of the real client IP address, even behind a reverse proxy.
- Node.js
- PostgreSQL
- Redis
- Express.js
This project is open-source and available under the MIT License.
---
You can now copy and paste this into your `README.md` file. Let me know if any further tweaks are needed!