A production-ready GraphQL API for task management with real-time updates, advanced caching, and enterprise-grade security
This project is a comprehensive GraphQL API built with Apollo Server 5 that demonstrates modern backend development practices. It features real-time subscriptions, intelligent caching with Redis, DataLoader for query optimization, and enterprise-level security measures.
- 🚀 Real-time Updates - GraphQL Subscriptions for live task updates
- ⚡ Performance Optimized - DataLoader + Redis caching eliminates N+1 queries
- 🔒 Production Security - JWT auth, rate limiting, query complexity analysis
- 📊 Complex Queries - Nested relationships with smart filtering
- 🎯 Clean Architecture - Modular schema design with separation of concerns
- ✅ Task Management - CRUD operations with status tracking (Pending, In Progress, Completed, Cancelled)
- ✅ User Management - Registration, authentication, profile management
- ✅ Comments System - Nested comments on tasks with user attribution
- ✅ Task Assignment - Assign tasks to users with role-based access
- 🔄 Real-time Subscriptions
- Task created/updated/deleted events
- Comment notifications
- User typing indicators
- Status change broadcasts
- 🎯 Complex Queries
- Nested relationships (tasks → assignee → comments → user)
- Filtering by status, priority, assignee
- Pagination support
- Task statistics and analytics
- 🔍 DataLoader Integration
- Batch loading for users
- Batch loading for tasks by user
- Batch loading for comments by task
- Eliminates N+1 query problems
- ⚡ Redis Caching Strategy
- User data caching (1 hour TTL)
- Task list caching with filter keys (5 min TTL)
- Smart cache invalidation on mutations
- 🔄 Cache Management
- Automatic invalidation on create/update/delete
- Pattern-based cache clearing
- TTL-based expiration
- 🔐 Authentication & Authorization
- JWT-based authentication
- Protected queries and mutations
- Field-level authorization
- 🛡️ Security Measures
- Query depth limiting (max 7 levels)
- Query complexity analysis (max 1000 complexity)
- Query timeout (10 seconds)
- Rate limiting (per-user and global)
- Input validation with Validator
- Security headers with Helmet
- CORS configuration
- 📊 Logging & Monitoring
- Request/response logging
- Error tracking
- Performance metrics
| Layer | Technology |
|---|---|
| GraphQL Server | Apollo Server 5 |
| Runtime | Node.js |
| Database | PostgreSQL |
| Caching | Redis |
| Authentication | JWT (jsonwebtoken) |
| Validation | Validator |
| Security | Helmet, graphql-depth-limit, graphql-query-complexity |
| Real-time | GraphQL Subscriptions (graphql-ws) |
src/
├── config/
│ ├── cache-config.js # Cache Configuration (Prefix & TTL)
│ ├── database.js # PostgreSQL connection pool
│ ├── pubsub.js # Subscriptions configuration
│ └── redis.js # Redis client configuration
├── middleware/
│ ├── auth.js # JWT authentication
│ └── security.js # Security headers & CORS
├── schema/
│ ├── typeDefs/
│ │ ├── index.js # All schemas
│ │ ├── baseType.js # Base types & scalars
│ │ ├── userType.js # User schema
│ │ ├── taskType.js # Task schema
│ │ ├── commentType.js # Comment schema
│ │ └── subscriptionType.js # Subscription schema
│ └── resolvers/
│ ├── index.js # All resolvers
│ ├── auth-resolver.js # Auth resolvers
│ ├── user-resolver.js # User resolvers
│ ├── task-resolver.js # Task resolvers
│ ├── comment-resolver.js # Comment resolvers
│ └── subscription-resolver.js # Subscription resolvers
├── utils/
│ ├── auth.js # Auth helper functions
│ ├── dataLoader.js # DataLoader helper functions
│ ├── inputValidator.js # Input validation schemas
│ ├── rateLimiter.js # Rate limiting logic
│ ├── redis.js # Redis helper functions
│ └── logger.js # Logging utility
└── server.js # Apollo Server setup
- Node.js >= 18.x
- PostgreSQL >= 14.x
- Redis >= 7.x
- Docker & Docker Compose (optional)
- Clone the repository
git clone https://github.com/asqirahmadani/Task-Management.git
cd Task-Management- Install dependencies
npm install- Configure environment variables
cp .env.example .envEdit .env:
# Server
PORT=4000
NODE_ENV=development
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=task_management
DB_USER=postgres
DB_PASSWORD=your_password
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# JWT
JWT_SECRET=your_super_secret_key_here
JWT_EXPIRES_IN=7d
# Security
RATE_LIMIT_WINDOW=15m
RATE_LIMIT_MAX_REQUESTS=100
QUERY_COMPLEXITY_LIMIT=1000
QUERY_DEPTH_LIMIT=7
QUERY_TIMEOUT=10000- Setup database
# Create database
createdb task_management
# Run migrations
npm run migrate- Start the server
# Development
npm run dev
# Production
npm start- Access Apollo Studio
http://localhost:4000/graphql
# Start all services (PostgreSQL, Redis, API)
docker-compose up -d
# View logs
docker-compose logs -f api
# Stop services
docker-compose down- JWT Tokens - Secure token-based authentication
- Password Hashing - bcrypt with salt rounds
- Token Expiration - Configurable token lifetime
// Depth Limiting - Prevents deeply nested queries
query {
user {
tasks {
assignedUser {
tasks {
assignedUser {
# Max depth exceeded - REJECTED
}
}
}
}
}
}
// Complexity Analysis - Prevents expensive queries
query {
# Complexity score calculated based on:
# - Number of fields
# - Nested relationships
# - List multipliers
# Max: 1000 complexity points
}- Per-User Limits - 100 requests per 15 minutes
- Global Limits - 1000 requests per minute
- Authenticated vs Public - Different limits for auth state
Eliminates N+1 query problems:
// Without DataLoader: N+1 queries
tasks.forEach((task) => {
db.query("SELECT * FROM users WHERE id = ?", task.assigned_to);
});
// With DataLoader: 1 batched query
const userIds = tasks.map((t) => t.assigned_to);
db.query("SELECT * FROM users WHERE id IN (?)", userIds);// Cache Keys Pattern
user:{userId} // TTL: 5 minutes
tasks:all:{filters} // TTL: 2 minutes
tasks:user:{userId} // TTL: 2 minutes
comments:task:{taskId} // TTL: 2 minutes
// Invalidation on mutations
createTask() → Clear tasks:* pattern
updateTask() → Clear specific task cache
deleteUser() → Clear user:* pattern- Automatic query cancellation after 10 seconds
- Prevents long-running queries from blocking
// Logged information
- Query/Mutation name
- Execution time
- Cache hit/miss
- User ID (if authenticated)
- Errors with stack traces- Query execution time
- DataLoader batch sizes
- Cache hit rates
- Error rates
View Full GraphQL Schema
# User Types
type User {
id: ID!
name: String!
email: String!
created_at: DateTime!
createdTasks: [Task!]!
assignedTasks: [Task]!
comments: [Comment!]!
}
# Task Types
type Task {
id: ID!
title: String!
description: String
status: TaskStatus!
priority: TaskPriority!
assigned_to: ID!
created_by: ID!
created_at: DateTime!
updated_at: DateTime!
assignedUser: User
creator: User
comments: [Comment!]!
commentCount: Int!
}
enum TaskStatus {
PENDING
IN_PROGRESS
COMPLETED
CANCELLED
}
enum TaskPriority {
LOW
MEDIUM
HIGH
URGENT
}
# Comment Types
type Comment {
id: ID!
task_id: ID!
user_id: ID!
text: String!
created_at: DateTime!
task: Task!
user: User!
}
# Subscription Types
type Subscription {
taskCreated: Task!
taskUpdated(taskId: ID): Task!
taskDeleted(taskId: ID!): TaskDeletedPayload!
commentAdded(taskId: ID!): Comment!
userTyping(taskId: ID!): UserTypingPayload!
}Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Asqi Rahmadani
- GitHub: @asqirahmadani
- Project Link: https://github.com/asqirahmadani/Task-Management
- Apollo Server - GraphQL server implementation
- DataLoader - Batching and caching layer
- GraphQL - Query language for APIs
⭐ If you found this project helpful, please consider giving it a star!
Made with ❤️ and GraphQL