Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Making API Using Node and Express
syed kamruzzaman
syed kamruzzaman

Posted on

     

Making API Using Node and Express

In this tutorial, we are making API for a Movie Portal. Here we use NodeJs, Express-5.0, and other necessary Packages. We are Trying to Follow the MVC Pattern.

Step 1 : Scaffolding
Open your terminal and type

npm init
Enter fullscreen modeExit fullscreen mode

Fill up your required field. Then open your visual studio or any kind of editor. Create .env file type this-

PORT= 8000DATABASE_URL = "mongodb://localhost:27017"IMAGE_BASE_URL = "http://127.0.0.1:8000"DBNAME = "exress_movie_api"
Enter fullscreen modeExit fullscreen mode

Then create the following folders-

  1. controllers
  2. db
  3. routes
  4. helpers
  5. middleware
  6. public / uploads
    • category
    • movie

Image description

Now install this app-

  1. express
  2. cors
  3. dotenv
  4. joi
  5. bcryptjs
  6. jsonwebtoken
  7. mongoose
  8. multer
  9. nodemon
  10. uuid

Image description
And here, in your package.json file add“type”: “module” because we are using express-5.0. if you don’t do that in your .js file import is not work.
After That, create an app.js file in your root folder. Here you type this –

import cors from 'cors';import dotenv from 'dotenv';import express from 'express';import connectiondb from './db/connectiondb.js';dotenv.config();const app = express();const port = process.env.PORT || 8000;const DATABASE_URL = process.env.DATABASE_URL || "mongodb:://localhost:27017";//connection databaseconnectiondb(DATABASE_URL);//app use for different purposeapp.use(cors());app.use(express.json());app.use(express.urlencoded({ extended:true}))app.listen(port, ()=>{    console.log(`server listening at http://localhost:${port}`)})
Enter fullscreen modeExit fullscreen mode

Now create db folder insideconnectiondb.js file and type this-

import mongoose from 'mongoose';//database connectionconst connectiondb = async(DATABASE_URL)=>{    try{        const options = {            dbName: process.env.DBNAME        }        const connectionResult = await mongoose.connect(DATABASE_URL, options);        console.log(`connection to mongoDB on database: ${connectionResult.connections[0].name} at ${new Date().toDateString()}`);    }catch(err){        console.log(err);    }}export default connectiondb;
Enter fullscreen modeExit fullscreen mode

Now last. Open your MongoDB and Create a Database. Database Name will be“express_movie_api” and Collection Name is “movies”;
Now open your terminal and type npm run dev. You can see this-

Image description

If you see your database name and current date then your connection will be ok. You are now going to the next step.

Step-2 : Model Defined
In your models folder make these files.

  1. User.js
  2. Category.js
  3. Movie.js

And Type this.
User.js

import mongoose from "mongoose";const DataSchema = new mongoose.Schema({    name: {        type: String,        trim: true,        required: true,        maxlength: 32,    },    email: {        type: String,        trim: true,        required: true,        unique: true,    },    password: {        type: String,        required: true    },},{ timestamps: true, versionKey:false })const User = mongoose.model('User', DataSchema);export default User;
Enter fullscreen modeExit fullscreen mode

Category.js

import mongoose from "mongoose";const DataSchema = new mongoose.Schema({    name: {        type: String,        required: [true, 'Please enter name'],        trim: true,        maxLength: [100, 'Category name cannot exceed 100 characters']    },    image: {         type: Object,     },},{ timestamps: true, versionKey:false })const Category = mongoose.model('Category', DataSchema);export default Category;
Enter fullscreen modeExit fullscreen mode

Movie.js

import mongoose from "mongoose";const DataSchema = new mongoose.Schema({    title: {        type: String,        required: [true, 'Please enter name'],        trim: true,        maxLength: [100, 'Category name cannot exceed 100 characters']    },    category_id: {        type: mongoose.Types.ObjectId,        ref: "Category",        required: true    },    descriptin: {        type: String,        trim: true,    },    image: {         type: String,         required: true    },},{ timestamps: true, versionKey:false })const Movie = mongoose.model('Movie', DataSchema);export default Movie;
Enter fullscreen modeExit fullscreen mode

Step-3 : Helpers Function define

Now you create some auxiliary function. This functions as some kind of middleware. Create this-

  1. bcryp.js
  2. jwt.js

bcryp.js Function Helping client password encoded and decoded.

import bcrypt from 'bcryptjs';export const hashMaker = (str)=> {    const salt = bcrypt.genSaltSync(10);    return bcrypt.hashSync(str, salt);}export const matchData = (str, hash)=> {    return bcrypt.compareSync(str, hash);}
Enter fullscreen modeExit fullscreen mode

jwt.js function helping Jwt token create and decoded this token.

import jwt from 'jsonwebtoken';const secret = "@#$%^&*&*"export const createToken = (payload)=> {    return jwt.sign(payload, secret, { expiresIn: '1d' }); //1day}export const decodeToken = (payload)=> {    return jwt.verify(payload, secret);}
Enter fullscreen modeExit fullscreen mode

Step-4: Making Some Middleware.
In your middleware folder create some middleware file. Like this-

  1. auth.js
  2. fileFolderName.js
  3. fileUpload.js

auth.js

import { decodeToken } from '../helpers/jwt.js';const auth = (req, res, next)=> {    try {        const token = req.headers.authorization.split(' ')[1];        req.user = decodeToken(token);        //console.log(req.user)        next();    } catch (err) {        res.status(400).send('Authentication Failed')    }}export default auth;
Enter fullscreen modeExit fullscreen mode

fileFolderName.js

const fileFloderName = (folderName) =>{    return ( req, res, next)=>{        req.folderName = folderName;        next();    }}export default fileFloderName
Enter fullscreen modeExit fullscreen mode

fileUpload.js

import multer from 'multer';const storage = multer({  storage: multer.diskStorage({    destination: function (req, file, cb) {      const folderName = req.folderName ?? file.fieldname;      cb(null, `public/uploads/${folderName}`);    },    filename: function (req, file, cb) {      cb(null, `${Date.now()}-${file.originalname}`);    },  }),  fileFilter: function (req, file, cb) {    const allowedMimeTypes = ['image/jpeg', 'image/png']; // Specify the allowed image file types    if (allowedMimeTypes.includes(file.mimetype)) {      cb(null, true); // Accept the file    } else {      cb(new Error('Invalid file type. Only JPEG and PNG files are allowed.')); // Reject the file    }  },  limits: {    fileSize: 2 * 1024 * 1024, // Set the maximum file size (2MB in this example)  },});export default storage;
Enter fullscreen modeExit fullscreen mode

After that Create validation folder for validation field and then create this file

  1. userSingupValidator.js
  2. categoryStoreValidator.js
  3. movieStoreValidator.js

userSingupValidator.js

import Joi from 'joi';export const userSignupValidator = (req, res, next) => {  const schema = Joi.object({    name: Joi.string().required().messages({      'any.required': 'Name is required',    }),    email: Joi.string().email().required().messages({      'string.email': 'Email must be a valid email address',      'any.required': 'Email is required',    }),    password: Joi.string()      .min(6)      .required()      .pattern(new RegExp('^[a-zA-Z0-9]{3,30}$'))      .messages({        'string.min': 'Password must be at least 6 characters',        'any.required': 'Password is required',        'string.pattern.base': 'Password must contain only alphanumeric characters',      }),      password_confirmation: Joi.string()      .valid(Joi.ref('password'))      .required()      .messages({        'any.only': 'Password confirmation must match the password',        'any.required': 'Password confirmation is required',      }),      job: Joi.string().optional(),  });  const { error } = schema.validate(req.body);  if (error) {    const errorMessage = error.details[0].message;    return res.status(400).json({ error: errorMessage });  }  next();};
Enter fullscreen modeExit fullscreen mode

categoryStoreValidator.js

import Joi from 'joi';export const categoryStoreValidator = (req, res, next) => {  const schema = Joi.object({    name: Joi.string()    .required().    messages({        'string.name': 'Name is required'       }),  });  const { error } = schema.validate(req.body);  if (error) {    const errorMessage = error.details[0].message;    return res.status(400).json({ error: errorMessage });  }  next();};
Enter fullscreen modeExit fullscreen mode

movieStoreValidator.js

import Joi from 'joi';export const movieStoreValidator = (req, res, next) => {  const schema = Joi.object({    title: Joi.string()    .required().    messages({        'string.name': 'Name is required'       }),    category_id: Joi.string()    .required().    messages({        'string.category_id': 'Category Name is required'    }),     image: Joi.string()    .required().    messages({        'string.image': 'image is required'    }),   });  const { error } = schema.validate(req.body);  if (error) {    const errorMessage = error.details[0].message;    return res.status(400).json({ error: errorMessage });  }  next();};
Enter fullscreen modeExit fullscreen mode

Step-5 : Route define
In your routes folder create this file-

  • rootRoute.js
  • authRoute.js
  • categoryRoute.js
  • movieRoute.js

rootRoute.js

In this file you add this code-

import express from 'express';import multer from 'multer';import CategoryRoute from './CategoryRoute.js';import authRoute from './authRoute.js';import movieRoute from './movieRoute.js';const route = (app)=>{    app.use(express.static("public/uploads/category"));    app.use(express.static("public/uploads/movie"));    app.use("/api", authRoute);    app.use("/api", CategoryRoute);    app.use("/api", movieRoute);    //Multer Error File Handling    app.use((err, req, res, next) => {        if (err instanceof multer.MulterError) {        // Multer-specific errors        return res.status(418).json({            err_code: err.code,            err_message: err.message,        });        } else {        // Handling errors for any other cases from whole application        return res.status(500).json({            err_code: 409,            err_message: "Something went wrong!",        });        }    });    //unknown route    app.use('*', (req, res)=>{        res.status(404).json({status:"fail", data:"Route does not exists"})    })}export default route;
Enter fullscreen modeExit fullscreen mode

here first we define static folder for save image.

app.use(express.static("public/uploads/category"));app.use(express.static("public/uploads/movie"));
Enter fullscreen modeExit fullscreen mode

Like category image and movie image. Then write error handling image function-

//Multer Error File Handling    app.use((err, req, res, next) => {        if (err instanceof multer.MulterError) {        // Multer-specific errors        return res.status(418).json({            err_code: err.code,            err_message: err.message,        });        } else {        // Handling errors for any other cases from whole application        return res.status(500).json({            err_code: 409,            err_message: "Something went wrong!",        });        }    });
Enter fullscreen modeExit fullscreen mode

At the end we write unknown route handler function. If user didn’t write proper url then show message“Route does not exists”

//unknown route    app.use('*', (req, res)=>{        res.status(404).json({status:"fail", data:"Route does not exists"})    })
Enter fullscreen modeExit fullscreen mode

Now go toapp.js file and add this line-

import rootRoute from './routes/rootRoute.js';rootRoute(app);
Enter fullscreen modeExit fullscreen mode

like this way-

import cors from 'cors';import dotenv from 'dotenv';import express from 'express';import connectiondb from './db/connectiondb.js';import rootRoute from './routes/rootRoute.js';dotenv.config();const app = express();const port = process.env.PORT || 8000;const DATABASE_URL = process.env.DATABASE_URL || "mongodb:://localhost:27017";//connection databaseconnectiondb(DATABASE_URL);//app use for different purposeapp.use(cors());app.use(express.json());app.use(express.urlencoded({ extended:true}))rootRoute(app);app.listen(port, ()=>{    console.log(`server listening at http://localhost:${port}`)})
Enter fullscreen modeExit fullscreen mode

Again we go torootRoute.js file. Here we first discuss about authRoute which we are importing from this

import authRoute from './authRoute.js';
Enter fullscreen modeExit fullscreen mode

so, createauthRoute.js file in the routes folder and write this code-

import express from 'express';import AuthController from '../controllers/AuthController.js';import auth from '../middleware/auth.js';import { userSignupValidator } from '../middleware/validation/userSingupValidator.js';const router = express.Router();router.post('/register', userSignupValidator, AuthController.registration);router.post('/login', AuthController.login);router.post('/logout', AuthController.logout);router.post('/change-password', auth, AuthController.changePassword);export default router;
Enter fullscreen modeExit fullscreen mode

Then go to the controllers folder createAuthController.js file and write this-

import { hashMaker, matchData } from "../helpers/bcryp.js";import { createToken } from "../helpers/jwt.js";import User from "../models/User.js";class UserController {  static registration = async (req, res) => {    try {      const { name, email, password, password_confirmation } = req.body;      const existEmail = await User.findOne({ email }).lean().exec();      if (existEmail) {        return res.status(413).json({          code: 201,          message: "This Email is already used.",        });      }      const hashPassword = hashMaker(password);      const registerUser = await new User({        name: name,        email: email,        password: hashPassword,      }).save();      console.log("userEmail", hashPassword);      res.status(201).json({        code: 201,        message: "User registration Successfully.",        payload: registerUser,      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  }  static login = async (req, res) =>{    try {        const { email, password } = req.body;        const existEmail = await User.findOne({ email }).lean().exec();        //mail check        if (!existEmail) {          return res.status(413).json({            code: 201,            message: "crediential didn't match",          });        }        const hashPassword = matchData(password, existEmail.password);        //password check        if(!hashPassword){            return res.status(413).json({                code: 201,                message: "crediential didn't match",              });        }        const {_id, name} = existEmail        const payload ={            name,            email,            token: "Bearer " + createToken({ _id, email })        }        res.status(200).json({            code: 200,            message: "User Login Successfully.",            payload        });      } catch (err) {        console.log(err);        res.status(500).json({          code: 500,          message: "Internal server error.",        });      }  }  static logout = (req, res)=>{      try {        // Clear the token from the cookie        res.clearCookie('token');        res.status(200).json({          code: 200,          message: 'User logged out successfully.',        });      } catch (err) {        console.log(err);        res.status(500).json({          code: 500,          message: "Internal server error.",        });      }  }  static changePassword = async(req, res)=>{    const {password, password_confirmation } = req.body;    try{      const {_id} = req.user;      if (password !== password_confirmation) {        return res.status(413).json({          code: 201,          message: "crediential didn't match",        });      }      const userInfo = await User.findById(_id);      const hashPassword = hashMaker(password);      userInfo.password = hashPassword;      await userInfo.save();      console.log(userInfo)      //await User.updateOne({ _id: _id }, { $set: payload }, { upsert: false });      res.status(200).json({        code: 200,        message: "passwrod Change Successfully.",    });    }catch(err){      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  }}export default UserController;
Enter fullscreen modeExit fullscreen mode

Image description

Is your output similar to this congratulation, you have successfully user registration. Now we are testing the login route.

Image description

If you log in successfully then we can see the token. This token is a jwt token. We can now use this token as an authentication.

Now we go to again rootRoute.js and this time we are talking about CategoryRoute.js. So create this file and write this

CategoryRoute.js

import express from 'express';import CategoryController from '../controllers/CategoryController.js';import fileFolderName from '../middleware/fileFolderName.js';import storage from '../middleware/fileUpload.js';import { categoryStoreValidator } from "../middleware/validation/categoryStoreValidator.js";const router = express.Router();router.get("/all-category", CategoryController.allCategory);router.get("/category-wise-movies", CategoryController.categoryWiseMovie);router.get("/single-category/:categoryId", CategoryController.singleCategory);router.post(  "/category-store",  //auth,  categoryStoreValidator,  fileFolderName("category"),  storage.fields([{ name: "image", maxCount: 1 }]),  CategoryController.store);router.put(  "/category-update/:categoryId",  //auth,  categoryStoreValidator,  fileFolderName("category"),  storage.fields([{ name: "image", maxCount: 1 }]),  CategoryController.update);router.delete(  "/category-delete/:categoryId",  //auth,  //categoryStoreValidator,  fileFolderName("category"),  storage.fields([{ name: "image", maxCount: 1 }]),  CategoryController.delete);// //find product by idrouter.param("categoryId", CategoryController.categoryById);export default router;
Enter fullscreen modeExit fullscreen mode

Here you see, we write router.param("categoryId", CategoryController.categoryById). This route is a special route, like when we call single route –
router.get("/single-category/:categoryId", CategoryController.singleCategory);

here this route we passed categoryId param. So this param first calls router. param route and after that call single-category route. It helps for reduce query.

Now we go to the controllers folder createCategoryController.js and write this

import fs from "fs";import Category from "../models/Category.js";import Movie from "../models/Movie.js";class CategoryController {  //find a Category by  id  static categoryById = async (req, res, next, id) => {    const category = await Category.findById(id);    if (!category) {      return res.status(404).json({        code: 404,        message: "Category not found.",      });    }    req.category = category;    // console.log('cat result', req.category)    next();  };  //all Category  static allCategory = async (req, res) => {    try {      const imageBaseURL = process.env.IMAGE_BASE_URL;      const allCategory = await Category.find();      // Update the image URL for each category      const updatedCategoryList = allCategory.map((category) => {        return {          ...category._doc,          image: `${imageBaseURL}/${category.image}`,        };      });      res.status(200).json({        message: "All Category",        data: updatedCategoryList,      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };  //Category wise movies  static categoryWiseMovie = async (req, res) => {    try {      const imageBaseURL = process.env.IMAGE_BASE_URL;      const allCategories = await Category.find();      // Update the image URL for each category      const updatedCategoryList = await Promise.all(allCategories.map(async (category) => {        // Find all movies related to this category        const movies = await Movie.find({ category_id: category._id });        // Update the image URL for each movie        const updatedMovies = movies.map((movie) => {          return {            ...movie._doc,            image: `${imageBaseURL}/${movie.image}`,          };        });        return {          ...category._doc,          image: category.image ? `${imageBaseURL}/${category.image}` : null,          movies: updatedMovies,        };      }));      res.status(200).json({        message: "Category-wise Movies",        data: updatedCategoryList,      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }};  //singel Category  static singleCategory = async (req, res) => {    const imageBaseURL = process.env.IMAGE_BASE_URL;    const category = req.category;    category.image = `${imageBaseURL}/${category.image}`;    res.status(200).json({      message: "Single Category",      data: category,    });  };  //store category  static store = async (req, res) => {    const { name } = req.body;    const image = req.files.image[0].filename;    try {      // const categoryInfo = await new Category({      //     name,      //     image: image ?? ''      // }).save()      console.log("controller req", image);      const categoryInfo = await Category.create({        name,        image: image,      });      res.status(200).json({        message: "Category Create Successfully",        data: categoryInfo,      });    } catch (err) {      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };  //Category update or edit  static update = async (req, res) => {    const { name } = req.body;    const imageBaseURL = process.env.IMAGE_BASE_URL;    let image = null; // Initialize image as null    let existingCategory = req.category;    try {      if (req.files && req.files.image) {        // If a new image then delete the old image        if (existingCategory && existingCategory.image) {          fs.unlinkSync(`public/uploads/category/${existingCategory.image}`);        }        // Save the new image        image = req.files.image[0].filename;      }      existingCategory.name = name ? name : existingCategory.name;      existingCategory.image = image ? image : existingCategory.image;      existingCategory.save();      // Update the image URL with the base URL      const updateCategory = await Category.findById(existingCategory._id);      updateCategory.image = `${imageBaseURL}/${updateCategory.image}`;      res.status(200).json({        message: "Category updated successfully.",        data: updateCategory,      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };  //delete category  static delete = async (req, res) => {    try {      // Find the category by ID      const category = req.category;      // Delete the category's image file if it exists      if (category.image) {        fs.unlinkSync(`public/uploads/category/${category.image}`);      }      // Delete the category from the database      await Category.deleteOne({ _id: category._id });      res.status(200).json({        message: "Category deleted successfully.",      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };}export default CategoryController;
Enter fullscreen modeExit fullscreen mode

Now again open your postman and test this api like this way

Image description

Image description

Now we are discussing movie route. So go to routes folder and create this-

movieRoute.js

import express from "express";import MovieController from "../controllers/MovieController.js";import fileFolderName from "../middleware/fileFolderName.js";import storage from "../middleware/fileUpload.js";import { movieStoreValidator } from "../middleware/validation/movieStoreValidator.js";import auth from '../middleware/auth.js';const router = express.Router();router.get("/all-movies", MovieController.allMovie);router.get("/top-movies", MovieController.topMovie);router.get("/single-movie/:movieId", MovieController.singleMovie);  router.post(    "/movie-store",    //auth,    movieStoreValidator,    fileFolderName("movie"),    storage.fields([{ name: "image", maxCount: 1 }]),    MovieController.store  );  router.post(    "/ai-movie-store",    //auth,    fileFolderName("movie"),    storage.fields([{ name: "image", maxCount: 1 }]),    MovieController.aiStore  );  router.put(    "/movie-update/:movieId",    //auth,    fileFolderName("movie"),    storage.fields([{ name: "image", maxCount: 1 }]),    MovieController.update  );  router.delete(    "/movie-delete/:movieId",    //auth,    MovieController.delete  );//   //find product by id router.param("movieId", MovieController.movieById);  export default router;
Enter fullscreen modeExit fullscreen mode

and then go to controllers folder and create this-
MovieController.js

import fs from "fs";import { v4 } from "uuid";import Movie from '../models/Movie.js';class MovieController{  //find a movie by  id  static movieById = async (req, res, next, id) => {    const movie = await Movie.findById(id);    console.log('movie info', movie)    if (!movie) {      return res.status(404).json({        code: 404,        message: "Movie not found.",      });    }    req.movie = movie;    // console.log('cat result', req.category)    next();  };  //all Movie  static allMovie = async (req, res) => {    try {      const imageBaseURL = process.env.IMAGE_BASE_URL;      const allMovie = await Movie.find().populate('category_id');      // Update the image URL for each category      const updatedMovieList = allMovie.map((movie) => {        return {            ...movie._doc,            image: `${imageBaseURL}/${movie.image}`,            category_id: {              ...movie.category_id._doc,              image: `${imageBaseURL}/${movie.category_id.image}`,            },          };      });      res.status(200).json({        message: "All Movie",        data: updatedMovieList,      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };  //Top Movie  static topMovie = async (req, res) => {    try {      const imageBaseURL = process.env.IMAGE_BASE_URL;      const topMovies = await Movie.find()        .sort({ createdAt: -1 })         .populate('category_id')        .limit(8);       // Update the image URL for each movie      const updatedTopMovies = topMovies.map((movie) => {        return {          ...movie._doc,          image: `${imageBaseURL}/${movie.image}`,          category_id: {            ...movie.category_id._doc,            image: `${imageBaseURL}/${movie.category_id.image}`,          },        };      });      res.status(200).json({        message: "Top 8 Movies",        data: updatedTopMovies,      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };  //singel Category  static singleMovie = async (req, res) => {    const imageBaseURL = process.env.IMAGE_BASE_URL;    const movie = req.movie;    await movie.populate('category_id');    movie.image = `${imageBaseURL}/${movie.image}`;    movie.category_id.image = `${imageBaseURL}/${movie.category_id.image}`;    res.status(200).json({      message: "Single movie",      data: movie,    });  };   //store Movie   static store = async (req, res) => {    const { title, discription, category_id } = req.body;    const image = req.files.image[0].filename;    try {        const movieInfo = await Movie.create({        title,        discription,        category_id,        image: image,      });      res.status(200).json({        message: "Movie Create Successfully",        data: movieInfo,      });    } catch (err) {      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };  //Ai movie store  static aiStore = async (req, res) => {    const { title, category_id, description, image } = req.body;    console.log('node-1', req.body)    // Convert the base64 image data to a buffer    const imageBuffer = Buffer.from(image, 'base64');    // Generate a unique filename for the image using UUID    const imageName = `${v4()}.jpg`;    try {      // Save the image to a directory (you can change the path as needed)      fs.writeFileSync(`./public/uploads/movie/${imageName}`, imageBuffer);      // Save the movie information to the database      const movieInfo = await Movie.create({        title,        description,        category_id,        image: imageName,      });      res.status(200).json({        message: "Movie Create Successfully",        data: movieInfo,      });    } catch (err) {      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };  //Category update or edit  static update = async (req, res) => {    const { title, discription, category_id } = req.body;    const imageBaseURL = process.env.IMAGE_BASE_URL;    let image = null; // Initialize image as null    let existingMovie = req.movie;    try {      if (req.files && req.files.image) {        // If a new image then delete the old image        if (existingMovie && existingMovie.image) {          fs.unlinkSync(`public/uploads/movie/${existingMovie.image}`);        }        // Save the new image        image = req.files.image[0].filename;      }      console.log('movie data', title, discription, category_id)      existingMovie.title = title ? title : existingMovie.title;      existingMovie.discription = discription ? discription : existingMovie.discription;      existingMovie.category_id = category_id ? category_id : existingMovie.category_id;      existingMovie.image = image ? image : existingMovie.image;      existingMovie.save();      console.log("existingMovie", existingMovie)      // Update the image URL with the base URL      const updateMovie = await Movie.findById(existingMovie._id);      updateMovie.image = `${imageBaseURL}/${updateMovie.image}`;      res.status(200).json({        message: "Movie updated successfully.",        data: updateMovie,      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };  //delete category  static delete = async (req, res) => {    try {      // Find the category by ID      const movie = req.movie;      // Delete the category's image file if it exists      if (movie.image) {        fs.unlinkSync(`public/uploads/movie/${movie.image}`);      }      // Delete the category from the database      await movie.deleteOne({ _id: movie._id });      res.status(200).json({        message: "movie deleted successfully.",      });    } catch (err) {      console.log(err);      res.status(500).json({        code: 500,        message: "Internal server error.",      });    }  };}export default MovieController
Enter fullscreen modeExit fullscreen mode

Now we do finish touch. Open postman and test it, like this-

Image description

Image description

Image description

So, our 1st part is done. Now we will do 2nd part
Scaffolding redux-toolkit in NextJs.Link

full Project github
Node
https://github.com/kamruzzamanripon/node-movie-api
NextJs
https://github.com/kamruzzamanripon/next-movie-ui-with-node-api
NextJs UI
https://github.com/kamruzzamanripon/next-movie-ui

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Frontend and Backend Full Stack Developer
  • Location
    Dhaka, Bangladesh
  • Education
    Master of Economic
  • Joined

More fromsyed kamruzzaman

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp