Since the initial PR for this is rather large, I'm including a write-up here to hopefully aid in the code review process.
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.
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).
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:
- Installing
diesel_cli
:$ cargo install diesel_cli --no-default-features --features "postgres"
- 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.
In the migrations/
directory, you will find all the database
migrations that diesel
will need to properly set up your database.
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)
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 databasediesel migration run
should run all the migrations
- make sure diesel can connect to your database:
- start the app:
cargo run
(orcargo 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 the7878
port, you can browse tohttp://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