Rapina 0.7.0 shipped on February 27, 2026. This release added rapina import database, which introspects a live database and generates a full resource scaffold from the existing schema. Graceful shutdown was also added, giving servers a clean path to drain in-flight requests before exiting.
rapina import database
rapina import database connected to a running database, introspected its schema, and generated handlers, DTOs, entity blocks, and migrations — the same output as rapina add resource, but driven by the real schema rather than a field list on the command line.
rapina import database --url postgres://user:pass@localhost/mydbThe command required a feature flag matching the database driver:
# Install with Postgres support
cargo install rapina-cli --features import-postgres
# Install with MySQL support
cargo install rapina-cli --features import-mysql
# Install with SQLite support
cargo install rapina-cli --features import-sqliteOptions
| Flag | Description |
|---|---|
--url | Database connection URL (also reads DATABASE_URL) |
--tables | Comma-separated list of tables to import (default: all) |
--schema | Schema name (Postgres default: public; MySQL: inferred from URL) |
To import only specific tables:
rapina import database --url postgres://user:pass@localhost/mydb --tables users,postsWhat was generated
For each imported table, the command created the same file structure as rapina add resource:
src/{resource}/mod.rs # Module declarations
src/{resource}/handlers.rs # list, get, create, update, delete handlers
src/{resource}/dto.rs # Create and Update request types
src/{resource}/error.rs # Error type with IntoApiError
src/entity.rs # schema! {} block appended (or created)
src/migrations/ # Pre-filled migration for the table
src/migrations/mod.rs # Updated with new migration entryUnmappable column types (such as PostGIS geometry) were skipped with a warning rather than failing the whole import.
Graceful shutdown
The server now handled SIGINT and SIGTERM gracefully. When a signal was received, Rapina stopped accepting new connections and waited for in-flight requests to complete before exiting.
The default timeout was 30 seconds. It was configurable with .shutdown_timeout():
use std::time::Duration;
use rapina::prelude::*;
Rapina::new()
.shutdown_timeout(Duration::from_secs(60))
.router(router)
.listen("127.0.0.1:3000")
.awaitCleanup hooks ran after connections drained (or the timeout expired). Multiple hooks were supported and ran in registration order:
Rapina::new()
.on_shutdown(|| async {
println!("closing database pool...");
})
.on_shutdown(|| async {
println!("flushing metrics...");
})
.router(router)
.listen("127.0.0.1:3000")
.awaitIf the timeout expired before all connections drained, the server logged a warning and forced the close.
AI assistant config files in rapina new
rapina new now generated AI assistant config files alongside the project scaffold:
| File | Purpose |
|---|---|
AGENT.md | Generic context for any AI assistant |
.claude/CLAUDE.md | Claude Code–specific instructions |
.cursor/rules | Cursor AI rules |
The files included framework-specific guidance: how handlers were structured, how to use TestClient, the #[errors()] macro, Validated<Json<T>>, and other Rapina conventions.
To skip generating these files:
rapina new my-project --no-airapina doctor and rapina routes parameters
Both commands gained --port and --host flags, so they could reach an application running on a non-default address without editing any config:
# Default (port 3000, host 127.0.0.1)
rapina doctor
rapina routes
# Custom port and host
rapina doctor --port 8080 --host 0.0.0.0
rapina routes --port 8080Both flags also read from the RAPINA_PORT environment variable, consistent with how rapina dev handled the port.
Middleware documentation
A new middleware documentation page was added to the docs site. It covered all built-in middleware types — CORS, rate limiting, compression, request logging, tracing, and timeout — with configuration examples and the recommended ordering.
CLI refactor: shared Catppuccin palette
The CLI's inline color definitions were extracted into a shared colors.rs module using the Catppuccin Mocha palette. Previously each command duplicated its own color constants; after the refactor all commands imported from one place.
Upgrade by bumping the version in your Cargo.toml:
rapina = "0.7.0"