A REST API boilerplate written in Rust, heavily inspired by Django.
Table of contents
Problem | Solution | Result |
---|---|---|
Database | Postgres | It's Postgres :) |
Rust SQL Toolkit | SQLx | Query the database with compile timed SQL (no ORM!) |
Webframework | Actix Web | Very fast web server |
OpenAPI Generation | Paperclip | Automatically generated specification of your API, which can be used to generate your API client. |
- Testing - Unit
- Testing - Integration
- How to implement custom users with
core::auth
- Develop locally or inside a docker container.
- Heroku Deployed Docker Container
To quickly get up an running you can use Docker Compose. Although your IDE will typically work better if everything installed locally.
Make sure you have Docker Desktop
This will start the database and run migrations.
docker-compose up migrations
Start your local development server, any changes will reload the code.
docker-compose up app
Now browse localhost:8000
Lets now start the integration tests watcher.
Stop the app (quicker iteration as we dont need to wait on the app)
docker-compose stop app
Same as the app container any code changes will automatically
docker-compose up tests
this will start and reload the integration tests when any code changes. We stop the app container as the two containers will often
Make sure you have rust and cargo and postgres installed.
Create your database.
createdb pexp
And run migrations
sqlx migrate run
Install cargo watch
cargo install cargo-watch
This is equivalent to cargo run
but with autoreload on changes in src
folder.
cargo watch --watch src --exec run
To run tests we can use.
cargo run tests
To run a specific test.
cargo test users::model::test_model_create
This will run the test_model_create
in tests/users
Creating a new migration using docker.
docker-compose exec app sqlx mig add test_migration
or locally
sqlx migrate add test_migration
Running migrations
docker-compose exec app sqlx mig run
If you find yourself quickly iterating on your schema this will reset the database with your new schema.
docker-compose down && \
docker volume rm planet-express_pgdata && \
docker-compose up migrations && \
docker-compose up tests
The following has been automated into the CI pipeline and here for reference.
Using Docker containers here means we can transition from Heroku in the future easily.
Login
heroku container:login
Due to SQLx requiring a database during compile time to check our SQL statements we need to set our network to host and have a database live with our migrations.
docker-compose up -d migrations && docker build --network="host" -t web .
docker tag web registry.heroku.com/planetexpres/web
docker push registry.heroku.com/planetexpres/web
If you haven't added a database yet run
heroku addons:create heroku-postgresql:hobby-dev
Configure our secrets
heroku config:set APP_AUTH__JWT_SECRET=supersecret
heroku config:set APP_AUTH__PASSWORD_SALT=supersecret
Finally release
heroku container:release web
With OpenAPI support we can generate clients based on our API. So if say we were building a React app we can automatically have our API translated into an API Client written in Javascript, Typescript orr any of the other generators available including rust!
To get started, lets start our server and export our api spec to a file we can pass to the generator.
curl http://0.0.0.0:8000/api/spec.json > api-spec.json
Lets see what kinda of things we can generate with our api spec.
docker run openapitools/openapi-generator-cli:v4.3.0 list
You can see
CLIENT generators:
...
- javascript
docker run \
-v ${PWD}/api-client:/local/out/javascript \
-v ${PWD}/api-spec.json:/local/in/api-spec.json \
openapitools/openapi-generator-cli:v4.3.0 generate \
--input-spec /local/in/api-spec.json \
--generator-name javascript \
--output /local/out/javascript \
--skip-validate-spec
If using typescript also add to the end
--additional-properties=typescriptThreePlus=true
It's best to have this committed in a different repo but generated whenever the the API is updated and built