Wix is a great platform for quickly building small websites with a minimal amount of code.
On top of Wix, Velo is also capable of powering large custom applications on top of Wix.
Such applications require tens of thousands of lines of code and they can rapidly transform into an unmaintainable mess if we are not organized.
In order to manage large codebases, we need to structure our project so it stays easy to extend as the number of functions increases while remaining maintainable and simple to debug.
Here is an example of the directory structure we use for our large projects. Each directory listed below contains 1 or more javascript files that expose modules that are used in the project
1. Entities
The folder where we store our business logic. Business logic is all the rules that are dictated by business and real-world processes. We split business logic into units called Entity.
An entity should contain all actions that are performed by an actor/object of our system. For example, a candy store will have entities such as:
Candy
Client
Employe
Because business logic should only contain business-related code, entities should be independent of the platform, security, and storage system.
Therefore they should only import methods from services and repositories and should be agnostic of Wix modules.
2. Repositories
Repositories contain our storage system. it acts as an interface between our code and our storage logic so that the rest of our application does not need to know how the storage system works and simply relies on methods provided by the repository. As we do for business logic, we split storage logic into units called Repository. A repository should expose methods to read and write data for a given entity. We want to keep methods as simple as possible so that we can reuse them across many use cases. For instance a candy repository:
queryCandies(filters)
getCandiesForCategory(categoryId)
updateCandy(candy)
...
On Velo, this means essentially working with the Wix-data API. But you could also have a repository pointing to another online database service such as MongoDB or Google Cloud.
3. Services
Now that we have our business logic and our storage logic, we use services to host generic code. Again, a service should restrict its logic to a given domain such as:
Sending emails
Managing files,
Interfacing with third-party API
...
As for repositories, services should not expose platform-related code. This means we could change the underlying provider without impacting the code. Take for instance the email service, It exposes a method to send emails:
emailService.send(recipient, templateId, templateData)
That method should not change if emails are sent via Wix or Sendgrid.
Most of the time we create those services as Velo packages so they can be reused across several projects.
4. Web modules
Web modules are the dispatchers/gatekeepers for our backend. Since our entities and repositories are system independent, this is where we handle authentication and authorization. A web module should only expose entities' and repositories' methods that are required by the frontend while ensuring that the user has the right to invoke them.
We also use web modules as a logging layer to monitor and debug our website. It's also where we manage errors so that any problem occurring in the backend can be gracefully handled for the frontend.
5. Hooks
Wix Data specifics directory, we use entities and repository to enforce some data logic. For more information about how to use hooks check out our post about hooks.
6. RouterS
Finally, the routers directory contains all routing logic (router pages). Routers should rely on services, repositories, and entities to construct routing logic.
The main benefit of following such a hierarchy strictly is that everything has its place. This means we spend less time searching through files for a given feature and debugging become easier:
There is a computation error, that’s an entity problem
Data is not saved that’s a faulty repository
Emails are not sent that’s probably a service issue,...
Let me know if you plan on using a similar structure for your next project or if you have a better one. As always if you have any questions can contact me via the forum (@kentin)
Comments