Skip to main content

a2a_rust/server/
router.rs

1use std::sync::Arc;
2
3use axum::Router;
4use axum::routing::{get, post};
5
6use super::handler::A2AHandler;
7use super::{jsonrpc, rest, streaming};
8
9/// Build an axum router exposing the A2A REST, JSON-RPC, and discovery routes.
10pub fn router<H>(handler: H) -> Router
11where
12    H: A2AHandler,
13{
14    let handler = Arc::new(handler);
15
16    Router::new()
17        .route(
18            "/.well-known/agent-card.json",
19            get(rest::get_agent_card::<H>),
20        )
21        .route("/message:send", post(rest::send_message::<H>))
22        .route(
23            "/{tenant}/message:send",
24            post(rest::tenant_send_message::<H>),
25        )
26        .route("/message:stream", post(streaming::send_message::<H>))
27        .route(
28            "/{tenant}/message:stream",
29            post(streaming::tenant_send_message::<H>),
30        )
31        .route("/tasks", get(rest::list_tasks::<H>))
32        .route("/{tenant}/tasks", get(rest::tenant_list_tasks::<H>))
33        // axum/matchit does not support literal suffixes like `:cancel` or `:subscribe`
34        // on the same segment as a capture, so those canonical A2A paths are dispatched
35        // inside the task handlers after extracting the full `{id}` segment.
36        .route(
37            "/tasks/{id}",
38            get(rest::get_task_or_subscribe::<H>).post(rest::cancel_task::<H>),
39        )
40        .route(
41            "/{tenant}/tasks/{id}",
42            get(rest::tenant_get_task_or_subscribe::<H>).post(rest::tenant_cancel_task::<H>),
43        )
44        .route(
45            "/tasks/{task_id}/pushNotificationConfigs",
46            post(rest::create_task_push_notification_config::<H>)
47                .get(rest::list_task_push_notification_configs::<H>),
48        )
49        .route(
50            "/{tenant}/tasks/{task_id}/pushNotificationConfigs",
51            post(rest::tenant_create_task_push_notification_config::<H>)
52                .get(rest::tenant_list_task_push_notification_configs::<H>),
53        )
54        .route(
55            "/tasks/{task_id}/pushNotificationConfigs/{id}",
56            get(rest::get_task_push_notification_config::<H>)
57                .delete(rest::delete_task_push_notification_config::<H>),
58        )
59        .route(
60            "/{tenant}/tasks/{task_id}/pushNotificationConfigs/{id}",
61            get(rest::tenant_get_task_push_notification_config::<H>)
62                .delete(rest::tenant_delete_task_push_notification_config::<H>),
63        )
64        .route(
65            "/extendedAgentCard",
66            get(rest::get_extended_agent_card::<H>),
67        )
68        .route(
69            "/{tenant}/extendedAgentCard",
70            get(rest::tenant_get_extended_agent_card::<H>),
71        )
72        .route("/rpc", post(jsonrpc::handle::<H>))
73        .route("/jsonrpc", post(jsonrpc::handle::<H>))
74        .with_state(handler)
75}