How to Install and Use Loco: A Flexible Full-Stack Framework for Rust π
Saturday, Jan 11, 2025 | 8 minute read
Discover a high-performance, secure full-stack framework built on Rust! π It offers convention over configuration, rapid development mode, powerful ORM, dynamic view generation, and efficient task management, making it ideal for modern developers! πβ¨
“In this fast-evolving world of development, choosing a highly efficient and secure full-stack framework is of utmost importance.”
The significance of full-stack frameworks in modern application development is undeniable! They not only enhance development efficiency but also greatly improve user experience. In recent years, the Rust language has sparked enthusiasm among developers with its exceptional performance and memory safety, and amidst this trend, Loco has emerged. π As a comprehensive development framework based on Rust, Loco aims to provide the convenience and speed akin to Ruby on Rails while fully leveraging all of Rust’s strengths.
1. Loco: A Revolutionary New Experience in Full-Stack Development π
Loco is a full-stack web framework built with the Rust language, and its design goal is to replicate the development experience of Ruby on Rails! β¨ It significantly boosts development efficiency and ensures program security, which has attracted many seasoned Rails developers. Moreover, it offers a fantastic opportunity for Rust newcomers to get involved in development!
2. The Unique Appeal of Loco: Key Features That Stand Out π
- Convention over Configuration π: Loco reduces cumbersome template code with intelligent defaults, allowing developers to focus more on implementing business logic.
- Rapid Development Mode β‘: The framework’s intuitive API simplifies prototype building and significantly shortens development cycles!
- Powerful ORM Integration ποΈ: Developers can easily use entity modeling for business logic, making it simple to handle relationships and validate associated data.
- Efficient Controllers π¦: Designed around Axum, which enhances web request management and supports functionalities like authentication and logging through middleware.
- Dynamic View Generation π¨: Integration with various template engines allows Loco to effortlessly create dynamic HTML content, greatly enhancing user experience.
- Background Task Management β³: Supports using Redis queues or threads for handling compute-intensive and I/O-intensive tasks, increasing task processing efficiency!
- Simple Scheduling Functionality β°: The built-in scheduling feature makes managing cron jobs incredibly simple and efficient, saving time and effort!
- Email Sending π§: Loco’s infrastructure makes it easy, fast, and reliable for developers to implement background email sending.
- Convenient Storage Operations πΎ: Supports multiple storage solutions like AWS S3, GCP, Azure, streamlining file handling processes.
- Performance-Optimized Cache Layer ποΈ: Loco implements a caching mechanism that significantly improves application performance, ensuring a smooth user experience!
3. User’s First Choice: Why Choose Loco? π
Loco is favored by developers for its efficient development process, especially evident in its structural consistency and the ease of prototype building! πͺ It seamlessly combines Rust’s safety and performance advantages with a range of clever features, making it the go-to choice for modern developers when building projects. In today’s rapidly changing tech environment, Loco provides developers with a stable yet flexible platform, effectively tackling complex development demands. β¨ Amidst the rapidly evolving industry standards, Loco indeed offers a minimalistic, fast, and efficient development experience, helping to enhance development efficiency, optimize code structure, and bolster security.
4. How to Install and Use Loco π
Ready to embark on your Loco journey? The first step is to install Rust and Cargo (Rust’s package management tool). These two companions are the foundation for running Loco, so be sure they are both installed! You can easily install Loco and Sea ORM CLI (if you need database support) using the following commands.
cargo install loco
cargo install sea-orm-cli # Only when a database is needed
- The command
cargo install loco
will install the Loco framework in your environment. - The command
cargo install sea-orm-cli
is optional and installs the Sea ORM CLI, which is essential if you plan to use a database!
Once installed, you can start creating a brand new SaaS application! Hereβs an example command for this step:
β― loco new
β β― App name? Β· myapp # Prompt for the app name, input myapp here
β β― What would you like to build? Β· SaaS App with client-side rendering # Choose the build type
β β― Select a DB Provider Β· Sqlite # Choose the database provider, here we select Sqlite
β β― Select your background worker type Β· Async (in-process tokio async tasks) # Choose background worker type
- The
loco new
command initiates the new application creation process. In the upcoming steps, you will be asked for some basic information:- Input your application name, for example,
myapp
. - Choose the build type, for instance, we selected βSaaS App with client-side rendering.β
- Select the database provider; we opted for Sqlite.
- Choose the background worker type, selecting Async for using asynchronous tasks.
- Input your application name, for example,
Upon successfully creating the application, the console will display the generated file structure. Next, you need to enter the frontend directory and build the project:
$ cd frontend/ # Navigate to the frontend directory
$ npm install && npm run build # Install dependencies and build the project
- After entering the frontend directory, use
npm install
to install the necessary dependencies, and then runnpm run build
to build the project files!
Next, you must enter the newly created myapp
directory and start the application:
$ cd myapp # Navigate to the application directory
$ cargo loco start # Start the Loco application
- The command
cargo loco start
will launch your newly created Loco application. Once the application starts successfully, the console will display the port it’s listening on, for example:
listening on port 5150
- Now, open your browser and go to
localhost:5150
to see your creation! π
Detailed Commentary on the Code π
Next, let’s dive into some of Loco’s core functionalities to understand how they work and their purposes!
Models π
In the model section, we define how to query users by email. Take a look at the following example:
impl Model {
pub async fn find_by_email(db: &DatabaseConnection, email: &str)
-> ModelResult<Self> {
Users::find() // Query users via the Users table
.filter(eq(Column::Email, email)) // Filter by email
.one(db).await? // Execute the query asynchronously
.ok_or_else(|| ModelError::EntityNotFound) // Return an error if no user is found
}
}
- Firstly, the
find_by_email
function is an asynchronous method that takes a database connection and an email parameter. Users::find()
searches for users through theUsers
table..filter(eq(Column::Email, email))
filters users based on email..one(db).await?
executes the query and retrieves a user asynchronously.- Finally, by using
ok_or_else(|| ModelError::EntityNotFound)
, if no user is found, an error is returned.
Controllers ποΈ
Controllers are responsible for handling requests and returning corresponding responses. Let’s take a look at the following example showing how to fetch a single note:
pub async fn get_one(
respond_to: RespondTo, // Response type
Path(id): Path<i32>, // Extract id from the request path
State(ctx): State<AppContext>, // Get the application context
) -> Result<Response> {
let item = Notes::find_by_id(id).one(&ctx.db).await?; // Fetch the note
match respond_to {
RespondTo::Html => html_view(&item), // Return HTML view if HTML format is requested
_ => format::json(item), // Otherwise return in JSON format
}
}
- The
get_one
method asynchronously searches for a specific item. respond_to
parameter specifies the request’s response type.Path(id): Path<i32>
extracts theid
from the request path.State(ctx): State<AppContext>
extracts the application context.- Depending on the response type, the appropriate format (HTML or JSON) is returned.
Views π
Views are used to render response data. Check out these examples:
// Literal
format::text("Loco") // Return text "Loco"
// Tera view engine rendering
format::render().view(v, "home/hello.html", json!({})) // Render the specified view
// Strongly typed JSON response, supported by `serde`
format::json(Health { ok: true }) // Return JSON health check information
// Features like Etag, cookies, etc.
format::render().etag("loco-etag")?.empty() // Return an empty response with Etag
- The code snippets above demonstrate how to use the
format
module to build different types of responses, adding flexibility to the application!
Background Jobs π οΈ
Here is a code example that shows how to handle scheduled tasks:
impl worker::Worker<DownloadArgs> for UsersReportWorker {
async fn perform(&self, args: DownloadArgs) -> worker::Result<()> {
let all = Users::find() // Find all users
.all(&self.ctx.db) // Retrieve the user list from the database
.await
.map_err(Box::from)?; // Asynchronously fetch and handle errors
for user in &all {
println!("user: {}", user.id); // Output each user's ID
}
Ok(())
}
}
- Here, the
perform
function serves as the core method for the background worker, asynchronously processing user reports. Users::find()
is used to find all users and outputs the ID of each user!
Deployment π
When deploying your application, you can opt for different deployment options, like Docker:
$ cargo loco generate deployment
? β― Choose your deployment βΊ
β― Docker
β― Shuttle
β― Nginx
- Use the command
cargo loco generate deployment
to create the necessary deployment configurations, after which you can choose Docker, Shuttle, or Nginx as your deployment platform!
Scheduled Tasks β°
An example of YAML configuration for scheduled tasks is shown below:
jobs:
db_vaccum:
run: "db_vaccum.sh" # Execute the database cleaning script
shell: true
schedule: "0 0 * * *" # Schedule the log cleaning task at midnight every day
tags: ["maintenance"]
send_birthday:
run: "user_birthday_task" # Execute the user birthday task
schedule: "Run every 2 hours" # Run every two hours
- In this configuration, we’ve configured two tasks:
db_vaccum
runs a database cleaning script at midnight every day.send_birthday
runs a birthday report task every two hours!
Modules Description π¦
Loco provides several modules to help developers better organize their code:
- app: The core component for handling web server applications.
- db: The database operation module.
- cache: A module for handling cache.
- controller: Manages routing for the web server.
- logger: Initializes the application logging.
- mailer: Handles email-related features.
- model: The module for handling model errors.
Structs π
Structure TestServer
in the application defines a test for running the Axum app.
Type Aliases π
To ensure code readability and simplicity, we define a list of application result options:
pub use self::errors::Error; // Export the error type
pub use validator; // Export the validator
With these steps and code examples, you’ll find it easy to get started and practically implement Loco’s open-source project! For further learning, feel free to check out the official documentation at loco.rs.βοΈ