This is the backend for a blogging application built with Node.js, Express, TypeScript, and MongoDB.
- Admin authentication with JWT
- CRUD operations for posts
- CRUD operations for categories
- Public routes for published posts and categories
- Centralized error handling
This backend is a classic REST API that you can interact with using any HTTP client (like Postman, Insomnia, or even your web browser for GET requests).
First, you need to start the server. In your terminal, from the project's root directory, you run:
npm run devThis command does two things:
- It uses
ts-node-devto compile your TypeScript code (.tsfiles) into JavaScript on the fly. - It starts a web server using Express, which will listen for incoming HTTP requests on the port you defined in your
.envfile (e.g.,3000).
- MongoDB: Your data (admins, posts, categories) is stored in a MongoDB database. The server connects to this database when it starts up.
- Mongoose: Mongoose is used as an Object Data Modeling (ODM) library. It allows you to define schemas for your data (like the
PostSchemaorCategorySchema) and provides a straightforward way to interact with the database (e.g.,Post.find(),Category.findById()).
- Seeding the Admin: Before you can do anything that requires authentication, you need an admin user. The
npm run seedcommand creates this user in the database. - Logging In: To get access to protected routes, you must first "log in" by sending a
POSTrequest to/api/auth/loginwith the admin's username and password. - Getting a JWT: If the credentials are correct, the server responds with a JSON Web Token (JWT). This token is like a temporary key or a pass.
- Accessing Protected Routes: To access a protected route (like creating a post), you must include this JWT in the
Authorizationheader of your request, like this:Authorization: Bearer <your_jwt_token>. - The
protectMiddleware: Every time you make a request to a protected route, theprotectmiddleware runs. It checks for a valid JWT in the header. If the token is valid, it allows the request to proceed to the controller. If not, it sends back a401 Unauthorizederror.
Let's say you want to create a new blog post. Here's how you would do it:
-
Log in:
- Send a
POSTrequest tohttp://localhost:3000/api/auth/loginwith the admin username and password in the request body. - The server will send you back a JWT. Copy this token.
- Send a
-
Create a Category (Optional):
- If you want to assign your post to a new category, send a
POSTrequest tohttp://localhost:3000/api/categories. - In the request body, include the category name (e.g.,
{ "name": "Technology" }). - Crucially, in the
Authorizationheader, include your JWT. - The server will create the category and send you back its details, including its unique ID.
- If you want to assign your post to a new category, send a
-
Create the Post:
- Send a
POSTrequest tohttp://localhost:3000/api/posts. - In the request body, include the post's details, like the title, content, and the ID of any categories you want to assign it to. You can also set its status to "published" or "draft".
{ "title": "My First Blog Post", "content": "This is the content of my first post.", "categories": ["<category_id_from_step_2>"], "status": "published" } - Again, you must include your JWT in the
Authorizationheader. - The server will create the post in the database and associate it with your admin account.
- Send a
Anyone can view your published content without needing to log in. For example, a frontend application could fetch all published posts by making a GET request to http://localhost:3000/api/public/posts. This route is not protected by the authMiddleware, so it's open to everyone.
In essence, you have a secure, admin-only area for managing content and a public-facing API for displaying that content.
- Node.js
- MongoDB
- Clone the repository:
git clone <repository-url>
- Install dependencies:
npm install
- Create a
.envfile in the root directory and add the following environment variables:PORT=3000 MONGODB_URI=mongodb://localhost:27017/blog JWT_SECRET=your_jwt_secret - Start the development server:
npm run dev
To create an admin user, run the following command:
npm run seedThis will create an admin user with the following credentials:
- Username:
admin - Password:
password
.
├── src
│ ├── config
│ │ └── db.ts
│ ├── controllers
│ │ ├── authController.ts
│ │ ├── categoryController.ts
│ │ └── postController.ts
│ ├── middlewares
│ │ ├── authMiddleware.ts
│ │ └── errorMiddleware.ts
│ ├── models
│ │ ├── Admin.ts
│ │ ├── Category.ts
│ │ └── Post.ts
│ ├── routes
│ │ ├── authRoutes.ts
│ │ ├── categoryRoutes.ts
│ │ ├── postRoutes.ts
│ │ └── publicRoutes.ts
│ ├── utils
│ │ └── generateToken.ts
│ └── server.ts
├── .env
├── package.json
├── tsconfig.json
└── seed.ts
PORT: The port the server will run on.MONGODB_URI: The connection string for your MongoDB database.JWT_SECRET: A secret key for signing JWT tokens.
Logs in an admin user and returns a JWT token.
Request Body:
{
"username": "admin",
"password": "password"
}Response:
{
"_id": "...",
"username": "admin",
"token": "..."
}Protected routes, requires JWT token.
GET /api/posts: Get all posts.GET /api/posts/:id: Get a single post by ID.POST /api/posts: Create a new post.PUT /api/posts/:id: Update a post.DELETE /api/posts/:id: Delete a post.
Protected routes, requires JWT token.
GET /api/categories: Get all categories.GET /api/categories/:id: Get a single category by ID.POST /api/categories: Create a new category.PUT /api/categories/:id: Update a category.DELETE /api/categories/:id: Delete a category.
No authentication required.
GET /api/public/posts: Get all published posts.GET /api/public/categories: Get all categories.