Sweet Life or Building a Web App Without Coding
Let's create a simple social network for guests to communicate at a virtual party. Registered users can make friends, create toasts, discuss and share them with other participants. In the classic MVC architecture, this is done by writing appropriate models, controllers, and views. But let's try to do without coding.
Take the free open source Evado Declarative Framework, which describes domain entities and relationships between them through a web interface. The minimum environment required to work is Node.js and MongoDB servers. The IDE is Visual Studio Code. However, the latter is not necessary if we do not plan to write a code.
Copy app boilerplate
from github repository to the local
/party folder (hereinafter, all file paths will be relative to
it) and install dependencies.
Configuration files are located in
When application starting, the choice of file depends on the value of the global variable
Each of configurations inherits data from
Change application and database name (by default connects to
localhost:27017 without password).
That's it, the configuration is complete. Next, run installation script:
Then launch the application (you can also launch it from Visual Studio - Start app configuration):
In development mode, the application is available at
You can log in as Adam with administrator rights, which was created during installation by default settings.
Quick overview of the Framework
Declarative Framework Evado consists of several basic modules and components,
which are determined by configuration settings.
All modules have a unified web interface.
Studio module creates and edits metadata,
which describe entities (domain models) and relationships between them.
Actual data is stored as JSON files in the
Office module operates the application by creating and editing objects based on metadata.
Administration module manages system users, security and other application parameters.
Take care of the guests of the party first. Go to the Studio module and create a Member class. Each member must be directly associated with a system user. To do this, add a required and unique User attribute.
Create a Toast class so party members can generate content. Add a string attribute Title and a text attribute Content. To bind a toast to a member, add an Author reference attribute. A reference type specifies that its value is a reference to another object. In this case, to an object of the Member class.
Toast is not always meant for the general public. Sometimes it is still a draft, and the author only decides how to present his thought brighter. And sometimes only a few can understand the full depth of the toast and everyone does not need to see it. To do this, add the string attribute Access. Go to the Enumerations tab and create an enumeration with access value items:
- Only for friends
- For everyone
Wise, ridiculous, provocative or funny opinions always evoke emotions in response. The party should be able to discuss toast. Create a Comment class with the required text attribute Text and reference attributes Toast and Author. They will keep links to the toast to which the comment relates and the member who created the comment. For the author, specify the default value as the member associated with the current system user.
Create a Creation Date attribute with the codename
_createdAt and the Local Date and Time view type.
Local date means the time zone will be applied.
To make two people friends, you need to get the consent of both.
At our party, we will adhere to this equality.
One person creates a friendship, the other can accept or reject it.
Create a Friend class that will define friendship.
Add required reference attributes Inviter and Invitee.
To define the state of friendship, add the
_state string attribute with the State view type.
Go to the States tab and create three states:
- Pending decision (default)
- Friendship accepted
- Friendship rejected
Go to the Transitions tab and create a couple of transitions:
- Start states Pending Decision and Friendship Rejected
- Final state Friendship Accepted
- Start states Pending Decision and Friendship Accepted
- Final state Friendship Rejected
After making a decision, the invitee can change the state of friendship. On the other hand, the inviter, as the creator of the object, can delete it at any time.
How can a user find all his comments, if the link of the comment to the user is stored in the Comment class? There is a backref for this. It defines a relationship through an attribute in the referenced class.
To display all comments on the toast, add the Comments backref to the Comment class and the Toast attribute. To display all of the member's toasts, add the Toasts backref to the Toast class and the Author attribute.
To display accepted friend members... And here the foreboding strikes the first blow that declarations alone will not be enough. Indeed, in order to find such participants, the following is necessary:
- first, find friends who are in the Friendship Accepted state and the current member is either an inviter or an invitee;
- second, find participants (except for the current one) who are associated with found friends.
The Studio web interface only creates a relationship by one attribute and adds a selection condition.
For a complex relationship, you will have to write your own implementation and connect it to the Filter field
Export the created metadata to get it in the app.
The export (import) button is located on the top panel of the Studio module.
You can choose any target folder, but note that the application will only be loaded from
After successful export everything is ready for operation in the Office module.
For self-registration of users in the configuration file
params section set
After completing the registration of a new user, you need to create an object of the Member class.
To do this, create a registration event listener in the Administration module.
And add a handler to it.
Basic feature of any multi-user application is the differentiation of access rights. The Evado Framework implements a role-based access control system (RBAC).
A user can be assigned one or more roles. Each role contains permissions that describe what can be done. For example, create an object or access a module. A permission can be locked by a rule that determines whether this permission will be applied. For example, if for permission to edit an object, impose a rule that checks whether the current user is the creator of the object, then only the author will receive the edit right.
In the Administration module go to the Security - Roles section. Initially, the application template defines three roles:
- administrator (full access to data)
- user (role for authenticated users)
- guest (role for anonymous users)
That's enough for our party. After logging in, the User role will be assigned by default. There is no need to set it explicitly.
Let's define the required permissions for a member:
- create, edit and delete his own toasts
- read toasts with allowed access
- edit and delete his own comments
- read and create comments on toasts with allowed access
- view members and friends
- create and delete his own friends
- edit friendship if the member is an invitee
And here again one cannot do with only declarative actions. For example, to define a rule for reading allowed toasts, you must define that the toast has "Everyone" or "Friends" access and that the current user is a accepted friend of the toast author. To do this, you need to write your own implementation of the rule.
Register as a new user, go to the Office module and taste all the planned functionality. The party took place, but it was not done without writing code. Even such a relatively simple application has problems that cannot be solved using a universal web interface. If the entity description structure becomes more complex to include more features, then it will yield to imperative code in simplicity and optimality.
The finished application can be run in docker.
Log in as Bob: