Expand description
A framework for building game backend servers: tokio + axum, modules with hooks, MySQL / PostgreSQL / SQLite through one database handle, plain-SQL migrations the app can own, OpenAPI, a command line, graceful shutdown.
It is a library you build your own server binary with. The message types are shared with the
clients through net_backend_protocol (re-exported as protocol).
use net_backend_server::{AppError, Config, NetBackendServer};
use net_backend_server::axum::{routing::get, Json};
async fn motd() -> Result<Json<&'static str>, AppError> {
Ok(Json("welcome"))
}
#[tokio::main]
async fn main() -> Result<(), net_backend_server::Error> {
let config = Config::load()?; // NBS_CONFIG / config.toml + NBS__* variables
NetBackendServer::new(config)
.route("/v1/game/motd", get(motd)) // your own routes, plain axum handlers
.run() // CLI: serve, migrate, migrations publish, config check
.await
}What is inside: the core: the app builder and module
system (NetBackendServer, Module, hooks), configuration (Config), the error
model (AppError), the database layer (db) and migrations (migrate), the HTTP basics
(http: health, info, body limits, request ids, client addresses, timeouts, panic safety,
CORS), OpenAPI, metrics, the command line (cli, command) and graceful shutdown; and the
accounts module Auth (auth: email + password and Steam logins, rotating tokens,
sessions, verification and reset mails (mail), roles, the audit log, /v1/admin, rate
limits (rate_limit)); and the WebSocket hub (ws: /v1/ws with the protocol’s envelope,
handlers by kind, pushes, rooms, caps, close codes, an AsyncAPI document at
ASYNCAPI_PATH); typed routes mounted from the protocol’s HttpCall (http::call); and
the modules storage (per-user JSON objects with versions) and chat (rooms, direct
messages, history, presence, moderation), each behind its cargo feature.
Cargo features: mysql (default), postgres, sqlite (additive, any combination compiles,
at least one is needed to run a server); steam (the built-in Steam ticket check) and smtp
(the SMTP mailer); storage and chat (the modules; off by default).
Re-exports§
pub use auth::Auth;pub use auth::AuthContext;pub use auth::AuthService;pub use auth::Authenticator;pub use config::Config;pub use config::SecretString;pub use db::Db;pub use db::DbError;pub use db::DbTx;pub use db::Dialect;pub use error::AppError;pub use error::Error;pub use hooks::Decision;pub use hooks::Event;pub use hooks::HookCtx;pub use hooks::Hooks;pub use http::ApiJson;pub use http::ClientIp;pub use http::Ext;pub use http::RequestId;pub use migrate::Migration;pub use module::Module;pub use state::AppState;pub use state::Clock;pub use state::ManualClock;pub use state::SystemClock;pub use net_backend_protocol as protocol;pub use axum;pub use sea_query;pub use sqlx;pub use utoipa;pub use utoipa_axum;
Modules§
- auth
- Authentication: the seam every request passes through (
Authenticator,AuthContext,RequireRole) and the built-in accounts moduleAuth. - chat
chat - Chat: public rooms, direct messages, group rooms, history, presence and moderation over the
WebSocket hub (cargo feature
chat, moduleChat). - cli
- The command line (“artisan-style”), built into every server binary:
- command
- App commands: extra command-line commands from modules and the app, run like the built-in
ones (
game-server user:create ada@example.com --admin). - config
- Configuration: a TOML file plus environment overrides, typed and validated at startup.
- db
- The database layer: one
Dbhandle over the sqlx pool of the configured backend, with statements built by sea-query so the same code runs on MySQL, PostgreSQL and SQLite. - error
- Errors:
Errorfor the framework itself (configuration, database, migrations, modules, startup) andAppErrorfor answers to clients. - hooks
- Hooks: where a game plugs its own rules into the framework and its modules.
- http
- HTTP basics: extractors (
ApiJson,Ext,RequestId), the middleware stack and the core routes. - Mail: the
Mailertrait, aLogMailer(development; the default), aMemoryMailer(tests), and the SMTP mailerSmtpMailer(featuresmtp: lettre on tokio with rustls + ring, no OpenSSL / aws-lc). - migrate
- Migrations: plain SQL per dialect, ordered, tracked in a table, namespaced per module, and publishable into the app (the Laravel way).
- module
- The module system: a
Modulebundles routes, migrations, hooks and OpenAPI parts under a name, like a service provider. - rate_
limit - Rate limiting: the
RateLimiterseam and a ready in-memory implementation. - shutdown
- Graceful shutdown: one
Shutdownsignal per server. - state
- The shared application state (“service container”): configuration, database, clock, hooks, the shutdown signal and the game’s own state values.
- storage
storage - Storage: per-user JSON objects (save slots, settings, inventory snapshots), the protocol’s
/v1/storageroutes (cargo featurestorage, moduleStorage). - ws
- The WebSocket hub at
/v1/ws: authenticated sockets speaking the protocol’s JSON envelope, request handlers by kind, server pushes to a connection / a user / a room / everyone, rooms, caps, rate limits, backpressure, heartbeats and graceful shutdown.
Macros§
- call_
route - A documented typed route:
call_route!(WriteObject, put_object)mountsput_object(which carries#[utoipa::path(..)]and takesCall<WriteObject>last) atWriteObject::ROUTE. Pass the result toNetBackendServer::routesorOpenApiRouter::routes.
Structs§
- NetBackend
Server - The server builder.
- Prepared
Server - A built server: database connected, router assembled. Serve it, or run migrations with it.
Constants§
- ASYNCAPI_
PATH - Where the AsyncAPI document of the WebSocket endpoint is served (with
openapi.enabledandws.enabled).