very fast at protocol indexer with flexible filtering, xrpc queries, cursor-backed event stream, and more, built on fjall
rust
fjall
at-protocol
atproto
indexer
1use crate::control::{FilterPatch, Hydrant};
2use crate::filter::{FilterMode, SetUpdate};
3use axum::{
4 Json, Router,
5 extract::State,
6 http::StatusCode,
7 routing::{get, patch},
8};
9use serde::Deserialize;
10
11type FilterSnapshot = crate::control::FilterSnapshot;
12
13pub fn router() -> Router<Hydrant> {
14 Router::new()
15 .route("/filter", get(handle_get_filter))
16 .route("/filter", patch(handle_patch_filter))
17}
18
19pub async fn handle_get_filter(
20 State(hydrant): State<Hydrant>,
21) -> Result<Json<FilterSnapshot>, (StatusCode, String)> {
22 hydrant
23 .filter
24 .get()
25 .await
26 .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
27 .map(Json)
28}
29
30#[derive(Deserialize)]
31pub struct PatchFilterBody {
32 pub mode: Option<FilterMode>,
33 pub signals: Option<SetUpdate>,
34 pub collections: Option<SetUpdate>,
35 pub excludes: Option<SetUpdate>,
36}
37
38pub async fn handle_patch_filter(
39 State(hydrant): State<Hydrant>,
40 Json(body): Json<PatchFilterBody>,
41) -> Result<Json<FilterSnapshot>, (StatusCode, String)> {
42 let mut p = FilterPatch::new(&hydrant.filter);
43 p.mode = body.mode;
44 p.signals = body.signals;
45 p.collections = body.collections;
46 p.excludes = body.excludes;
47 p.apply()
48 .await
49 .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
50 .map(Json)
51}