boron.9
boron.9

Reputation: 43

Best practice for validating input in Express/Mongoose app (controllers and models)

I'm new to node/express/mongoose and backend in general, and I'm building an API from the ground up.

I split my code into controllers and DAOs (mongoose models) and I'm not sure where validation should be taking place, what exactly should the controller and model each be doing?

For example, for the route GET /users/:id, I want it to:

Here's what I tried. It's currently doing everything I want above, but I'm not sure if it's the best implementation:

users.controller.js

const UserModel = require('../models/users.model')
const mongoose = require('mongoose')

exports.getById = async (req, res) => {
    // Check that the id is a valid ObjectId
    if (!mongoose.Types.ObjectId.isValid(req.params.id)) {
        return res.status(400).json({ error: 'Invalid ObjectID' })
    }

    try {
        const user = await UserModel.findById(req.params.id)

        if (!user) return res.status(404).json({ error: 'No user with this ID' })

        res.status(200).send(user)
    } catch (err) {
        res.status(500).send(err)
    }
}

users.model.js

exports.findById = async (id) => {
    let user = await User.findById(id)

    if (!user) {
        return null
    }

    user = user.toJSON()
    delete user._id
    delete user.__v
    delete user.password
    return user
}

Is this the best way to structure things? Please critique and suggest any improvements and best practices.

Upvotes: 1

Views: 530

Answers (1)

Vlaczas
Vlaczas

Reputation: 41

I prefer to do all validation and logic in Controllers file and helpers classes in separate small js files. Also trying to keep the models as lean as possible. Actually you can create different middleware functions to validate some inputs. It is also helpful to create ErrorResponse middleware so you can do such simple and easy to read validations as:

if (!userFromDB) throw new ErrorResponse({code: 404, msg: "User doesn't exist"})

than catch it and handle in separate file with different options of the answer.

Backend has 100+ ways of implementing it. You need to choose you own 😁

Upvotes: 0

Related Questions