relay_server/endpoints/
mod.rs

1//! Web server endpoints.
2//!
3//! This module contains implementations for all supported relay endpoints, as well as a generic
4//! `forward` endpoint that sends unknown requests to the upstream.
5
6mod attachments;
7mod autoscaling;
8mod batch_metrics;
9mod batch_outcomes;
10mod common;
11mod envelope;
12mod events;
13mod forward;
14mod health_check;
15mod minidump;
16mod monitor;
17mod nel;
18#[cfg(sentry)]
19mod playstation;
20mod project_configs;
21mod public_keys;
22mod security_report;
23mod statics;
24mod store;
25mod traces;
26mod unreal;
27
28use axum::extract::DefaultBodyLimit;
29use axum::routing::{Router, any, get, post};
30use relay_config::Config;
31
32use crate::middlewares;
33use crate::service::ServiceState;
34
35/// Size limit for internal batch endpoints.
36const BATCH_JSON_BODY_LIMIT: usize = 50_000_000; // 50 MB
37
38#[rustfmt::skip]
39pub fn routes(config: &Config) -> Router<ServiceState>{
40    // Relay-internal routes pointing to /api/relay/
41    let internal_routes = Router::new()
42        .route("/api/relay/healthcheck/{kind}/", get(health_check::handle))
43        .route("/api/relay/events/{event_id}/", get(events::handle))
44        .route("/api/relay/autoscaling/", get(autoscaling::handle))
45        // Fallback route, but with a name, and just on `/api/relay/*`.
46        .route("/api/relay/{*not_found}", any(statics::not_found));
47
48    // Sentry Web API routes pointing to /api/0/relays/
49    let web_routes = Router::new()
50        .route("/api/0/relays/projectconfigs/", post(project_configs::handle))
51        .route("/api/0/relays/publickeys/", post(public_keys::handle))
52        // Network connectivity check for downstream Relays, same as the internal health check.
53        .route("/api/0/relays/live/", get(health_check::handle_live))
54        .route_layer(DefaultBodyLimit::max(crate::constants::MAX_JSON_SIZE));
55
56    let batch_routes = Router::new()
57        .route("/api/0/relays/outcomes/", post(batch_outcomes::handle))
58        .route("/api/0/relays/metrics/", post(batch_metrics::handle))
59        .route_layer(DefaultBodyLimit::max(BATCH_JSON_BODY_LIMIT));
60
61    // Ingestion routes pointing to /api/:project_id/
62    let store_routes = Router::new()
63        // Legacy store path that is missing the project parameter.
64        .route("/api/store/", store::route(config))
65        // cron monitor level routes.  These are user facing APIs and as such support trailing slashes.
66        .route("/api/{project_id}/cron/{monitor_slug}/{sentry_key}", monitor::route(config))
67        .route("/api/{project_id}/cron/{monitor_slug}/{sentry_key}/", monitor::route(config))
68        .route("/api/{project_id}/cron/{monitor_slug}", monitor::route(config))
69        .route("/api/{project_id}/cron/{monitor_slug}/", monitor::route(config))
70
71        .route("/api/{project_id}/store/", store::route(config))
72        .route("/api/{project_id}/envelope/", envelope::route(config))
73        .route("/api/{project_id}/security/", security_report::route(config))
74        .route("/api/{project_id}/csp-report/", security_report::route(config))
75        .route("/api/{project_id}/nel/", nel::route(config))
76        // No mandatory trailing slash here because people already use it like this.
77        .route("/api/{project_id}/minidump", minidump::route(config))
78        .route("/api/{project_id}/minidump/", minidump::route(config))
79        .route("/api/{project_id}/events/{event_id}/attachments/", post(attachments::handle))
80        .route("/api/{project_id}/unreal/{sentry_key}/", unreal::route(config))
81        // The OTLP/HTTP transport defaults to a request suffix of /v1/traces (no trailing slash):
82        // https://opentelemetry.io/docs/specs/otlp/#otlphttp-request
83        // Because we initially released this endpoint with a trailing slash, keeping it for
84        // backwards compatibility.
85        .route("/api/{project_id}/otlp/v1/traces", traces::route(config))
86        .route("/api/{project_id}/otlp/v1/traces/", traces::route(config));
87        // NOTE: If you add a new (non-experimental) route here, please also list it in
88        // https://github.com/getsentry/sentry-docs/blob/master/docs/product/relay/operating-guidelines.mdx
89
90    #[cfg(sentry)]
91    let store_routes = store_routes.route("/api/{project_id}/playstation/", playstation::route(config));
92    let store_routes = store_routes.route_layer(middlewares::cors());
93
94    Router::new().merge(internal_routes)
95        .merge(web_routes)
96        .merge(batch_routes)
97        .merge(store_routes)
98        // Forward all other API routes to the upstream. This will 404 for non-API routes.
99        .fallback(forward::forward)
100}