appcore-api
Stable 1.0.0 · MSRV Rust 1.89 · crates.io · docs.rs · code source
Guide et exemples maintenus par le crate
Le dépôt Runtime maintient le guide détaillé, exemple débutant et exemple intermédiaire. Le wiki résume la frontière publique ; les détails d’API et d’exécution restent avec le code du crate.
Responsabilité : host HTTP command/query/status et DTOs de transport.
Dépendances internes : appcore-core, appcore-security et
appcore-supervisor.
API principale : CommandRequest/CommandResponse,
QueryRequest/QueryResponse, erreurs de validation, CommandEndpoint,
QueryEndpoint, ApiRouter, ApiRequest/ApiResponse, RuntimeHttpHost,
HttpApiConfig, statut statique, policy capability pour commands et queries
applicatives, vérification token et vue du sync log.
À utiliser pour les routes Runtime et queries applicatives enregistrées. Ne pas
ajouter resources REST produit ou schémas métier. Les applications utilisent
les contrats via appcore-sdk/api ; l'exécutable de déploiement possède le host HTTP.
Les queries applicatives sont autorisées par la policy capability composée avant le router. Les queries de statut Runtime restent hors du catalogue applicatif.
Sur la ligne de maintenance 1.0 actuelle, les hosts Runtime gèlent
l'enregistrement des queries de ApiRouter après le bootstrap. Les snapshots
du router partagent des endpoints immuables via Arc ; la façade directe, le
HTTP et le peer RPC libèrent le mutex d'état du host avant d'appeler
l'endpoint. Les queries indépendantes s'exécutent donc en parallèle et un
enregistrement tardif échoue avec router_frozen.
query_names_iter permet à la validation du manifest d'emprunter ce registre
immuable ; la méthode owned déterministe query_names reste disponible pour la
sortie. Avec 1 024 queries, le scan emprunté a mesuré 28,63 us p50 et 2,41 Mio
de RSS de pic, contre 183,26 us et 2,55 Mio pour la matérialisation complète.
La query intégrée runtime.audit limite chaque réponse aux 1 000 éléments les
plus récents. Elle capture des snapshots partagés des enregistrements et
entrées sous des locks courts, puis matérialise seulement cette page après leur
libération, au lieu de cloner en profondeur les deux files complètes de 10 000
éléments. Sélectionner 1 000 sur 10 000 a mesuré 2,06 us p50 et 11,88 Mio de RSS
de pic, contre 4,16 ms et 20,33 Mio pour les anciennes copies complètes.
runtime.events suit la même frontière de snapshot, limite la page récente à
1 000 et continue d'omettre les payloads opaques de sa réponse inchangée.
Sélectionner 1 000 sur 10 000 événements a mesuré 2,39 us p50 et 8,48 Mio de RSS
de pic, contre 2,09 ms et 14,59 Mio pour cloner tout l'historique.
La limite configurée s'applique au corps HTTP complet avant la
désérialisation JSON par Axum. Les routes protégées acceptent exactement un
header bearer Authorization bien formé; les doublons échouent fermés.
La validation de query structurée transmet le JSON à un writer compteur borné.
Elle applique ainsi la limite exacte d'octets sérialisés sans conserver un
Vec<u8> encodé, tandis que la méthode publique payload_bytes() reste
compatible. Le chemin HTTP ne valide qu'une fois avant le dispatch blocking.
Le router possède un seul RuntimeStaticInfo immuable partagé ; cloner l'état
de la requête ne copie ni les listes de peers, ni les seeds DNS, ni les paths ou
les chaînes d'identité. Le dispatch blocking prend possession des requêtes
command/query. L'audit query ne conserve que l'ID et le nom bornés pendant le
traitement du payload.
Les chemins command owned appellent CommandRequest::into_envelope, conservent
la validation V1 et déplacent l'allocation UTF-8 existante dans
CommandEnvelope. to_envelope reste disponible aux callers empruntés.
CommandTokenVerifier possède aussi des méthodes additives pour les requêtes
empruntées. Leurs defaults matérialisent RequestValidationDetails et appellent
les méthodes owned existantes, donc les verifiers existants gardent leur
comportement. Le verifier du Runtime les surcharge pour hasher directement le
texte ou le JSON structuré, sans copie owned du payload.
HttpCommandAuth::default() exige l'authentification et échoue fermé tant
qu'aucun vérificateur de token n'est configuré. Seul
insecure_local_for_testing() désactive explicitement l'authentification
command/query pour des tests locaux contrôlés. /v1/health reste public par
contrat. Les refus d'autorisation command sont audités avec des métadonnées
normalisées, sans credentials, payload ni clé d'idempotence.
1.0.2-rc : reload coordonné du routing
La ligne candidate 1.0.2-rc ajoute le ReloadableRuntimeHttpHost opt-in. Un
candidat doit avoir une génération strictement plus récente sur la même adresse
liée et réussir /v1/health avant et après une commutation atomique du routing.
Les requêtes déjà acceptées gardent leur Router initial jusqu'à leur fin ; la
génération précédente est drainée sous délai. Un échec de santé ou de drain
restaure l'ancienne génération et ferme l'admission de la génération défaillante.
Le owner conserve au plus une génération active et une en drain. Une génération
défaillante avec des requêtes bloque un autre reload jusqu'à ce que son dernier
permit libère le Router. generation_snapshot rapporte l'admission et
l'in-flight actif/en drain sans données de requête ni historique non borné. Une
annulation après la commutation restaure synchroniquement la génération
précédente.
Le pointeur actif est lock-free, les délais sont plafonnés à 60 secondes et le snapshot contient uniquement les compteurs génération, in-flight, succès, échec et rollback. La composition root peut transférer un listener TCP déjà lié pour valider le bind avant démarrage. Les changements d'adresse exigent une autre génération de listener préparée et ne sont pas inférés.
Cette API décrit seulement l'état du source. Elle ne doit pas être considérée
comme disponible dans le paquet stable 1.0.0 indiqué ci-dessus. Voir
reload coordonné.
Maturité : surface HTTP V1 stricte et stable.