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 CLI 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/(...)/.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 (1)