Live Link - Click Here

API Endpoints

Auth Routes

POST /register

  • Signs up the user with the passed username and password and returns a jwt token along with the userId
  • The request body should include the fields to be registered (username, password) in JSON format

POST /login

  • Logs in the user if the username and password fields match and returns a jwt token along with the userId

User Routes

GET /user/{id}

  • Fetches the user with the given ID. Returns a JSON object with the user's information

PUT /user

  • Updates the logged in user with the information passed in the request body
  • This route requires authentication
  • The request body should include the fields to be updated (username, bio, image) in JSON format
  • Returns a JSON object with the updated user's information

DELETE /user

  • Deletes the logged in user if the user is logged in otherwise returns 401 error code
  • This route requires authentication
  • Returns a success message if the deletion was successful

POST /user/follow

  • Creates a follow relationship between the authenticated user and the user with the given id
  • The request body should include the id of the user to follow (id) in json format
  • This route requires authentication
  • Returns a success message if the follow was successful

DELETE /user/unfollow

  • Deletes a follow relationship between the authenticated user and the user with the given id
  • The request body should include the id of the user to unfollow {id} in JSON format
  • This route requires authentication
  • Returns a success message if the unfollow was successful

GET /user/{id}/followers

  • Fetches the followers of the user with the given id in the url
  • Returns a JSON array of the user's followers

GET /user/{id}/following

  • Fetches the users that the user with the given id is following
  • Returns a JSON array of the users that the user is following

GET /user/following/posts

  • Fetches the latest posts from users that the authenticated user follows
  • This route requires authentication
  • Thir route makes use of aggregate() function in MongoDB to get the posts that belongs to his followers sorted by creation date
  • Returns a JSON array of the posts

GET /user/{id}/posts

  • Fetches the posts by the user with the given id
  • The number of posts returned can be controlled with the page and limit query parameters
  • Default values are - limit=5 page=1
  • Returns a JSON object with the posts and a flag indicating whether there are more posts

Posts Routes

GET /posts

  • Fetches all posts, sorted by creation date in descending order
  • The number of posts returned can be controlled with the page and limit query parameters
  • Each post is returned with the author's details filled
  • The number of posts returned is limited to 5

GET /posts/{postId}

  • Fetches the post with the given postId
  • Returns the post details with the author's details filled, post creation date and content

POST /posts/new

  • Creates a new post
  • The request body should include the content of the post
  • This route requires authentication

DELETE /posts/{postId}

  • Deletes the post with the given postId
  • This route requires authentication
  • Only the author of the post can delete it

TakeAways

The Advantage of FollowSchema

  • Scalability: As the number of followers and following grows, the UserSchema can become inefficient because it stores all the following users in an array within the user document. There is a size limitation on a document in a collection i.e., 16 megabytes which is avoided by the FollowSchema. On the other hand, the FollowSchema can handle large numbers of followers and following more efficiently.

  • Query Efficiency: It’s easier and more efficient to query the FollowSchema for specific follow relationships. For example, to find all the users that a specific user is following or to find all the followers of a specific user.

  • Data Integrity: The FollowSchema provides better data integrity. If a user is deleted, their follow relationships are also deleted. In the UserSchema, if a user is deleted, their ID may still exist in the following arrays of other users.

The Reason behind using startSession() in this code block

The Popular ACID properties
  • Atomicity: The session ensures that all operations (deleting posts, login credentials, and user profile) are treated as a single unit of work. If any operation fails, the entire transaction is rolled back, leaving the database in a consistent state.
  • Consistency: By using a session, you ensure that the database transitions from one consistent state to another. If an error occurs during the transaction, the database reverts back to its original state.
  • Isolation: Sessions provide isolation, meaning that uncommitted changes are not visible to other sessions until they are committed.
  • Durability: Once the changes are committed, they are permanent and survive subsequent system failures.

Neccessity in this codeblock: In the implemeted code, if an error occurs while deleting the user’s posts, login credentials, or profile, the session aborts the transaction and the database remains unchanged. This prevents partial deletions and ensures data integrity. If all operations are successful, the session commits the transaction and all changes are saved to the database.

Project Structure and File Meaning

This project is organized as follows:

  • src/: This directory contains all the core functionality of the application.
    • assets/: This directory contains the DataBase Design Schema Diagram as .png and .svg files
    • config/: This directory contains the configuration files.
      • db.js: Defines the connection for MongoDB database.
    • middlewares/: This directory contains middleware functions for the application.
      • auth.js: Provides authentication middleware using JWT.
    • models/: This directory contains the Mongoose models for the application.
      • User.js: Defines the User model.
      • Login.js: Defines the Login model.
      • Post.js: Defines the Post model.
      • Follow.js: Defines the Follow model.
    • routes/: This directory contains the route handlers for the application.
      • users.js: Defines the routes for user-related operations. Prefix is /users
      • posts.js: Defines the routes for post-related operations. Prefix is /posts
      • auth.js: Defines the routes for Authorization operations like login and register.
    • index.js: This is the main application file. It sets up the Express application, connects to the MongoDB database, and starts the server.
  • package.json: This file lists the project dependencies and other metadata.
  • README.md: This file provides an overview of the project and instructions for running the application.
  • .gitignore: Ignores the files not needed for github tracking
  • .env.example: Example file for .env to create yourself with your secret values.

Schema Design

Setup Instructions

Follow these steps to set up the project:

1. Install Node.js and npm

If you haven't already, you'll need to install Node.js and npm (which comes with Node.js). You can download them from the official Node.js website.

2. Clone the Project

Clone the project repository

git clone https://github.com/YuvarajSingh-0/AmericanEliteMarket-Assign.git

3. Install Dependencies

Navigate to the project directory in your terminal and run the following command to install all the project dependencies listed in the package.json file:

npm install

4. Set Up Your Database

This project uses MongoDB with Mongoose. If you don’t have MongoDBs server, Mongosh installed, you’ll need to install it and set up a database for your project. You’ll also need to update database connection strings in .env file in the upcoming step.

Note: Normally, MongoDB server is enough for working with database, which creates standalone server in the local machine. But, for this particular codeblock to work Mongo shell is needed which is used to setup a replica set. Transactions only work with the replica set being setup. So, follow the below steps:

  • Download and install MongoDB community server and Mongo shell
  • If the mongoDB is already running, stop the service by entering the below command in command prompt after opening it administrator mode
net stop MongoDB
  • Now change the directory to bin Folder of wherever the MongoDB is installed usually it is in C:\Program Files\MongoDB\Server\7.0\bin
cd C:/"program files"/MongoDB/Server/7.0/bin
  • Now register the replica set in the databse service
mongod --replSet "rs0"
  • Now we need the initiate the replica set to be running for that open the mongoshell and type in
rs.initiate()

Now everything is set.

If you wish not to go through this setup hassle. comment out this codeblock and uncomment this codeblock

5. Environment Variables

You’ll need to create your own .env file in the root of your project and add the necessary variables mentioned.

  • JWT_SECRET
  • MONGODB_URI - mongodb://hostnameWithUsernameAndPassoword/databasename replace this string with appropriate URL

6. Start the Server

Once everything is set up, you can start the server by running the following command in your terminal:

npm start

This will open a http://localhost:3000 site.