mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-03 00:47:53 +00:00
3.0 KiB
3.0 KiB
API Conventions
HTTP Handlers (Actix-Web)
Handlers in storyteller_web follow this structure:
- Request/Response types with
#[derive(Deserialize/Serialize, ToSchema)] - Error enum implementing
ResponseError,Display,Serialize,ToSchema - Handler function annotated with
#[utoipa::path(...)]for OpenAPI docs - Handler returns
Result<Json<Response>, ErrorType>. Only useResult<HttpResponse, ErrorType>when you need to set headers/cookies.
Error Types
- Use
CommonWebErrorfor simple handlers that only need standard HTTP error codes - Use a custom error enum when you need endpoint-specific error variants (e.g.
LoginErrorType::InvalidCredentials) - Custom error enums MUST implement
ResponseError(actix),Display, andSerialize - When adding
From<RequireUserSessionError>or similar conversions, implement them onCommonWebErrorin its own module (orphan rule) - Error response bodies include:
success: false,error_code,error_code_str
Session/Auth
Helpers live in storyteller_web under http_server/web_utils/user_session/. Each takes a
generic mysql_executor: E (any sqlx::Executor), so whether it reuses a connection or acquires
its own depends on the argument you pass:
require_user_session(http_request, session_checker, mysql_executor)— require a logged-in user.require_user_session_extended(...)— same, with extra session detail.require_moderator(http_request, session_checker, mysql_executor)— admin-only endpoints.
PREFER passing an already-open connection (&mut *conn) so the helper reuses it. Passing
&server_state.mysql_pool makes it acquire a fresh connection — avoid that when the handler
already holds one (the double-acquire adds pool pressure; this crate has had pool-timeout
incidents). There is no *_using_connection variant — the reuse/acquire choice is the argument.
API Type Definitions
- Shared request/response types go in
artcraft_api_defscrate (undercrates/api_clients/artcraft/artcraft_api_defs/) - Types that need
ResponseErrorimpl must stay instoryteller_web(orphan rule) - New types must be added to
api_doc.rsschemas (in storyteller-web) for Swagger generation
Enums (Database-backed)
- Located in
crates/schema/public/enums/src/by_table/{table_name}/ - Require manual
to_str()andfrom_str()implementations - Use
impl_enum_display_and_debug_using_to_str!andimpl_mysql_enum_coders!macros - Add comprehensive tests: serialization, round-trip, variant count
- YOU CAN ADD NEW VALUES but DO NOT CHANGE EXISTING VALUES without a migration strategy
- Note that adding new values can break older versions of the Tauri desktop app that read responses over Rust - make sure it consumes variants with an "Unknown(String)" variant catch-all to future proof the APIs.
Tokens (Primary Keys)
- Located in
crates/schema/public/tokens/src/tokens/ - Opaque
Stringwrappers with Stripe-like prefixes (e.g.user_,mf_) - Use
impl_string_token!,impl_mysql_token_from_row!,impl_crockford_generator!macros