Incorporate modules in the dapp
Let's put this into practice by moving code into smaller modules. Start by creating a folder named news_feed
and adding a module.rell
file inside it:
module;
Now, import everything from this module into your main.rell
file by adding:
import news_feed;
Next, create a file named src/news_feed/model.rell
and move the entity definitions into this file.
entity user {
mutable name;
key id: byte_array;
key account;
}
entity follower {
index user;
index follower: user;
key user, follower;
}
entity post {
timestamp = op_context.last_block_time;
index user;
content: text;
}
Also, move the import statement for the account
entity from the ft-library
to the module.rell
file. Adding it to the module.rell
file makes sense as all files in the module can access it.
module;
import lib.ft4.accounts.{ account };
import lib.ft4.auth;
Similarly, move the auth_handler
to src/news_feed/auth.rell
and post_dto
to src/news_feed/dto.rell
. You can consider the require_user
and format_user
utility functions to add them directly to module.rell
if you prefer. The queries are moved to src/news_feed/queries.rell
, and the operations are moved to src/news_feed/operations.rell
.
Your module.rell
file in the news_feed
module should now look like this:
module;
import lib.ft4.accounts.{ account };
import lib.ft4.auth;
function require_user(id: byte_array) = require(user @? { id }, "User with id %s does not exist".format(id));
function format_user(user) = "%s#%s".format(user.name, user.id.to_hex().sub(0, 5));
With proper imports, the main.rell
file should now contain only the create_user
operation, which is useful for testing purposes.
Now, create a new module called test_operations
in the test
folder by creating a file there and declaring it as a module:
module;
import lib.ft4.core.accounts.{ create_account_with_auth, single_sig_auth_descriptor };
import news_feed.*;
operation create_user(name, pubkey) {
val account = create_account_with_auth(single_sig_auth_descriptor(pubkey, set(["A", "T", "MySession"])));
create user ( name, pubkey, account );
}
In your test file, you'll need to import this module explicitly, possibly using relative imports:
import ^.test_operations.{ create_user };
The create_user
operation is no longer accessible from main.rell
, but it can still be helpful for testing against a test node. To support this, create a new module named development
alongside main.rell
, including the test operation:
module;
import main;
import test.test_operations.*;
In your chromia.yml
file, you can toggle between using the main
module and the development
module as the entry point for your dapp by altering the module:
tag in the blockchains
definition:
blockchains:
my-news-feed:
module: development # set to "main" for production
You have now learned to use Rell modules to structure your project effectively. Your file structure should resemble the following:
├── development.rell
├── main.rell
├── news_feed
│ ├── auth.rell
│ ├── dto.rell
│ ├── model.rell
│ ├── module.rell
│ ├── operations.rell
│ └── queries.rell
└── test
├── news_feed_test.rell
└── test_operations.rell
In the next module, we will discuss a proper replacement for the create_user
operation and how to integrate it with a front-end client.