Publier des événements
Les modules collaborent sans se connaître : ils publient des événements au core, qui les relaie (LISTEN/NOTIFY) et les journalise.
Publier #
// events.rs — publication best-effort
pub async fn publish_note_created(state: &AppState, note_id: Uuid, user_id: Uuid) {
let payload = json!({
"type": "NoteCreated",
"payload": { "note_id": note_id, "user_id": user_id, "module_id": "memo" }
});
let url = format!("{}/internal/events/publish", state.settings.core.url);
let _ = reqwest::Client::new().post(&url)
.header("X-Internal-Secret", &state.settings.core.internal_secret)
.json(&payload).send().await;
}On publie en « fire-and-forget » pour ne pas ralentir la requête utilisateur :
// dans le handler create, après la réponse — on n'attend pas la publication
let st = state.clone();
tokio::spawn(async move { events::publish_note_created(&st, note.id, user.id).await; });Publier — dans d'autres langages #
// Rust
let payload = json!({ "type": "NoteCreated",
"payload": { "note_id": note_id, "user_id": user_id, "module_id": "memo" } });
client.post(format!("{core}/internal/events/publish"))
.header("X-Internal-Secret", secret)
.json(&payload).send().await.ok();<?php
$ch = curl_init("$core/internal/events/publish");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ["X-Internal-Secret: $secret", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode([
"type" => "NoteCreated",
"payload" => ["note_id" => $noteId, "user_id" => $userId, "module_id" => "memo"],
]),
]);
curl_exec($ch);# Python — requests
requests.post(f"{core}/internal/events/publish",
headers={"X-Internal-Secret": secret},
json={"type": "NoteCreated",
"payload": {"note_id": note_id, "user_id": user_id, "module_id": "memo"}})// Go
body, _ := json.Marshal(map[string]any{"type": "NoteCreated",
"payload": map[string]string{"note_id": noteID, "user_id": userID, "module_id": "memo"}})
req, _ := http.NewRequest("POST", core+"/internal/events/publish", bytes.NewReader(body))
req.Header.Set("X-Internal-Secret", secret)
http.DefaultClient.Do(req)# Perl — LWP
$ua->post("$core/internal/events/publish",
'X-Internal-Secret' => $secret, 'Content-Type' => 'application/json',
Content => encode_json({ type => "NoteCreated",
payload => { note_id => $note_id, user_id => $user_id, module_id => "memo" } }));Souscrire #
Déclarez vos abonnements dans le manifeste ([events].subscribed) — par exemple UserDeleted pour purger les notes d'un utilisateur supprimé. C'est ainsi qu'on garde la cohérence entre modules sans aucun couplage de code.
Note
Émettez des événements au passé et nommés clairement (NoteCreated, NoteDeleted) ; incluez toujours module_id dans la charge utile.