I'm currently getting started with NodeJS, MongoDB, Mongoose etc and got a few questions about Mongoose schemes/model best practices:
Is it acceptable to have multiple schemes/models for a single view? Let's take a calendar app for example. I have a single view for the calendar and several models like the CalendarModel (stores calendarID, color, owner etc) and the CalendarEventModel (contains info on the events to be shown in the calendar.) Is this a suitable approach?
In the above example, should there be a controller for each Model/Scheme or is it considered acceptable to have one controller that controls both models/schemes and puts them together into the single view that I have?
Would it be a good alternative to have one CalendarModel and store all CalendarEvents within that model, so that the model would consist of info like this: calendarID, owner, color, eventsList
Thank you! :)
There is no one simple answer to this problème. This really depends on what is the requirement. Here are a few pointers.
- Both have some pros and cons but I would say it is a suitable approach
Single View with multiple schemes/models
Pro:
- Allow to group data that change together in a schema
- Simple because only one view to use and all present
Con:
- A single view is great but changing data requires all the view to be loaded again
- A single view may not be reusable because it will tend to contain a lot of useless info if reused
Multiple View with multiple schemes/models
Pro:
- Very flexible and reusable.
- More control over the size of the data.
- A good grouping of data that change together (Granularity)
Con:
- More complex to manage
- May not new reusability
- Maybe overkill
- It depends on the job the controller does for the app. For this question, I would really ask myself the question of what is the goal of the controller. A big controller is simpler but does multiple things and it may become quickly a mess to maintain.
If you change a model and you have a single controller you have to change it and you may break the controller for another functionality.
If you change a model and you have multiple controllers you have to change a single point and it is more controlled but you are more vulnerable to create side effects on other views and controllers.
- This is a question of data.
Single Model
Pro:
- Simple
- Load once get all
- Less roundtrip
- All centralized
Con:
- Forced to store events and calendar in the same database
- No caching possible
- Large transfer size each time something change
- New event requires the update of the calendar
Multiple Models
Pro:
- More Control on the database for storage
- Possible to get pieces to size the data
- Possible to cache stable data
Con:
- More complex for migration and data coherence
- More roundtrip to the database or aggregation required
- Maybe overkill and more query and assembly
My approach to this example without knowing the exact requirement.
- I would separate the events and the main model.
- This allows to update and reload update without reloading the calendar
- Since the calendar does not change a lot I would cache (Redis or in process state) the calendar avoiding the database load.
- I could load events per month and years. This is great to keep the size small.
- If the requirements are fixed one controller and one view is good but rarely the requirements will change. Without over-engineering I would separate events and calendar in two-controller. When I add the custom font feature per calendar this will change the calendar model and controller only.
- The view can be a single instance for the global view but if I have a detailed event view also I would add another view. Each view has a single purpose and reuse is possible but not forced.
- Lastly, the business rule should stay in the same layer and not leak between. For instance, the rule that two events cannot be on the same day may be enforced by the controller. Another rule that says that event should be a move to an existing calendar should also be in the controller layer if decided so.
Notes: This is my opinion and there exist multiple opinions on the subject. Also, it is really dependant on the requirements. One good solution for one app/api may be the worst solution for another.
EDIT:
Single or Multiple Controllers
I would tend to group code that does a single purpose. Here if I have 2 models (event/calendar) and 2 views (Calendar overview and event detail) I would tend to have 2 controllers if they have different roles. If creating and editing can be directly done in the calendar overview, then use a single controller and the event detail use a subset of that same controller for its view. But calendar preference/overview and event management can be two different things. Note here that the number of models could be 5 or 7 and it would not matter. I could have 6 different schemas to help me with the storage and database but only have 1 controller.
Deciding the number of things
Models:
- An abstraction of the data and the storage solution (files, database, in memory,...). Therefore, choosing the correct representation depends on the desired data structure. Think about what changes and what can be group together.
- In this example, 1 model for Calendar(
{id, color, owner,...}
), 1 model for Events, 1 model for Owner, ... If you need to use SQL for Events ({id, calendar id, detail id}
) and Events details is in Mongo ({id, name, time, color, date, description}
) then use 2 models for the events.
Controllers:
- Represent a function and a way to interact with the user. Logical function grouping. And business rules centralization.
- In this example, there is 2 logical grouping, Calendar overview management with preference and Event update and creation and detail loading. Note that both controllers will use the Event model. The calendar will load the events of the current month but may just load the id, name and time. The Event controller will load only a specific event and allow it to create and update this event.
Views:
- These are representations of the data. This allows us to simplify the output and keep the model structure and the business rules from leaking. Nobody has to know that you may use 3 database kind to store your data and how your data is structured.
- In this example, there could be 3 or more views. There could be a per month overview and a per year overview. Each uses the calendar overview but are separate views because the data may not be structure exactly the same. Also, there could be an event list overview that uses the calendar overview controller. And event detail view.
Note that visually all views will be different but at the core, it is just a way to package the calendar and the selected events (1 month, 1 day, 1 year, all events) for the visual. If all the view turn out identical just create a single one but independent view allows you to change requirement. 1 day view may require more detail on events than the 1 year view.