A NestJS-based GraphQL backend for a blog platform with real-time notifications.
- User Authentication: User registration and login with JWT tokens
- Blog Management: Create, read, update, and delete blog posts
- Real-time Notifications: GraphQL subscriptions for real-time blog notifications
- GraphQL API: Full GraphQL API with queries, mutations, and subscriptions
- PostgreSQL: Database for persistent storage
- Redis: Pub/Sub for cross-instance notifications
Backend
├── GraphQL Gateway (Apollo Server)
├── Auth Module (JWT authentication)
├── Blog Module (CRUD operations)
└── Notification Service (Real-time subscriptions)
Infrastructure
├── PostgreSQL (Database)
└── Redis (Pub/Sub)
- Node.js (v18 or higher)
- PostgreSQL (v12 or higher)
- Redis (v6 or higher)
- Install dependencies:
npm install- Set up environment variables:
cp .env.example .envEdit .env with your database and Redis configuration:
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_NAME=rpg_blog
JWT_SECRET=your-secret-key-change-in-production
REDIS_HOST=localhost
REDIS_PORT=6379
PORT=3200
FRONTEND_URL=http://localhost:3000- Create PostgreSQL database:
CREATE DATABASE rpg_blog;- Start Redis:
redis-servernpm run start:devThe server will start on http://localhost:3200 and GraphQL playground will be available at http://localhost:3200/graphql.
Register User
mutation {
register(input: {
email: "user@example.com"
username: "johndoe"
password: "password123"
}) {
token
user {
id
email
username
}
}
}Login
mutation {
login(input: {
email: "user@example.com"
password: "password123"
}) {
token
user {
id
email
username
}
}
}Create Blog (Requires authentication)
mutation {
createBlog(input: {
title: "My First Blog Post"
content: "This is the content of my blog post."
}) {
id
title
content
author {
id
username
}
createdAt
}
}Get All Blogs
query {
blogs {
id
title
content
author {
id
username
}
createdAt
}
}Get Single Blog
query {
blog(id: "blog-id") {
id
title
content
author {
id
username
}
createdAt
}
}Update Blog (Requires authentication, owner only)
mutation {
updateBlog(id: "blog-id", input: {
title: "Updated Title"
content: "Updated content"
}) {
id
title
content
}
}Delete Blog (Requires authentication, owner only)
mutation {
deleteBlog(id: "blog-id")
}Subscribe to New Blog Notifications
subscription {
newBlogNotification {
message
blog {
id
title
content
author {
id
username
}
createdAt
}
timestamp
}
}For protected operations (mutations and some queries), include the JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>
For GraphQL subscriptions, pass the token in the connection parameters:
{
authorization: `Bearer ${token}`
}src/
├── auth/ # Authentication module
│ ├── entities/ # User entity
│ ├── dto/ # Data transfer objects
│ ├── guards/ # JWT guards
│ ├── strategies/ # Passport strategies
│ └── decorators/ # Custom decorators
├── blog/ # Blog module
│ ├── entities/ # Blog entity
│ └── dto/ # Blog DTOs
├── notification/ # Notification service
│ └── dto/ # Notification DTOs
├── config/ # Configuration files
└── main.ts # Application entry point
DB_HOST: PostgreSQL host (default: localhost)DB_PORT: PostgreSQL port (default: 5432)DB_USERNAME: PostgreSQL username (default: postgres)DB_PASSWORD: PostgreSQL password (default: postgres)DB_NAME: Database name (default: rpg_blog)JWT_SECRET: Secret key for JWT tokensREDIS_HOST: Redis host (default: localhost)REDIS_PORT: Redis port (default: 6379)REDIS_PASSWORD: Redis password (optional)PORT: Server port (default: 3200)FRONTEND_URL: Frontend URL for CORS (default: http://localhost:3000)NODE_ENV: Environment (development/production)
# Unit tests
npm run test
# E2E tests
npm run test:e2e
# Test coverage
npm run test:covUNLICENSED