Compare commits

...

22 Commits

Author SHA1 Message Date
fa-sharp
594e15a768 add Dockerfile 2026-02-22 02:24:28 -05:00
fa-sharp
13918f65ad ci: remove unnecessary steps when no updates are available 2026-02-20 23:12:20 -05:00
fa-sharp
97c8b6a38d Update README.md 2026-02-20 05:51:00 -05:00
fa-sharp
97854359bf Update README.md 2026-02-20 05:43:55 -05:00
fa-sharp
bf394f7dbc Create .gitignore.liquid 2026-02-20 05:43:55 -05:00
fa-sharp
9096d6a3e9 Delete TEMPLATE_USAGE.md 2026-02-20 05:43:55 -05:00
ffc5b946c2 ⬆️ Automated Dependency Upgrade (#5)
This PR contains automated dependency upgrades that have been tested with `cargo check` and `cargo build`

## Changes

```
name       old req        compatible     latest         new req
====       =======        ==========     ======         =======
aide       0.16.0-alpha.1 0.16.0-alpha.2 0.16.0-alpha.2 0.16.0-alpha.2
anyhow     1.0.101        1.0.102        1.0.102        1.0.102
schemars   1.0            1.2.1          1.2.1          1.2
serde_json 1.0.145        1.0.149        1.0.149        1.0.149
tokio      1.48.0         1.49.0         1.49.0         1.49.0
   Upgrading git dependencies
     Locking 0 packages to latest Rust 1.90.0 compatible versions
   Upgrading recursive dependencies
     Locking 0 packages to latest Rust 1.90.0 compatible versions
note: Re-run with `--verbose` to show more dependencies
  git: axum-app-wrapper
  latest: 7 packages
```

## Testing

 Generated test project with aide
 Generated test project without aide
 All builds passed
 All checks passed

## Workflow Run

https://gitea.fasharp.io/fa-sharp/axum-template/actions/runs/14

---
*This PR was automatically created by the dependency check workflow.*

Co-authored-by: Dependency Bot <bot@gitea.actions>
Reviewed-on: #5
2026-02-20 10:19:08 +00:00
fa-sharp
2c807d62bc add openapi routes to aide template 2026-02-20 04:57:27 -05:00
fa-sharp
2efaa86440 add hello routes to template 2026-02-20 03:56:40 -05:00
fa-sharp
ea5a23ac23 ci: fix gitea credentials for opening pr 2026-02-20 03:41:08 -05:00
fa-sharp
8415a4e503 Update dependency-check.yml 2026-02-20 03:29:26 -05:00
fa-sharp
0e0da24caf ci: fix remote git url 2026-02-20 03:25:40 -05:00
fa-sharp
e0f91c6c80 ci: fix duplicate git commit 2026-02-20 03:14:02 -05:00
fa-sharp
da2129344d Update dependency-check.yml 2026-02-20 03:07:12 -05:00
fa-sharp
19b1952d14 Update dependency-check.yml 2026-02-20 03:03:02 -05:00
fa-sharp
673a53c34b ci: use own pr logic 2026-02-20 02:55:14 -05:00
fa-sharp
a0e9e2d834 Update dependency-check.yml 2026-02-20 02:32:26 -05:00
fa-sharp
29dda132d8 Update dependency-check.yml 2026-02-20 02:30:06 -05:00
fa-sharp
634b677947 ci: checkout and commit new deps 2026-02-20 02:28:00 -05:00
fa-sharp
2f9dccdf4f ci: fix pr action branch 2026-02-20 02:20:15 -05:00
fa-sharp
80c77444d2 ci: fix public server URL 2026-02-20 01:48:39 -05:00
fa-sharp
b3e301e45a Update dependency-check.yml 2026-02-20 01:46:50 -05:00
9 changed files with 254 additions and 293 deletions

View File

@@ -1,13 +1,11 @@
name: Dependency Check name: Dependency Check
on: on:
schedule:
# Run every Monday at 9:00 AM UTC
- cron: "0 9 * * 1"
workflow_dispatch: # Allow manual triggering workflow_dispatch: # Allow manual triggering
env: env:
RUST_VERSION: "1.90" RUST_VERSION: "1.90"
TEA_VERSION: "0.9.2"
jobs: jobs:
check-dependencies: check-dependencies:
@@ -72,10 +70,12 @@ jobs:
working-directory: dep-check-test working-directory: dep-check-test
- name: Check with upgraded dependencies - name: Check with upgraded dependencies
if: steps.upgrade.outputs.has_updates == 'true'
run: cargo check run: cargo check
working-directory: dep-check-test working-directory: dep-check-test
- name: Build with upgraded dependencies - name: Build with upgraded dependencies
if: steps.upgrade.outputs.has_updates == 'true'
run: cargo build run: cargo build
working-directory: dep-check-test working-directory: dep-check-test
@@ -108,7 +108,7 @@ jobs:
- Update the template if needed - Update the template if needed
- Test locally with \`cargo generate\` and \`cargo upgrade\` - Test locally with \`cargo generate\` and \`cargo upgrade\`
**Workflow Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" **Workflow Run:** ${{ vars.PUBLIC_SERVER_URL }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
# Create issue via Gitea API # Create issue via Gitea API
curl -X POST \ curl -X POST \
@@ -123,6 +123,7 @@ jobs:
}" }"
- name: Generate test project without aide - name: Generate test project without aide
if: steps.upgrade.outputs.has_updates == 'true'
run: | run: |
mkdir -p dep-check-no-aide && cd dep-check-no-aide mkdir -p dep-check-no-aide && cd dep-check-no-aide
cargo generate --path .. --name dep-check-no-aide --vcs none --init \ cargo generate --path .. --name dep-check-no-aide --vcs none --init \
@@ -134,18 +135,22 @@ jobs:
working-directory: ${{ github.workspace }} working-directory: ${{ github.workspace }}
- name: Check without aide (current dependencies) - name: Check without aide (current dependencies)
if: steps.upgrade.outputs.has_updates == 'true'
run: cargo check run: cargo check
working-directory: dep-check-no-aide working-directory: dep-check-no-aide
- name: Upgrade dependencies (no aide) - name: Upgrade dependencies (no aide)
if: steps.upgrade.outputs.has_updates == 'true'
run: cargo upgrade --incompatible run: cargo upgrade --incompatible
working-directory: dep-check-no-aide working-directory: dep-check-no-aide
- name: Check without aide (upgraded dependencies) - name: Check without aide (upgraded dependencies)
if: steps.upgrade.outputs.has_updates == 'true'
run: cargo check run: cargo check
working-directory: dep-check-no-aide working-directory: dep-check-no-aide
- name: Build without aide (upgraded dependencies) - name: Build without aide (upgraded dependencies)
if: steps.upgrade.outputs.has_updates == 'true'
run: cargo build run: cargo build
working-directory: dep-check-no-aide working-directory: dep-check-no-aide
@@ -178,7 +183,7 @@ jobs:
## Workflow Run ## Workflow Run
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ${{ vars.PUBLIC_SERVER_URL }}/${{ github.repository }}/actions/runs/${{ github.run_number }}
--- ---
*This PR was automatically created by the dependency check workflow.* *This PR was automatically created by the dependency check workflow.*
@@ -187,23 +192,66 @@ jobs:
cat pr-body.txt cat pr-body.txt
working-directory: ${{ github.workspace }} working-directory: ${{ github.workspace }}
- name: Install Tea
if: steps.upgrade.outputs.has_updates == 'true'
env:
TEA_DL_ARCH: '${{ fromJson(''{ "x86": "386", "x64": "amd64", "ARM": "arm", "ARM64": "arm64" }'')[ runner.arch ] }}'
TEA_DL_URL: "https://dl.gitea.com/tea/${{ env.TEA_VERSION }}/tea-${{ env.TEA_VERSION }}-linux-"
shell: bash
run: |
if ! command -v tea >/dev/null 2>&1; then
TEA_DIR=$(mktemp -d -t tmp.XXXX)
pushd $TEA_DIR
wget -q -nc "${TEA_DL_URL}${TEA_DL_ARCH}"
wget -q -nc "${TEA_DL_URL}${TEA_DL_ARCH}.sha256"
if $(sha256sum --quiet -c "tea-${{ env.TEA_VERSION }}-linux-${TEA_DL_ARCH}.sha256"); then
sudo mv "tea-${{ env.TEA_VERSION }}-linux-${TEA_DL_ARCH}" /usr/bin/tea
sudo chmod +x /usr/bin/tea
sudo cp -rf /usr/bin/tea $RUNNER_TOOL_CACHE/bin
popd
rm -rf $TEA_DIR
else
popd
rm -rf $TEA_DIR
echo "::error title=⛔ error hint::Tea v${{ env.TEA_VERSION }} Checksum Failed"
exit 1
fi
else
echo "Tea CLI already installed"
fi
- name: Login to Gitea
if: steps.upgrade.outputs.has_updates == 'true'
shell: bash
run: >-
tea login add
-u "${{ github.server_url }}"
-t "${{ secrets.REPO_WRITE_TOKEN }}"
- name: Create Pull Request with dependency updates - name: Create Pull Request with dependency updates
if: steps.upgrade.outputs.has_updates == 'true' if: steps.upgrade.outputs.has_updates == 'true'
uses: infinilabs/gitea-pr@v0
permissions: permissions:
contents: write contents: write
with: working-directory: ${{ github.workspace }}
url: ${{ github.server_url }} run: |
token: ${{ secrets.GITHUB_TOKEN }} # Read the PR body from file
path: ${{ github.workspace }}/axum-template PR_BODY=$(cat pr-body.txt)
commit-message: "chore: upgrade dependencies"
committer: "Dependency Bot <bot@github.actions>" # Configure git authentication
author: "Dependency Bot <bot@github.actions>" git config user.name "Dependency Bot"
base: ${{ github.ref_name }} git config user.email "bot@gitea.actions"
branch: deps/auto-upgrade-${{ github.run_number }}
title: "⬆️ Automated Dependency Upgrade" # Commit and push changes
body-path: ${{ github.workspace }}/pr-body.txt git checkout -b "deps/auto-upgrade-${{ github.run_number }}"
pr-label: "deps/bot" git add Cargo.toml.liquid
git commit -m "chore: upgrade dependencies"
git push origin "deps/auto-upgrade-${{ github.run_number }}"
# Create PR with description from file
tea pr create \
--title "⬆️ Automated Dependency Upgrade" \
--description "$PR_BODY" \
--labels "deps/bot"
- name: Summary - name: Summary
if: success() if: success()

20
.gitignore.liquid Normal file
View File

@@ -0,0 +1,20 @@
# Rust
/target
# Env files
.env*
!.env.example
# OS files
.DS_Store
# Build artifacts
*.exe
*.dll
*.so
*.dylib
# Temporary files
tmp/
temp/
*.tmp

View File

@@ -6,19 +6,20 @@ description = "{{project-description}}"
[dependencies] [dependencies]
{% if include_aide %} {% if include_aide %}
aide = { version = "0.16.0-alpha.1", features = [ aide = { version = "0.16.0-alpha.2", features = [
"axum", "axum",
"axum-json", "axum-json",
"axum-query", "axum-query",
"swagger"
] } ] }
{% endif %} {% endif %}
anyhow = "1.0.101" anyhow = "1.0.102"
axum = { version = "0.8.8", features = ["json", "query"] } axum = { version = "0.8.8", features = ["json", "query"] }
axum-app-wrapper = { git = "https://gitea.fasharp.io/fa-sharp/axum-app-wrapper", rev = "a8d5e4f962" } axum-app-wrapper = { git = "https://gitea.fasharp.io/fa-sharp/axum-app-wrapper", rev = "a8d5e4f962" }
dotenvy = "0.15.7" dotenvy = "0.15.7"
figment = { version = "0.10.19", features = ["env"] } figment = { version = "0.10.19", features = ["env"] }
{% if include_aide %} {% if include_aide %}
schemars = { version = "1.0", features = [ schemars = { version = "1.2", features = [
"chrono04", "chrono04",
"preserve_order", "preserve_order",
"url2", "url2",
@@ -26,8 +27,8 @@ schemars = { version = "1.0", features = [
] } ] }
{% endif %} {% endif %}
serde = { version = "1.0.228", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.145" serde_json = "1.0.149"
tokio = { version = "1.48.0", default-features = false, features = [ tokio = { version = "1.49.0", default-features = false, features = [
"macros", "macros",
"net", "net",
"rt", "rt",

45
Dockerfile Normal file
View File

@@ -0,0 +1,45 @@
# Image versions (can be overridden by args when building)
ARG RUST_VERSION=1.90
ARG DEBIAN_VERSION=bookworm
### Build server ###
FROM rust:${RUST_VERSION}-slim-${DEBIAN_VERSION} AS build
WORKDIR /app
# Copy all necessary files to build the server
COPY Cargo.lock Cargo.toml ./
COPY ./src ./src
# COPY ./migrations ./migrations
# etc...
ARG pkg={{project-name}}
RUN --mount=type=cache,id=rust_target,target=/app/target \
--mount=type=cache,id=cargo_registry,target=/usr/local/cargo/registry \
--mount=type=cache,id=cargo_git,target=/usr/local/cargo/git \
set -eux; \
cargo build --package $pkg --release --locked; \
objcopy --compress-debug-sections target/release/$pkg ./run-server
### Run server ###
FROM debian:${DEBIAN_VERSION}-slim AS run
# Create non-root user
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/home/appuser" \
--shell "/sbin/nologin" \
--uid "${UID}" \
appuser
USER appuser
# Copy server binary
COPY --from=build --chown=appuser /app/run-server /usr/local/bin/
# Run server
WORKDIR /app
ENV {{env_prefix}}_HOST=0.0.0.0
CMD ["run-server"]

View File

@@ -10,6 +10,7 @@ A production-ready template for building web services with Rust and Axum.
- **Graceful Shutdown** - Handles SIGTERM and SIGINT signals - **Graceful Shutdown** - Handles SIGTERM and SIGINT signals
- **Plugin Architecture** - Modular app initialization with `axum-app-wrapper` - **Plugin Architecture** - Modular app initialization with `axum-app-wrapper`
- **Optional OpenAPI** - API documentation with `aide` (optional) - **Optional OpenAPI** - API documentation with `aide` (optional)
- **Docker / OCI** - Dockerfile with sensible defaults for quick deployment
## Usage ## Usage
@@ -24,7 +25,7 @@ cargo install cargo-generate
Generate a new project from this template: Generate a new project from this template:
```bash ```bash
cargo generate --git <your-template-repo-url> cargo generate --git https://gitea.fasharp.io/fa-sharp/axum-template
``` ```
You'll be prompted for: You'll be prompted for:
@@ -35,16 +36,9 @@ You'll be prompted for:
- **Default log level**: trace, debug, info, warn, or error - **Default log level**: trace, debug, info, warn, or error
- **Include aide**: Whether to include OpenAPI documentation support - **Include aide**: Whether to include OpenAPI documentation support
### Manual Setup
1. Clone or download this repository
2. Update `Cargo.toml` with your project name and details
3. Copy `.env.example` to `.env` and configure your environment variables
4. Run `cargo build`
## Configuration ## Configuration
Configuration is loaded from environment variables. The prefix is configurable during template generation. Configuration is loaded from environment variables and validated in the `config.rs` file. The variable prefix is configurable during template generation.
Example with `APP` prefix: Example with `APP` prefix:
@@ -58,18 +52,20 @@ APP_PORT=8080
APP_LOG_LEVEL=info APP_LOG_LEVEL=info
``` ```
In development, you can use the `.env` file. In development, you can use the `.env` file to set environment variables.
## Project Structure ## Project Structure
``` ```
. .
├── src/ ├── src/
│ ├── main.rs # Entry point, server setup │ ├── routes/ # API routes
│ ├── lib.rs # App initialization
│ ├── config.rs # Configuration management │ ├── config.rs # Configuration management
── state.rs # Application state ── lib.rs # Axum server setup
│ ├── main.rs # Entry point
│ └── state.rs # Axum server state
├── Cargo.toml # Dependencies ├── Cargo.toml # Dependencies
├── .env # Local environment variables
└── .env.example # Example environment variables └── .env.example # Example environment variables
``` ```
@@ -80,7 +76,7 @@ In development, you can use the `.env` file.
cargo run cargo run
# Run with custom log level # Run with custom log level
RUST_LOG=debug cargo run APP_LOG_LEVEL=debug cargo run
# Build for production # Build for production
cargo build --release cargo build --release

View File

@@ -1,255 +0,0 @@
# Axum Template Usage Guide
This repository is a **cargo-generate** template for creating new Axum web services with a pre-configured, production-ready setup.
## Quick Start
### Prerequisites
Install `cargo-generate`:
```bash
cargo install cargo-generate
```
### Generate a New Project
#### From a Git Repository (Recommended for Production Use)
```bash
cargo generate --git https://gitea.fasharp.io/fa-sharp/axum-template
```
#### From Local Path (For Testing)
```bash
cargo generate --path /path/to/axum-template
```
### Interactive Prompts
When you run `cargo generate`, you'll be prompted for:
1. **Project name**: The name of your new project (e.g., `my-api-server`)
2. **Project description**: Brief description (e.g., "REST API for user management")
3. **Environment variable prefix**: Prefix for configuration env vars (e.g., `APP``APP_HOST`, `APP_PORT`)
4. **Default port**: Server's default port (e.g., `8080`)
5. **Default log level**: Choose from `trace`, `debug`, `info`, `warn`, or `error`
6. **Include aide**: Whether to include OpenAPI documentation support (`true` or `false`)
### Non-Interactive Mode
You can skip prompts by providing values via CLI:
```bash
cargo generate --git <repo-url> \
--name my-service \
--define project-description="My awesome service" \
--define env_prefix="API" \
--define default_port="3000" \
--define default_log_level="info" \
--define include_aide=true
```
## Generated Project Structure
```
my-project/
├── src/
│ ├── main.rs # Application entry point with server setup
│ ├── lib.rs # App initialization and plugin registration
│ ├── config.rs # Configuration management (figment-based)
│ └── state.rs # Application state management
├── Cargo.toml # Dependencies (customized based on your choices)
├── .env.example # Example environment variables
├── .gitignore # Pre-configured for Rust projects
└── README.md # Project-specific README
```
## Configuration
The generated project uses environment variables for configuration. The prefix is customizable during generation.
Example with `APP` prefix:
```bash
# Required
APP_API_KEY=your-secret-api-key
# Optional (defaults are set during template generation)
APP_HOST=127.0.0.1
APP_PORT=8080
APP_LOG_LEVEL=info
```
In development, copy `.env.example` to `.env`:
```bash
cp .env.example .env
# Edit .env with your values
```
## Features Included
### Core Features (Always Included)
- **Axum 0.8** - Modern, ergonomic web framework
- **Environment-based Config** - `figment` for flexible configuration
- **Structured Logging** - `tracing` with JSON output in production
- **Graceful Shutdown** - Handles SIGTERM, SIGINT, and Ctrl-C
- **Plugin Architecture** - `axum-app-wrapper` for modular initialization
- **Rust 2024 Edition** - Latest language features
### Optional Features
- **OpenAPI Documentation** - `aide` and `schemars` (optional during generation)
## Next Steps After Generation
1. **Navigate to your project**:
```bash
cd my-project
```
2. **Configure environment**:
```bash
cp .env.example .env
# Edit .env with your actual values
```
3. **Run in development**:
```bash
cargo run
```
4. **Add your routes**:
- Create a new module for your routes
- Implement a plugin function
- Register it in `src/lib.rs`
5. **Build for production**:
```bash
cargo build --release
```
## Customization Tips
### Adding Routes
Create a new module (e.g., `src/routes.rs`):
```rust
use axum::{routing::get, Router};
use axum_app_wrapper::AdHocPlugin;
use crate::state::AppState;
pub fn plugin() -> AdHocPlugin<AppState> {
AdHocPlugin::new().on_router(|router| async move {
let routes = Router::new()
.route("/health", get(health_check));
Ok(router.merge(routes))
})
}
async fn health_check() -> &'static str {
"OK"
}
```
Register it in `src/lib.rs`:
```rust
pub async fn create_app() -> anyhow::Result<(axum::Router, AppConfig, impl Future + Send)> {
let (router, state, on_shutdown) = App::new()
.register(config::plugin())
.register(routes::plugin()) // Add this line
.init()
.await?;
let app_config = state.config.to_owned();
Ok((router.with_state(state), app_config, on_shutdown))
}
```
### Adding Dependencies
Just edit `Cargo.toml` as normal:
```bash
cargo add sqlx --features postgres,runtime-tokio
```
### Changing the Environment Prefix
The prefix is baked in during template generation. To change it later, search and replace in:
- `src/config.rs` (the `extract_config` function)
- `.env.example`
## Publishing Your Template
### GitHub
1. Push this directory to GitHub
2. Enable "Template repository" in Settings
3. Others can use: `cargo generate --git https://github.com/you/axum-template`
### GitLab/Gitea
1. Push to your instance
2. Share the URL: `cargo generate --git https://gitea.example.com/you/axum-template`
### Private Repositories
cargo-generate supports authentication:
```bash
cargo generate --git https://github.com/you/private-template --branch main
# You'll be prompted for credentials if needed
```
## Template Maintenance
### Updating Dependencies
Update the versions in `Cargo.toml.liquid` and commit:
```bash
# Edit Cargo.toml.liquid
git add Cargo.toml.liquid
git commit -m "Update dependencies"
git push
```
### Testing the Template
Generate a test project locally:
```bash
cargo generate --path . --name test-project --define include_aide=true
cd test-project
cargo check
cargo test
```
## Troubleshooting
### "Failed to parse Cargo.toml"
- Make sure template syntax is on separate lines in `.liquid` files
- Cargo-generate needs `.liquid` extension for files with Jinja2 syntax
### Missing Imports in Generated Code
- Check that Rust edition is set to 2024 in `Cargo.toml.liquid`
- Edition 2024 includes `Future` in the prelude
### Conditional Features Not Working
- Use `{% if variable %}...{% endif %}` syntax
- Keep conditionals on their own lines in TOML files
- Test with both `true` and `false` values
## License
Configure the license for your template as appropriate. The generated projects will inherit this license unless modified.

View File

@@ -3,10 +3,15 @@ use axum_app_wrapper::App;
use crate::config::AppConfig; use crate::config::AppConfig;
mod config; mod config;
mod routes;
mod state; mod state;
pub async fn create_app() -> anyhow::Result<(axum::Router, AppConfig, impl Future + Send)> { pub async fn create_app() -> anyhow::Result<(axum::Router, AppConfig, impl Future + Send)> {
let (router, state, on_shutdown) = App::new().register(config::plugin()).init().await?; let (router, state, on_shutdown) = App::new()
.register(config::plugin()) // Extract configuration and add to state
.register(routes::plugin()) // Add API routes
.init()
.await?;
let app_config = state.config.to_owned(); let app_config = state.config.to_owned();
Ok((router.with_state(state), app_config, on_shutdown)) Ok((router.with_state(state), app_config, on_shutdown))

54
src/routes/hello.rs Normal file
View File

@@ -0,0 +1,54 @@
{% if include_aide %}
use axum::extract::{Json, Query};
use schemars::JsonSchema;
use serde::Deserialize;
{% endif %}
use crate::state::AppState;
{% if include_aide == false %}
pub fn routes() -> axum::Router<AppState> {
axum::Router::new()
.route("/", axum::routing::get(hello_handler))
.route("/", axum::routing::post(post_handler))
}
async fn hello_handler() -> String {
"Hello, World!".to_string()
}
async fn post_handler() -> String {
"Post handler!".to_string()
}
{% else %}
pub fn routes() -> aide::axum::ApiRouter<AppState> {
aide::axum::ApiRouter::new()
.api_route(
"/",
aide::axum::routing::get_with(hello_handler, |op| op.summary("Greet user")),
)
.api_route(
"/",
aide::axum::routing::post_with(post_handler, |op| op.summary("Relay message")),
)
}
async fn hello_handler(Query(query): Query<HelloQuery>) -> String {
format!("Hello, {}!", query.name)
}
async fn post_handler(Json(body): Json<PostBody>) -> String {
format!("Received message: {}", body.message)
}
#[derive(Debug, Clone, Deserialize, JsonSchema)]
struct HelloQuery {
/// The name of the person to greet
name: String,
}
#[derive(Debug, Clone, Deserialize, JsonSchema)]
struct PostBody {
/// The message to relay
message: String,
}
{% endif %}

47
src/routes/mod.rs Normal file
View File

@@ -0,0 +1,47 @@
use axum_app_wrapper::AdHocPlugin;
use crate::state::AppState;
pub mod hello;
/// Adds all API routes to the server under `/api`
pub fn plugin() -> AdHocPlugin<AppState> {
AdHocPlugin::new().on_setup(|router, _state| {
{% if include_aide == false %}
let api_routes = axum::Router::new().nest("/hello", hello::routes());
Ok(router.nest("/api", api_routes))
{% else %}
// Build API routes
let api_router = aide::axum::ApiRouter::new().nest("/hello", hello::routes());
// OpenAPI configuration
let mut openapi = aide::openapi::OpenApi {
info: aide::openapi::Info {
title: "{{project-name}}".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
description: Some("{{project-description}}".to_string()),
..Default::default()
},
servers: vec![aide::openapi::Server {
url: "/api".to_string(),
..Default::default()
}],
..Default::default()
};
// Add API routes to the router under `/api` and also merge them into the OpenAPI docs
let router = router.nest("/api", api_router.finish_api(&mut openapi));
// Add OpenAPI documentation routes
let openapi_json = serde_json::to_string_pretty(&openapi).unwrap();
let openapi_route = axum::routing::get(|| async move { openapi_json });
let swagger_route = aide::swagger::Swagger::new("/api/openapi.json").axum_route();
let router = router
.route("/api/openapi.json", openapi_route)
.route("/api/docs", swagger_route.into());
Ok(router)
{% endif %}
})
}