This template repository is intended to be a base of project development for micro-services or APIs based on CRUD and simple APIs.
Caution:
This code skeleton is currently in a
release-candidate
version, meaning that it is not guaranteed to be 100% stable. However it is guaranteed to pass compilation.
- Based on Rocket latest version.
- Lightning fast API and console commands.
- Can run as an API as well as CLI commands.
- Automated CRUD code generation.
- Easy to use fine-tuned security.
- simple MVC-oriented design, with controllers, middleware, etc.
And a lot of features you know and love from non crab friendly languages and frameworks !
- prerequisites
- getting started
- first steps
- the skeleton
- generating a CRUD
- creating a command
- deployment
- future versions & roadmap
- changelog
- license
To run this app skeleton, you need to:
- have rust installed & setup. You can refer to this page to setup your rust environment.
- install PostgreSQL database driver in your system. As this application use source linking and PostgreSQL as a database, you must have PostgreSQL drivers installed on your system. You can use this page to help you with this step.
- install the diesel CLI. This application uses Diesel as it's ORM, so you must use the diesel CLI to handle database migration. You can learn how to install diesel CLI on this page.
For this chapter and onwards, the documentation will assume you have a
linux
or'nix
system, and thus give command for those systems.A dockerized version of this skeleton is planned to arrive in the
1.0.0-rc2
version, and will ease development and deployment phases.
First, clone this repository :
git clone [email protected]:owlnext-fr/rust-microservice-skeleton.git
cd rust-microservice-skeleton
Then launch the dev database :
docker-compose up --build -d
This will instanciate a PostgreSQL database for development purposes only. Do not use this container in production environment.
Note:
The future dockerization of this project will make the development database obsolete.
And now launch your IDE in the project directory :
code .
This skeleton is inteded to use with two modes :
launch
that will launch the API server.console
that will execute a given command.
This is made to allow ease of development using the same codebase for API development and console command (e.g. async runners, crons, etc.).
Before using this code skeleton, let's create a .env.local
file to store all your application configuration.
ROCKET_LOG_LEVEL=debug
DATABASE_URL=postgres://postgres:changeme@localhost/api
RUST_BACKTRACE=1
APP_DATABASE_URL="postgres://postgres:changeme@localhost/api"
APP_JWT_TTL=3600
APP_JWT_REFRESH_TTL=86400
APP_UPLOAD_DIR="rust-microservice-skeleton/upload"
APP_PACKAGE_NAME="rust-microservice-skeleton"
APP_PACKAGE_VERSION="1.0.0"
Now that your app is ready, let's create you your first user.
First, run the command to create an API user :
cargo run -- console app:create-account ""
This command will guide you through the creation of your first Account
, Application
and User
.
These are organization unit to split users and applications data. Let's say for now that an Account
can have multiple Application
, and an Application
can have multiple users.
All data from an Account
is separated for another, same for the Application
.
Note:
You can make your user an
administrator
by using theapp:promote-user
console command.
So, now that you have a user to play with your API, let's fire up this server shall we ?!
cargo run -- launch
You should see that your API is up and running. Under the hood it has populated the database, generated certificates for JWT authentication and some other configuration things.
Now let's authenticate as our new user:
curl --request POST \
--url http://localhost:8000/api/auth/token \
--header 'Content-Type: application/json' \
--data '{
"login": "<your login>",
"password": "<your password>"
}
'
Yay ! you should have a JWT token. Now use it to do your first request on the API:
curl --request GET \
--url 'http://localhost:8000/api/users?page=1&per_page=25' \
--header 'Authorization: Bearer <access_token>'
Now lets examine all the directory of this application skeleton:
command
is to store all your commands invokable by theconsole
mode.controllers
is to create all your application controllers.core
have all the core modules to let you create applications with this skeleton. Modify it at your own risks !.domain/dto
contains all input and output models (e.g. DTO) for your API.domain/model
contains all your model representation.domain/repository
contains all your data model repository (e.g. database request layers)exceptions
stores all the custom logic exception of your application.fixtures
stores all your data fixtures.libraires
will contain all your external integrations, such as libraries, connectors, external APIs, etc.middlewares
contains all your model and transitive middlewares.migrations
contains all database migrations handled bydiesel
.security
contains all your security policies to access your API.main.rs
is the main entrypoint of this skeleton. Modify it at your own risks !
Generating a crud is a two part operation:
- We need to generate all the code required to CRUD operations and middlewares.
- We need to create the database migration.
To create all the code, simply run:
cargo run -- make:generate-scaffold ""
It will :
- Generate the model structures: model, DTOs and data repository.
- Generate the middleware.
- Generate the security policy (e.g. security voter).
- Generate the controllers.
- Update the rocket builder in the
core
to register all your new code.
Now that you have all the code, let's generate the migration:
source .env && diesel migration generate
This will generate a new database migration that you can complete.
Once completed, you can activate the migration by running:
source .env && diesel migration run
Note:
Due to a current bug on diesel, you will have to perform manual replace in the whole
src/domain/schema.rs
file:
created_by -> Int4,
->created_by -> Nullable<Int4>,
deleted_by -> Int4,
->deleted_by -> Nullable<Int4>,
roles -> Array<Nullable<Text>>,
->roles -> Array<Text>,
This bug will be patched in the version
1.0.0-rc2
.
Now, you should have all your database and model connected, you only need to fill your model, DTO and middleware and you are good to go with your CRUD !
As stated previously, this skeleton offers the possibility to create console commands like the ones you used to setup your user.
To create one, simply create file in the command/<domain>
folder, add it to the desired mod.rs
, and create a struct implementing ConsoleCommand
. Your struct should at least have a field for the CronLogMiddleware
.
Then fill the required functions, and write the body of your command in the do_run
function.
Now go to the src/core/rocket_factory.rs
and locate the ConsoleCommandRegistry
instantiation, under the command registry initialization
, and add your command as all other are added.
Now run your command with:
cargo run -- console <command name> "<command args>"
Note:
Even if your command does not handle any arguments, the
""
are required after the command name.This bug will be addressed in a future version.
Note:
A command generator, similar as the CRUD generator, will be implemented in the version
1.0.0-rc2
.
This is a release-candidate
version and thus should not be used in production at this time.
Furthermore, a dockerized and deployable version will be available starting version 1.0.0-rc2
.
-
Version 1.0.0-rc2
- [FEATURE] Dockerized version.
- [FEATURE] A makefile to automate all recurrent tasks.
- [FEATURE] Automated console command generation.
- [PATCH] The replacement bug in the
schema.rs
. - [FEATURE] add a .env example.
- [PATCH] remove the .vscode folder.
- [FEATURE] Error dispatch with external tooling like Pushover/Sentry.
- [FEATURE] Adding CORS support.
-
Future versions
- [PATCH] Remove the
""
required by clap for the console command launch. - [FEATURE] Automated API documentation.
- [PATCH] Remove the
You can find the changelog in the CHANGELOG.md file.
This code is under BSD 3-Clause license