Skip to content

Rust Backend

BanjoFox edited this page Nov 30, 2017 · 1 revision

Attribution

This is the README.md from Paul's Pull Request #17 which was so well written I figured it deserved its own Wiki page. It does an excellent job of walking through the back-end items that it is hard to improve upon. -- Banjo

Introduction

The rust app here uses primarily Rocket.rs and Diesel, along with a number of smaller crates to fill in any gaps. There are two primary entry points into the code, src/bin/main.rs and src/fedibook/lib.rs. This is a pretty standard setup for rust projects, in which the bulk of the code is in a library-style crate (src/fedibook/) and the main runnable binary is a smaller crate that sets up a few things and then calls into the library crate. Keeping this separation is useful for adding other binaries down the line, and it doesn't really cost us anything now.

src/bin/main.rs

This is the file that, when compiled, implements the actual runnable binary. It will be where we set up all the necessary data structures that the webapp needs to run, gathers config from the user (right now it's just using the standard Rocket.toml file that rocket.rs expects), and sets up the various routes that are actually defined in the library crate.

Currently we are mounting routes under 2 prefixes: "/" and "/api/v1", though there is nothing actually implemented under "/api/v1", other than a placeholder example route. All the URLs mounted under "/" are routes that you would expect a user to request in their browser. The routes that are currently written implement a barebones user login/registration system, though there are still many things to do to improve that system.

Routes under the "/api/v1" prefix are routes that should not be directly browsed to, but will use OAuth for authentication, accept and return JSON, and would primarily be used via XMLHttpRequests from the browser webapp (or via cURL during development).

src/fedibook/

This is where the real meat of the application is. The main entry point for the library crate is src/fedibook/lib.rs, that has all the mod statements and such. There are a few directories from here that should be pretty self-explanatory. controllers, forms, models, and routes. The routes module contain the definitions for the actual endpoints, though I've tried to keep those small and move the bulk of the logic into the controllers.

There is a special file, src/fedibook/schema.rs, that holds the generated database schema. This is generated by:

  1. Installing diesel_cli: $ cargo install diesel_cli --no-default-features --features "postgres"
  2. Running diesel print-schema --with-docs -s fedibook > src/fedibook/schema.rs

The version of diesel that was used to develop this has a small bug in which the joinable!() invocation at the bottom of the schema.rs file had to be slightly changed, but the next version of diesel does not have that bug and I am working on upgrading fedibook to that version.

Migrations

In the migrations/ directory, you will find all the database migrations that diesel will need to properly set up your database.

Templates

In the templates/ directory, you will find the templates that rocket uses to serve the login, logout, register, and home pages (barely more than placeholders right now)

In the browser

To go with the user registration/login system, I have a handful of (very) barebones templates that can be used to register, login, and logout in a browser. Assuming that rust, postgres, and diesel are already installed, the workflow goes like this:

  • start postgres. make sure you can successfully connect to it
  • cd into the fedibook directory and set up the database (this is only necessary the first time):
    • make sure diesel can connect to your database: export DATABASE_URL="postgres://user:pass@host/dbname"
    • diesel setup should create the database
    • diesel migration run should run all the migrations
  • start the app: cargo run (or cargo run --bin fedibook-server if you want to be explicit)
  • When you see "Rocket has launched from http://...." you should be able to connect to the running app
  • Assuming you run the app on localhost and use the 7878 port, you can browse to http://localhost:7878/auth/sign_up and register a user account
  • If the registration succeeds, it will redirect you to http://localhost:7878/auth/sign_in. You won't actually be able to sign in yet, you have to confirm your account.
  • Go back to the command line, you should see a message that has a path at the end with the token to confirm your account.
  • Go to http://localhost:7878<the path from the console> in your browser
  • If the confirmation succeeded, it should redirect you back to the /auth/sign_in page, where you should be able to log in now.
  • If the log in succeeds, it should redirect you to /web and show you a message, and a "logout" button

Going to /web without logging in should redirect you to the login page