DEV Community

nabbisen
nabbisen

Posted on • Edited on • Originally published at scqr.net

Loco 0.14 on Cathyos: Getting started

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 
Enter fullscreen mode Exit fullscreen mode

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`) 
Enter fullscreen mode Exit fullscreen mode

Then :)

$ loco --version loco 0.14.0 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

Prepare ORM (Optional)

Install the crate below in addition when database is required:

$ cargo install sea-orm-cli 
Enter fullscreen mode Exit fullscreen mode

I installed it.

Create a project

OK. Run to start:

$ loco new 
Enter fullscreen mode Exit fullscreen mode

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) 
Enter fullscreen mode Exit fullscreen mode

The result was:

🚂 Loco app generated successfully in: /(...)/loco-example 
Enter fullscreen mode Exit fullscreen mode

Understand the project structure

Yay, the project was created. Let's come in:

$ cd loco-example/ 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

Start the server

$ cargo loco start 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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)) } 
Enter fullscreen mode Exit fullscreen mode

Access via browser (Optional)

http://localhost:5150 looks like:

access via browser

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 
Enter fullscreen mode Exit fullscreen mode

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"}' 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 ); 
Enter fullscreen mode Exit fullscreen mode

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 !!!

Reference

Top comments (1)