Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions socialMedia/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Social Media Backend

This folder contains a simple social media backend built with Node.js, Express, TypeScript and MongoDB. It demonstrates basic CRUD operations for users and posts.

## Setup

1. Install dependencies:
```bash
npm install
```
2. Create a `.env` file with the following variables:
```env
PORT=3000
DB_NAME=your_db_name
MONGODB_URI=mongodb://localhost:27017
```
3. Start the development server:
```bash
npm run start
```

The API exposes `/users` and `/posts` endpoints for creating and fetching users and posts.
29 changes: 29 additions & 0 deletions socialMedia/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import express, { Express, Request, Response } from "express";
import morgan from "morgan";
import connectDB from "./db";
import config from "./config";
import postRouter from "./routes/post.routes";
import userRouter from "./routes/user.routes";

const app: Express = express();

app.use(express.json());
app.use(morgan("dev"));

app.use(postRouter);
app.use(userRouter);

app.get("/", (_req: Request, res: Response) => {
return res.send("Social Media Backend");
});

connectDB()
.then(() => {
app.listen(config.port, () => {
console.log(`Server is running on port: ${config.port}`);
});
})
.catch((error: any) => {
console.error("Error starting the server:", error);
process.exit(1);
});
12 changes: 12 additions & 0 deletions socialMedia/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as dotenv from "dotenv";
dotenv.config();

const config = {
port: process.env.PORT || 3000,
db: {
dbName: process.env.DB_NAME!,
uri: process.env.MONGODB_URI!,
},
};

export default config;
19 changes: 19 additions & 0 deletions socialMedia/controllers/createPost.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Request, Response } from "express";
import Post from "../models/post.model";
import apiResponse from "../utils/apiResponse.utils";
import apiError from "../utils/errorResponse.utils";

const createPost = async (req: Request, res: Response) => {
try {
const { author, content } = req.body;
const post = new Post({ author, content });
await post.save();
return res.status(201).send(apiResponse(201, post, "Post created successfully"));
} catch (err: any) {
return res.status(500).send(
apiError(500, "INTERNAL_SERVER_ERROR", err.message || "Internal server error")
);
}
};

export default createPost;
19 changes: 19 additions & 0 deletions socialMedia/controllers/createUser.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Request, Response } from "express";
import User from "../models/user.model";
import apiResponse from "../utils/apiResponse.utils";
import apiError from "../utils/errorResponse.utils";

const createUser = async (req: Request, res: Response) => {
try {
const { username, email } = req.body;
const user = new User({ username, email });
await user.save();
return res.status(201).send(apiResponse(201, user, "User created successfully"));
} catch (err: any) {
return res.status(500).send(
apiError(500, "INTERNAL_SERVER_ERROR", err.message || "Internal server error")
);
}
};

export default createUser;
17 changes: 17 additions & 0 deletions socialMedia/controllers/getAllPosts.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Request, Response } from "express";
import Post from "../models/post.model";
import apiResponse from "../utils/apiResponse.utils";
import apiError from "../utils/errorResponse.utils";

const getAllPosts = async (_req: Request, res: Response) => {
try {
const posts = await Post.find({}).populate("author");
return res.status(200).send(apiResponse(200, posts, "Posts fetched successfully"));
} catch (err: any) {
return res.status(500).send(
apiError(500, "INTERNAL_SERVER_ERROR", err.message || "Internal server error")
);
}
};

export default getAllPosts;
17 changes: 17 additions & 0 deletions socialMedia/controllers/getAllUsers.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Request, Response } from "express";
import User from "../models/user.model";
import apiResponse from "../utils/apiResponse.utils";
import apiError from "../utils/errorResponse.utils";

const getAllUsers = async (_req: Request, res: Response) => {
try {
const users = await User.find({});
return res.status(200).send(apiResponse(200, users, "Users fetched successfully"));
} catch (err: any) {
return res.status(500).send(
apiError(500, "INTERNAL_SERVER_ERROR", err.message || "Internal server error")
);
}
};

export default getAllUsers;
Empty file removed socialMedia/controllers/index.ts
Empty file.
20 changes: 20 additions & 0 deletions socialMedia/models/post.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import mongoose, { Schema, Document } from "mongoose";
import { IUser } from "./user.model";

export interface IPost extends Document {
author: IUser["_id"];
content: string;
createdAt: Date;
updatedAt: Date;
}

const postSchema = new Schema<IPost>(
{
author: { type: Schema.Types.ObjectId, ref: "User", required: true },
content: { type: String, required: true },
},
{ timestamps: true, versionKey: false }
);

export const Post = mongoose.model<IPost>("Post", postSchema);
export default Post;
17 changes: 17 additions & 0 deletions socialMedia/models/user.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import mongoose, { Schema, Document } from "mongoose";

export interface IUser extends Document {
username: string;
email: string;
}

const userSchema = new Schema<IUser>(
{
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
},
{ timestamps: true, versionKey: false }
);

export const User = mongoose.model<IUser>("User", userSchema);
export default User;
17 changes: 15 additions & 2 deletions socialMedia/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "Crafting a dynamic social media backend to connect users, enable interactions, and foster engagement.",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon app.js"
},
"repository": {
"type": "git",
Expand All @@ -15,5 +16,17 @@
"bugs": {
"url": "https://github.com/ritulsingh/backend_collection/issues"
},
"homepage": "https://github.com/ritulsingh/backend_collection#readme"
"homepage": "https://github.com/ritulsingh/backend_collection#readme",
"dependencies": {
"dotenv": "^16.3.1",
"express": "^4.18.2",
"mongoose": "^7.4.1",
"morgan": "^1.10.0"
},
"devDependencies": {
"@types/express": "^4.17.17",
"@types/morgan": "^1.9.4",
"typescript": "^5.1.6",
"nodemon": "^3.0.1"
}
}
10 changes: 10 additions & 0 deletions socialMedia/routes/post.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Router } from "express";
import createPost from "../controllers/createPost.controller";
import getAllPosts from "../controllers/getAllPosts.controller";

const router = Router();

router.post("/posts", createPost);
router.get("/posts", getAllPosts);

export default router;
10 changes: 10 additions & 0 deletions socialMedia/routes/user.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Router } from "express";
import createUser from "../controllers/createUser.controller";
import getAllUsers from "../controllers/getAllUsers.controller";

const router = Router();

router.post("/users", createUser);
router.get("/users", getAllUsers);

export default router;
3 changes: 3 additions & 0 deletions socialMedia/sample.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PORT=3000
DB_NAME="socialmedia"
MONGODB_URI="mongodb://127.0.0.1:27017"
32 changes: 32 additions & 0 deletions socialMedia/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Node 18",
"compilerOptions": {
"lib": [
"ES2021",
"dom"
],
"module": "commonjs",
"target": "es2022",
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true
},
"include": [
"*.ts",
"config/**/*.ts",
"controllers/**/*.ts",
"db/**/*.ts",
"models/**/*.ts",
"routes/**/*.ts",
"types/**/*.ts",
"utils/**/*.ts",
"validators/**/*.ts"
],
"exclude": [
"node_modules"
]
}
9 changes: 9 additions & 0 deletions socialMedia/types/apiResponse.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface SuccessResponse {
statusCode: number;
data: any;
message: string;
success: boolean;
error: null;
}

export default SuccessResponse;
12 changes: 12 additions & 0 deletions socialMedia/types/errorResponse.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
interface ErrorResponse {
statusCode: number;
data: null;
error: {
code: string;
message: string;
};
success: boolean;
meta?: any;
}

export default ErrorResponse;
10 changes: 10 additions & 0 deletions socialMedia/types/post.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Document } from "mongoose";

interface IPost extends Document {
author: string;
content: string;
createdAt: Date;
updatedAt: Date;
}

export default IPost;
10 changes: 10 additions & 0 deletions socialMedia/types/user.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Document } from "mongoose";

interface IUser extends Document {
username: string;
email: string;
createdAt: Date;
updatedAt: Date;
}

export default IUser;
14 changes: 14 additions & 0 deletions socialMedia/utils/apiResponse.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import SuccessResponse from "../types/apiResponse.type";

const apiResponse = (statusCode: number, data: any, message: string = "Success") => {
const response: SuccessResponse = {
statusCode,
data,
message,
success: statusCode < 400,
error: null,
};
return response;
};

export default apiResponse;
17 changes: 17 additions & 0 deletions socialMedia/utils/errorResponse.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import ErrorResponse from "../types/errorResponse.type";

const apiError = (statusCode: number, code: string, message: string = "Something went wrong", meta?: any) => {
const response: ErrorResponse = {
statusCode,
data: null,
error: {
code,
message,
},
success: false,
meta,
};
return response;
};

export default apiError;