M. Çağlar TUFAN
M. Çağlar TUFAN

Reputation: 910

Express REST API router and Mongoose schema design

I'm learning how to create REST API with Mongoose (MongoDB).

I'm trying to develop an Express REST API with Mongoose. What I'm trying to do is simple but I'm not sure which way to design both REST API end points and Mongoose schemas.

I have users schema for now, and each user object has only username and password. To list, add, modify and delete users I have a /api/users end point.

models/user.js:

const userSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    }
});

routes/users.js

router.get('/', async (req, res, next) => {
    // List all users
});

router.get('/:id', async (req, res, next) => {
    // Get user with specified id
});

router.post('/', async (req, res, next) => {
    // Create user with given body
});

router.put('/:id', async (req, res, next) => {
    // Update user with given id and body
});

router.delete('/:id', async (req, res, next) => {
    // Remove user with given id
});

Now, what I want to do is users to have documents. They will be able to create documents, rename them, change them or delete them. I searched about how I should implement this idea to my API and I found out 3 choices.

  1. Normalization: Create another Mongoose model named documents and give referances to documents in user model.

  2. Denormalization (Embedding): Add documents attribute in user model and add each document to user object directly.

  3. Hybrid: If my documents model going to have many attributes, I should to create document model seperately and give references to user objects along with the necessary document data to store in user object.

I will not have many attributes in my document model, I think I will only need path and dateCreated attributes in my document model. So, I will be using 1st or 2nd option. Which one should I use? Is there any any better method for this particular situation?

My second question is about users.js router end points to list, add, change and remove documents of users. Should I create another router file for these operations like routers/documents.js and use end point like /api/documents/? If so what end points I am going to need like router.get('/:userId/'), router.get('/:userId/:documentId') etc.? Or should I add new end points in existing users router like /api/users/:id/add_document/, /api/users/:id/documents/ etc.?

Thanks in advance.

Upvotes: 2

Views: 414

Answers (1)

derstauner
derstauner

Reputation: 1796

For your first question, please visit my answer here:

embedding vs referencing

For the second I would create a separate router file following the separation of concerns pattern and concerning endpoint I would choose router.get('/:userId/:documentId'), because if I unterstand you correctly, every document belongs to an user.

Upvotes: 1

Related Questions