Summary
Loco is a relatively new Rust web framework which first appeared around 2021. It is strongly inspired by Ruby on Rails, and designed to bring developers productivity as various functionality on routing, middlewares, and request handling. They aim to provide modern and intuitive development experience.
This post shows how to start Web API development to manage users in several minutes thanks to their great app template.
Environment
- OS: Cathyos (based on Arch Linux)
- Programming Language: Rust 1.84.0
- App: Loco 0.14.0
Tutorial
loco installation
Get loco
executable first.
$ cargo install loco
The result was:
Updating crates.io index
Downloaded loco v0.14.0
Downloaded 1 crate (367.8 KB) in 0.16s
Installing loco v0.14.0
(...)
Compiling loco v0.14.0
Finished `release` profile [optimized] target(s) in 16.72s
Installing /home/nabbisen/.cargo/bin/loco
Installed package `loco v0.14.0` (executable `loco`)
Then :)
$ loco --version
loco 0.14.0
Activate executables which cargo
installs
When $PATH
doesn't include ~/.cargo/bin
, loco
must be missing. In such case, it is necessary to append the line below to ~/.fish_profile
to:
set -U fish_user_paths $HOME/.cargo/bin $fish_user_paths
Prepare ORM (Optional)
Install the crate below in addition when database is required:
$ cargo install sea-orm-cli
I installed it.
Create a project
OK. Run to start:
$ loco new
You will be asked what kind of app you want to create. My reponses were:
✔ ❯ App name? · loco-example
? ❯ What would you like to build? ›
Saas App with server side rendering
Saas App with client side rendering
❯ Rest API (with DB and user auth)
lightweight-service (minimal, only controllers and views)
Advanced
✔ ❯ Select a DB Provider · Sqlite
✔ ❯ Select your background worker type · Async (in-process tokio async tasks)
The result was:
🚂 Loco app generated successfully in:
/(...)/loco-example
Understand the project structure
Yay, the project was created. Let's come in:
$ cd loco-example/
And see what there are:
$ ls
drwxr-xr-x - (user) 10 1月 12:46 .cargo
drwxr-xr-x - (user) 10 1月 12:46 .github
drwxr-xr-x - (user) 10 1月 12:46 config
drwxr-xr-x - (user) 10 1月 12:46 examples
drwxr-xr-x - (user) 10 1月 12:46 migration
drwxr-xr-x - (user) 10 1月 12:46 src
drwxr-xr-x - (user) 10 1月 12:46 tests
.rw-r--r-- 339 (user) 10 1月 12:46 .gitignore
.rw-r--r-- 49 (user) 10 1月 12:46 .rustfmt.toml
.rw-r--r-- 1.3k (user) 10 1月 12:46 Cargo.toml
.rw-r--r-- 2.4k (user) 10 1月 12:46 README.md
Start the server
$ cargo loco start
The result was:
Compiling loco-example v0.1.0 (/(...)/loco-example)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 41.10s
Running `target/debug/loco_example-cli start`
2025-01-10T03:51:27.386666Z WARN app: loco_rs::boot: pretty backtraces are enabled (this is great for development but has a runtime cost for production. disable with `logger.pretty_backtrace` in your config yaml) environment=development
2025-01-10T03:51:27.394779Z INFO app: loco_rs::db: auto migrating environment=development
2025-01-10T03:51:27.398632Z INFO app: sea_orm_migration::migrator: Applying all pending migrations environment=development
2025-01-10T03:51:27.399422Z INFO app: sea_orm_migration::migrator: Applying migration 'm20220101_000001_users' environment=development
2025-01-10T03:51:27.399875Z INFO app: sea_orm_migration::migrator: Migration 'm20220101_000001_users' has been applied environment=development
2025-01-10T03:51:27.400196Z INFO app: loco_rs::boot: initializers loaded initializers="" environment=development
2025-01-10T03:51:27.412320Z INFO app: loco_rs::controller::app_routes: [GET] /_ping environment=development
2025-01-10T03:51:27.412500Z INFO app: loco_rs::controller::app_routes: [GET] /_health environment=development
2025-01-10T03:51:27.412558Z INFO app: loco_rs::controller::app_routes: [POST] /api/auth/register environment=development
2025-01-10T03:51:27.412591Z INFO app: loco_rs::controller::app_routes: [GET] /api/auth/verify/{token} environment=development
2025-01-10T03:51:27.412648Z INFO app: loco_rs::controller::app_routes: [POST] /api/auth/login environment=development
2025-01-10T03:51:27.412693Z INFO app: loco_rs::controller::app_routes: [POST] /api/auth/forgot environment=development
2025-01-10T03:51:27.412724Z INFO app: loco_rs::controller::app_routes: [POST] /api/auth/reset environment=development
2025-01-10T03:51:27.412758Z INFO app: loco_rs::controller::app_routes: [GET] /api/auth/current environment=development
2025-01-10T03:51:27.412796Z INFO app: loco_rs::controller::app_routes: [POST] /api/auth/magic-link environment=development
2025-01-10T03:51:27.412827Z INFO app: loco_rs::controller::app_routes: [GET] /api/auth/magic-link/{token} environment=development
2025-01-10T03:51:27.412957Z INFO app: loco_rs::controller::app_routes: +middleware name="limit_payload" environment=development
2025-01-10T03:51:27.413002Z INFO app: loco_rs::controller::app_routes: +middleware name="catch_panic" environment=development
2025-01-10T03:51:27.413040Z INFO app: loco_rs::controller::app_routes: +middleware name="etag" environment=development
2025-01-10T03:51:27.413106Z INFO app: loco_rs::controller::app_routes: +middleware name="logger" environment=development
2025-01-10T03:51:27.413144Z INFO app: loco_rs::controller::app_routes: +middleware name="request_id" environment=development
2025-01-10T03:51:27.413184Z INFO app: loco_rs::controller::app_routes: +middleware name="fallback" environment=development
2025-01-10T03:51:27.413239Z INFO app: loco_rs::controller::app_routes: +middleware name="powered_by" environment=development
▄ ▀
▀ ▄
▄ ▀ ▄ ▄ ▄▀
▄ ▀▄▄
▄ ▀ ▀ ▀▄▀█▄
▀█▄
▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄ ▀▀█
██████ █████ ███ █████ ███ █████ ███ ▀█
██████ █████ ███ █████ ▀▀▀ █████ ███ ▄█▄
██████ █████ ███ █████ █████ ███ ████▄
██████ █████ ███ █████ ▄▄▄ █████ ███ █████
██████ █████ ███ ████ ███ █████ ███ ████▀
▀▀▀██▄ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ██▀
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
https://loco.rs
environment: development
database: automigrate
logger: debug
compilation: debug
modes: server
listening on http://localhost:5150
The server started !!
Besides, the routing is defined in src/controllers/auth.rs
:
pub fn routes() -> Routes {
Routes::new()
.prefix("/api/auth")
.add("/register", post(register))
.add("/verify/{token}", get(verify))
.add("/login", post(login))
.add("/forgot", post(forgot))
.add("/reset", post(reset))
.add("/current", get(current))
.add("/magic-link", post(magic_link))
.add("/magic-link/{token}", get(magic_link_verify))
}
Access via browser (Optional)
http://localhost:5150 looks like:
Register users via curl
If there is no local email service, edit config/development.yaml
to disable smtp beforehand:
mailer:
# SMTP mailer configuration.
smtp:
# Enable/Disable smtp mailer.
- enable: true
+ enable: false
and restart the server.
Access via curl
to register a user:
$ curl -X POST http://localhost:5150/api/auth/register -H "content-type: application/json" --data '{"email":"test@test.test", "password":"testpassword", "name":"testname"}'
You will see SQLite database file is created in the root directory named loco-example_development.sqlite
.
Open the database:
$ sqlite3 loco-example_development.sqlite
Check it:
sqlite> .tables
seaql_migrations users
sqlite> select * from users;
2025-01-10 04:08:06|2025-01-10 04:08:06|(...)|test@test.test|$argon2id$v=19$m=19456,t=2,p=(...)|(...)|testname|||(...)|2025-01-10T13:08:06.638250752+09:00|||
sqlite> .schema users
CREATE TABLE IF NOT EXISTS "users" ( "created_at" timestamp_with_timezone_text NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" timestamp_with_timezone_text NOT NULL DEFAULT CURRENT_TIMESTAMP, "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "pid" uuid_text NOT NULL, "email" varchar NOT NULL UNIQUE, "password" varchar NOT NULL, "api_key" varchar NOT NULL UNIQUE, "name" varchar NOT NULL, "reset_token" varchar NULL, "reset_sent_at" timestamp_with_timezone_text NULL, "email_verification_token" varchar NULL, "email_verification_sent_at" timestamp_with_timezone_text NULL, "email_verified_at" timestamp_with_timezone_text NULL, "magic_link_token" varchar NULL, "magic_link_expiration" timestamp_with_timezone_text NULL );
Conclusion
We saw how to install Loco via cargo
and create Web API to register users. There are other API provided such as to login or reset an account.
Hope it helps in some way you to get familiar with the wonderful framework !!!
Top comments (0)