1.
Create the folder micro-blogging-app
2. Create the sub folder models, routes, public
3. Initialize a Node.js project ( open terminal run the following command : npm init -y)
4. Install necessary dependencies: (open terminal run the following command : npm
install express mongoose)
5. Create the following files
1. models/User.js
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
followers: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }]
});
module.exports = mongoose.model('User', UserSchema);
2. models/Post.js
const mongoose = require('mongoose');
const PostSchema = new mongoose.Schema({
content: { type: String, required: true },
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
createdAt: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Post', PostSchema);
3. routes/user.js
const express = require('express');
const User = require('../models/User');
const router = express.Router();
// Register a user
router.post('/register', async (req, res) => {
try {
const { username, email } = req.body;
const user = new User({ username, email });
await user.save();
res.status(201).json(user);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Follow a user
router.post('/follow/:id', async (req, res) => {
try {
const currentUser = await User.findById(req.body.userId);
const userToFollow = await User.findById(req.params.id);
currentUser.following.push(userToFollow._id);
userToFollow.followers.push(currentUser._id);
await currentUser.save();
await userToFollow.save();
res.json({ message: `Now following ${userToFollow.username}` });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Find user by username
router.get('/find/:username', async (req, res) => {
try {
const user = await User.findOne({ username: req.params.username });
if (!user) return res.status(404).json({ error: 'User not found' });
res.json(user);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
module.exports = router;
4. routes/post.js
const express = require('express');
const Post = require('../models/Post');
const User = require('../models/User');
const router = express.Router();
// Create a post
router.post('/create', async (req, res) => {
try {
const { content, userId } = req.body;
const post = new Post({ content, author: userId });
await post.save();
res.status(201).json(post);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Get posts from followed users
router.get('/feed/:userId', async (req, res) => {
try {
const user = await User.findById(req.params.userId).populate('following');
const posts = await Post.find({ author: { $in: user.following } }).populate('author');
res.json(posts);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
module.exports = router;
5. app.js
const express = require('express');
const mongoose = require('mongoose');
const path = require('path');
const userRoutes = require('./routes/user');
const postRoutes = require('./routes/post');
const app = express();
// Middleware
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));
// MongoDB connection
mongoose.connect('mongodb://localhost:27017/micro-blogging-app', { useNewUrlParser:
true, useUnifiedTopology: true })
.then(() => console.log('MongoDB connected'))
.catch(err => console.log(err));
// Routes
app.use('/api/users', userRoutes);
app.use('/api/posts', postRoutes);
// Start server
const PORT = 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
6. public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Micro-Blogging App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>Welcome to Micro-Blogging</h1>
<div id="userForm">
<h2>Register User</h2>
<input type="text" id="username" placeholder="Username">
<input type="email" id="email" placeholder="Email">
<button onclick="registerUser()">Register</button>
</div>
<div id="postForm">
<h2>Create Post</h2>
<textarea id="content" placeholder="Write your post..."></textarea>
<input type="hidden" id="userId">
<button onclick="createPost()">Post</button>
</div>
<!-- Follow User Section -->
<div id="followForm">
<h2>Follow User</h2>
<input type="text" id="followUsername" placeholder="Username of user to
follow">
<button onclick="followUser()">Follow</button>
</div>
<h1>Your Feed</h1>
<!-- UserId input for logged in user -->
<input type="hidden" id="userId" value="userId1"> <!-- Replace with dynamic
userId -->
<!-- Feed container -->
<div id="posts">
<!-- Posts will be dynamically loaded here -->
</div>
<!-- Load feed button -->
<button onclick="loadFeed()">Load Feed</button>
</div>
<script src="app.js"></script>
</body>
</html>
7. public/style.css
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
.container {
width: 600px;
margin: 20px auto;
padding: 20px;
background: white;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1, h2 {
text-align: center;
}
textarea, input {
width: 100%;
padding: 10px;
margin: 5px 0;
}
button {
padding: 10px;
background-color: #007BFF;
color: white;
border: none;
cursor: pointer;
}
#posts {
margin-top: 20px;
}
8. public/app.js
// Register a user
function registerUser() {
const username = document.getElementById('username').value;
const email = document.getElementById('email').value;
fetch('/api/users/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, email })
})
.then(response => response.json())
.then(data => {
alert('User registered successfully!');
document.getElementById('userId').value = data._id;
})
.catch(err => console.error(err));
}
// Create a post
function createPost() {
const content = document.getElementById('content').value;
const userId = document.getElementById('userId').value;
fetch('/api/posts/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content, userId })
})
.then(response => response.json())
.then(data => {
alert('Post created successfully!');
loadFeed();
})
.catch(err => console.error(err));
}
// Follow a user
function followUser() {
const followUsername = document.getElementById('followUsername').value;
const currentUserId = document.getElementById('userId').value;
// Get the userId of the user to follow by username
fetch(`/api/users/find/${followUsername}`)
.then(response => response.json())
.then(userToFollow => {
if (!userToFollow) {
alert('User not found');
return;
}
// Make follow request
fetch(`/api/users/follow/${userToFollow._id}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: currentUserId })
})
.then(response => response.json())
.then(data => {
alert(`You are now following ${userToFollow.username}`);
})
.catch(err => console.error(err));
})
.catch(err => console.error(err));
}
// Load feed
function loadFeed() {
const userId = document.getElementById('userId').value;
fetch(`/api/posts/feed/${userId}`)
.then(response => response.json())
.then(posts => {
const postsDiv = document.getElementById('posts');
postsDiv.innerHTML = '';
posts.forEach(post => {
const postElement = document.createElement('div');
postElement.innerHTML = `<p><strong>${post.author.username}</strong>:
${post.content}</p>`;
postsDiv.appendChild(postElement);
});
})
.catch(err => console.error(err));
}