DEV Community

Discussion on: Help with a beginner's project! An app with Front and Back-end.

Collapse
 
sergchr profile image
Serhii

Hi, Lucas!
I'm not telling about best practices, but from my experience:

  • Yes, you can use JWT + Passport.js for the purpose you described. Passport gives you the simplicity of integrating many authentication schemes such as raw email + password, Twitter, Google, etc. You can also use just JSON web tokens, it will be simpler as you don't necessarily need Passport.js. Say, you have "/sign-up" endpoint where you create a JWT token and write required payload (in your case it is at least a role of a user) and send it back to a client and "/sign-in" where you authenticate a user. When a client makes a request to your backend, you can parse[1] a JWT token to extract a user's role and define the next logic.

[1] For this purpose you can have a middleware, which can be used in protected endpoints, that extract a JWT token from a request (e.g. a client sends a token in the request body), decodes it and receives a user's role (and other payloads if you put it there) and you can put the extracted payload to, say, "req.user", so it will be available in your next functions (endpoints handlers - controllers):

handleProtectedEndpoint (req, res) {
 const role = req.user.role;
 if (role === 'STORE') {
  // ... 
 }
 return res.sendStatus(200);
}

"The relationship between a STORE user and it's sub-users would be one-to-few. So, should I have them referenced inside my schema or actually embed them inside the STORE schema?"

You could embed other documents (users as you say) to a user document, like this:

// define a User model, pseudocode
const user = mongodb.Schema({
 email: { type: String, required: true, unique: true },
 role: { type: String, required: true },
 password: { type: String },

 // you'll put sub-users here
 users: { type: Object },
})

But this method has cons:

  • "users" field uses a document space not in a good way: takes additional space + duplicating users.
  • what if you need to know if a particular user is belonging to a store? You will need to fetch all the stores and parse their users to find out.
  • in case of updating "user" schema - e.g. adding/removing/changing existed fields, say, you rename "email" field to "emailAddress" and add a field "name" with default value - in this case, "users" you put in stores will be outdated and you need to make additional checks on documents fetching or to make a manual migration.

So, it is better to make a reference, like this:

// define a User model, pseudocode
const user = mongodb.Schema({
 // ... user's fields

 // so, "users" is an array of User references
 users: [{ type: mongodb.ObjectId, ref: 'User' }],
})

And in case you need to find out what users belong to a store, your query will be:

// mongoose pseudocode
const users = await User.findOne({ email: storeEmail }).populate('users');
// "populate" will fetch users documents by references
Collapse
 
theuserll profile image
L.L.

Wow Sergiy, thank you for your detailed response. I am glad that I actually fully understand both.😁. I didn't think about the cons in embedding before posting. It makes sense to me the pros in referencing. Thanks again!