Architecture


It's helpful to understand some of the philosophies behind Mojo at a very high level. These are abstract concepts, but will help construct a mental model of how to develop applications in a scalable, elegant way.

What is MV*?

MVC, MVP, MVVM, HMVC, these are design patterns to help develop web, or server-side applications. Let's disect a little bit what MVC actually means in Mojo.

The "M" in MVC represents a Model. A model can be anything that represents data, such as a person, message, or a collection of messages. Models might also have properties, and/or methods specific to the data it's representing. A good example might be Messages.markAllRead, Message.markRead, or User.logout.

The "C" in MVC represents a Controller. Controllers contain logic specifc to the view it's representing. The controller typically (but not always) displays information from a model, or many models to the view, and also relays any user interaction from the view, to the models. The controller effectively guards the model, or any part of the application from view-specific logic.

The "V" in MVC represents a View (or templates). Views take information from the controller, and display it to the user. Views also take any interaction, and relay them back to the controller.

In Mojo, it's possible to include the view with the controller (it's easier to implement up-front), but this practice is discouraged since it makes maintanence a bit more difficult. Designers for instance might have a harder time modifying templates if it means they have to dive into JavaScript files.

Notice the order of these terms - MCV - this is how data flows to the user . You typically start with a model which provides information to the controller, to the view, then finally to the user (model -> controller -> view -> user). Think of this like layers of your application.

Framework Layers

It might be easy to think of your application in layers, where each new layer is supported by the previous layer. In MVC, the layers might look something like:

service -> models -> controllers -> views -> user.

Each proceding layer can interact with the previous layer, but not vice-versa. This means that, as a rule of thumb, controllers can interact with models, and service, but models should never interact with controllers. Views can interact with controllers, but controllers shouldn't ever really interact with the views. And the obvious - users can interact with the view, but a view cannot interact with the user.

This sort of model also comes with many other benefits. For one, it'll make your application more maintainable, and testable. Another benefit is that parts of your application will become modular. For instance, you could theoretically take out just the service, and models and re-use them for an API server.

Thinking about applications development in layers also reduces the cognitive overhead of planning your application architecure. Layering encourages you to focus on what you need immediately, and nothing else. If you're focusing on the views, just focus on that, not their relationship between other parts of the application. This includes models, and the HTTP router.

Planning

See structuring your application for more info.

When starting a new project, it's helpful to know the application requirements before jumping into code. This usually involves a few things:

  1. What does the application look like?
  2. What sort of data does the application need to represent?

The first step is probably easier to tackle since we can visually breakdown our application, and know exactly how, and where the views should be laid out into a heirarchial folder structure.

For instance, when you look at a list of items in a mock-up, you can assume it's a list view. If you see a view that's clearly toggling between two states (pages), it's probably a stack view. Everything else is just a base view.

This sort of practice is easy to pick-up between other team members, and creates a consistent way to handle how view components are created. It's also easy for non-developers to follow, especially designers looking to change some of the UI elements. Maintaining a hierarchy of views in Mojo also makes it easy to move components around within your application if you need to perform any sort of maintainence, or refactoring.

Once you have an idea of how your application should be broken apart, you can start building your views with the data it needs to represent - step two.

You typically write fixtures (fake data) along with views, so you know what properties the view needs. Fixtures allow you to construct views independently from models - great for encapsulation. Mojo easily allows you to write views with just fixtures, then later on, swap them out for real models - like a flip of a switch.

Developing views with fixtures is also a great way of building apps indendently from any API (especially with teams of people, you can easily write front-end and backend apps in parallel with this method). Fixtures also make your views more testable, and give you an additional idea of what model relationships look like - similar to the practice of looking at your mock-ups before building your views.

After you've created your views with fixture data, you should have a clear idea of the models your application needs. This is a pretty straight forward process. See structuring models for more information.

After developing your models, you can add other parts of your application, such as an HTTP router, realtime data, offline mode, or internationalization. These sort of features are non-fundamental, and should always be added after you've figured the structure of your models & views.

If you're interested to see the above concepts applied in practice, checkout this demonstration of a reader application developed in less than 2 hours: