A modular blog platform written in Rust. The project exposes a HTTP API for posts, comments and author management while broadcasting events to Telegram and Discord. The server is built on top of the Screw ecosystem, Hyper for the HTTP layer and Rbatis for database access with PostgreSQL. The web front-end lives in the blog-ui repository.
The user-facing website is developed separately in the
blog-ui repository. It provides
the front-end that consumes this API and offers server-side rendering support
when the ssr feature is enabled.
blog-ui is wired in as a Cargo workspace member at blog-server/blog-ui, but
it is not committed here (it is gitignored). The Makefile clones it for you
on demand, pinned to BLOG_UI_TAG:
make blog-ui # clone blog-ui at BLOG_UI_TAG into ./blog-ui
make blog-ui BLOG_UI_TAG=1.4.2 # override the pinned tagmake run and make build depend on this target, so the clone happens
automatically the first time you build (see Running). The clone is
idempotent — to switch tags after a clone exists, rm -rf blog-ui first.
This repository is a Cargo workspace made up of several crates:
| Crate | Description |
|---|---|
blog-server-api |
HTTP entry point, request routing and middleware setup. |
blog-server-services |
Service layer with implementations for posts, comments, authors and social integrations. |
blog-generic |
Shared domain entities, events and utilities used by other crates. |
blog-ui |
Yew/WASM front-end (ssr rendering + static assets). Fetched on demand via make; gitignored, not committed here. See UI Repository. |
- CRUD operations for posts and comments.
- Author profiles with subscription management and optional social data.
- JSON based API with automatic request/response handling.
- Optional server‑side rendering through the
blog-uicrate (--features ssr). - Optional login via Yandex or Telegram (
--features yandexor--features telegram). - Event broadcasting through RabbitMQ, Telegram bots and Discord webhooks.
- Configuration driven notifications via
config.yaml.
- Rust toolchain (1.70 or later recommended)
gitandmake(used to fetch theblog-uiworkspace member)- PostgreSQL database
- Optional: RabbitMQ for the event bus
- Optional, only to build the front-end / SSR assets: the
wasm32-unknown-unknowntarget (rustup target add wasm32-unknown-unknown) andtrunk(cargo install trunk)
Compilation relies on a few environment variables. They must be supplied at build or run time:
export SITE_URL="http://127.0.0.1:3000"
export JWT_SECRET="changeme"
export SERVER_ADDRESS="127.0.0.1:3000"
export PG_URL="postgres://postgres:postgres@localhost:5432/blog"
export RABBIT_URL="amqp://guest:guest@localhost:5672/"
export TELEGRAM_BOT_TOKEN="0000000:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Runtime configuration such as Telegram chat IDs or Discord webhooks is stored in
config.yaml.
- Ensure PostgreSQL is running and matches the
PG_URLconnection string. - Adjust
config.yamlfor notification channels if necessary. - Start the server:
make runmake run first fetches blog-ui (if missing) and then runs
cargo run -p blog-server-api. Use make build to compile without running.
You can still invoke cargo directly (cargo run -p blog-server-api), but only
once blog-ui has been cloned — otherwise the workspace fails to load.
On start up the server applies database migrations, connects to RabbitMQ if
available and listens on SERVER_ADDRESS.
Note: server-side rendering reads
dist/index.htmlat runtime (produced by atrunk buildofblog-ui). A plainmake runfrom the workspace root has nodist/, so SSR requests will fail locally; the full stack is assembled by theDockerfile.
The router exposes a JSON API under the /api path. A selection of routes:
GET /api/posts– list published postsGET /api/post/{id}– retrieve a single postPOST /api/post– create a postPATCH /api/post/{id}– update a postDELETE /api/post/{id}– delete a postGET /api/comments/{post_id}– list comments for a postPOST /api/comment– create a commentGET /api/author/me– current author profilePOST /api/login– password based login
Many additional endpoints handle author management, subscriptions and searching.
See router.rs for the full list.
Fetch blog-ui first (so the workspace loads), then run the suite. CI scopes
tests to the server crate:
make blog-ui
cargo test -p blog-server-apiLicensed under the MIT license.
Issues and pull requests are welcome. Please open an issue describing the change or bug before submitting a pull request.