Skip to main content

ServerConfig

Struct ServerConfig 

Source
pub struct ServerConfig {
Show 48 fields pub schema_path: PathBuf, pub database_url: String, pub bind_addr: SocketAddr, pub cors_enabled: bool, pub cors_origins: Vec<String>, pub compression_enabled: bool, pub tracing_enabled: bool, pub otlp_endpoint: Option<String>, pub otlp_export_timeout_secs: u64, pub tracing_service_name: String, pub apq_enabled: bool, pub cache_enabled: bool, pub graphql_path: String, pub health_path: String, pub readiness_path: String, pub introspection_path: String, pub metrics_path: String, pub metrics_json_path: String, pub playground_path: String, pub playground_enabled: bool, pub playground_tool: PlaygroundTool, pub subscription_path: String, pub subscriptions_enabled: bool, pub metrics_enabled: bool, pub metrics_token: Option<String>, pub admin_api_enabled: bool, pub admin_token: Option<String>, pub admin_readonly_token: Option<String>, pub introspection_enabled: bool, pub introspection_require_auth: bool, pub design_api_require_auth: bool, pub pool_min_size: usize, pub pool_max_size: usize, pub pool_timeout_secs: u64, pub auth: Option<OidcConfig>, pub tls: Option<TlsServerConfig>, pub database_tls: Option<DatabaseTlsConfig>, pub require_json_content_type: bool, pub max_request_body_bytes: usize, pub max_header_count: usize, pub max_header_bytes: usize, pub request_timeout_secs: Option<u64>, pub max_get_query_bytes: usize, pub rate_limiting: Option<RateLimitConfig>, pub pool_tuning: Option<PoolPressureMonitorConfig>, pub admission_control: Option<AdmissionConfig>, pub security_contact: Option<String>, pub shutdown_timeout_secs: u64,
}
Expand description

Server configuration.

Fields§

§schema_path: PathBuf

Path to compiled schema JSON file.

§database_url: String

Database connection URL (PostgreSQL, MySQL, SQLite, SQL Server).

§bind_addr: SocketAddr

Server bind address.

§cors_enabled: bool

Enable CORS.

§cors_origins: Vec<String>

CORS allowed origins (if empty, allows all).

§compression_enabled: bool

Enable compression.

§tracing_enabled: bool

Enable request tracing.

§otlp_endpoint: Option<String>

OTLP exporter endpoint for distributed tracing.

When set (e.g. "http://otel-collector:4317"), the server initializes an OpenTelemetry OTLP exporter. When None, the OTEL_EXPORTER_OTLP_ENDPOINT environment variable is checked as a fallback. If neither is set, no OTLP export occurs (zero overhead).

§otlp_export_timeout_secs: u64

OTLP exporter timeout in seconds (default: 10).

§tracing_service_name: String

Service name for distributed tracing (default: "fraiseql").

§apq_enabled: bool

Enable APQ (Automatic Persisted Queries).

§cache_enabled: bool

Enable query caching.

§graphql_path: String

GraphQL endpoint path.

§health_path: String

Health check endpoint path (liveness probe).

Returns 200 as long as the process is alive, 503 if the database is down.

§readiness_path: String

Readiness probe endpoint path.

Returns 200 when the server is ready to serve traffic (database reachable), 503 otherwise. Kubernetes readinessProbe should point here.

§introspection_path: String

Introspection endpoint path.

§metrics_path: String

Metrics endpoint path (Prometheus format).

§metrics_json_path: String

Metrics JSON endpoint path.

§playground_path: String

Playground (GraphQL IDE) endpoint path.

§playground_enabled: bool

Enable GraphQL playground/IDE (default: false for production safety).

When enabled, serves a GraphQL IDE (GraphiQL or Apollo Sandbox) at the configured playground_path.

Security: Disabled by default for production safety. Set to true for development environments only. The playground exposes schema information and can be a reconnaissance vector for attackers.

§playground_tool: PlaygroundTool

Which GraphQL IDE to use.

  • graphiql: The classic GraphQL IDE (default)
  • apollo-sandbox: Apollo’s embeddable sandbox
§subscription_path: String

WebSocket endpoint path for GraphQL subscriptions.

§subscriptions_enabled: bool

Enable GraphQL subscriptions over WebSocket.

When enabled, provides graphql-ws (graphql-transport-ws) protocol support for real-time subscription events.

§metrics_enabled: bool

Enable metrics endpoints.

Security: Disabled by default for production safety. When enabled, requires metrics_token to be set for authentication.

§metrics_token: Option<String>

Bearer token for metrics endpoint authentication.

Required when metrics_enabled is true. Requests must include: Authorization: Bearer <token>

Security: Use a strong, random token (e.g., 32+ characters).

§admin_api_enabled: bool

Enable admin API endpoints (default: false for production safety).

Security: Disabled by default. When enabled, requires admin_token to be set. Admin endpoints allow schema reloading, cache management, and config inspection.

§admin_token: Option<String>

Bearer token for admin API authentication.

Required when admin_api_enabled is true. Requests must include: Authorization: Bearer <token>

Security: Use a strong, random token (minimum 32 characters). This token grants access to destructive admin operations: reload-schema, cache/clear.

If admin_readonly_token is set, this token is restricted to write operations only. If admin_readonly_token is not set, this token also grants access to read-only endpoints (backwards-compatible).

§admin_readonly_token: Option<String>

Optional separate bearer token for read-only admin operations.

When set, restricts admin_token to destructive operations only (reload-schema, cache/clear) and uses this token for read-only endpoints (config, cache/stats, explain, grafana-dashboard).

Operators and monitoring tools can use this token without gaining the ability to modify server state or reload the schema.

Security: Must be different from admin_token and at least 32 characters. Requires admin_api_enabled = true and admin_token set.

§introspection_enabled: bool

Enable introspection endpoint (default: false for production safety).

Security: Disabled by default. When enabled, the introspection endpoint exposes the complete GraphQL schema structure. Combined with introspection_require_auth, you can optionally protect it with OIDC authentication.

§introspection_require_auth: bool

Require authentication for introspection endpoint (default: true).

When true and OIDC is configured, introspection requires same auth as GraphQL endpoint. When false, introspection is publicly accessible (use only in development).

§design_api_require_auth: bool

Require authentication for design audit API endpoints (default: true).

Design audit endpoints expose system architecture and optimization opportunities. When true and OIDC is configured, design endpoints require same auth as GraphQL endpoint. When false, design endpoints are publicly accessible (use only in development).

§pool_min_size: usize

Database connection pool minimum size.

§pool_max_size: usize

Database connection pool maximum size.

§pool_timeout_secs: u64

Database connection pool timeout in seconds.

§auth: Option<OidcConfig>

OIDC authentication configuration (optional).

When set, enables JWT authentication using OIDC discovery. Supports Auth0, Keycloak, Okta, Cognito, Azure AD, and any OIDC-compliant provider.

§Example (TOML)

[auth]
issuer = "https://your-tenant.auth0.com/"
audience = "your-api-identifier"
§tls: Option<TlsServerConfig>

TLS/SSL configuration for HTTPS and encrypted connections.

When set, enables TLS enforcement for HTTP/gRPC endpoints and optionally requires mutual TLS (mTLS) for client certificates.

§Example (TOML)

[tls]
enabled = true
cert_path = "/etc/fraiseql/cert.pem"
key_path = "/etc/fraiseql/key.pem"
require_client_cert = false
min_version = "1.2"  # "1.2" or "1.3"
§database_tls: Option<DatabaseTlsConfig>

Database TLS configuration.

Enables TLS for database connections and configures per-database TLS settings (PostgreSQL, Redis, ClickHouse, etc.).

§Example (TOML)

[database_tls]
postgres_ssl_mode = "require"  # disable, allow, prefer, require, verify-ca, verify-full
redis_ssl = true               # Use rediss:// protocol
clickhouse_https = true         # Use HTTPS
elasticsearch_https = true      # Use HTTPS
verify_certificates = true      # Verify server certificates
§require_json_content_type: bool

Require Content-Type: application/json on POST requests (default: true).

CSRF protection: rejects POST requests with non-JSON Content-Type (e.g. text/plain, application/x-www-form-urlencoded) with 415.

§max_request_body_bytes: usize

Maximum request body size in bytes (default: 1 MB).

Requests exceeding this limit receive 413 Payload Too Large. Set to 0 to use axum’s default (no limit).

§max_header_count: usize

Maximum number of HTTP headers per request (default: 100).

Requests with more headers than this limit receive 431 Request Header Fields Too Large. Prevents header-flooding DoS attacks that exhaust memory.

§max_header_bytes: usize

Maximum total size of all HTTP headers in bytes (default: 32 KiB).

Requests whose combined header name+value bytes exceed this limit receive 431 Request Header Fields Too Large. Prevents memory exhaustion from oversized header values.

§request_timeout_secs: Option<u64>

Per-request processing timeout in seconds (default: None — no timeout).

When set, each HTTP request must complete within this many seconds or the server returns 408 Request Timeout. This is a defence-in-depth measure against slow or runaway database queries.

Recommendation: set to 60 for production deployments.

§Example (TOML)

request_timeout_secs = 60
§max_get_query_bytes: usize

Maximum byte length for a query string delivered via HTTP GET.

GET queries are URL-encoded and passed as a query parameter. Very long strings are either a DoS attempt or a sign that the caller should use POST instead. Default: 100_000 (100 KiB).

§Example (TOML)

max_get_query_bytes = 50000
§rate_limiting: Option<RateLimitConfig>

Rate limiting configuration for GraphQL requests.

When configured, enables per-IP and per-user rate limiting with token bucket algorithm. Defaults to enabled with sensible per-IP limits for security-by-default.

§Example (TOML)

[rate_limiting]
enabled = true
rps_per_ip = 100      # 100 requests/second per IP
rps_per_user = 1000   # 1000 requests/second per authenticated user
burst_size = 500      # Allow bursts up to 500 requests
§pool_tuning: Option<PoolPressureMonitorConfig>

Connection pool pressure monitoring configuration.

When enabled = true, the server spawns a background task that monitors pool metrics and emits scaling recommendations via Prometheus metrics and log lines. The pool is not resized at runtime — act on fraiseql_pool_tuning_* events by adjusting max_connections and restarting.

§Example (TOML)

[pool_tuning]
enabled = true
min_pool_size = 5
max_pool_size = 50
tuning_interval_ms = 30000
§admission_control: Option<AdmissionConfig>

Admission control configuration.

When set, enforces a maximum number of concurrent in-flight requests and a maximum queue depth. Requests that exceed either limit receive 503 Service Unavailable immediately instead of stalling under load.

§Example (TOML)

[admission_control]
max_concurrent = 500
max_queue_depth = 1000
§security_contact: Option<String>

Security contact email for /.well-known/security.txt (RFC 9116).

When set, the server exposes a /.well-known/security.txt endpoint with this email address as the security contact. This helps security researchers report vulnerabilities responsibly.

§Example (TOML)

security_contact = "security@example.com"
§shutdown_timeout_secs: u64

Graceful shutdown drain timeout in seconds (default: 30).

After a SIGTERM or Ctrl+C signal, the server stops accepting new connections and waits for in-flight requests and background runtimes (observers) to finish. If the drain takes longer than this value, the process logs a warning and exits immediately instead of hanging indefinitely.

Set this to match terminationGracePeriodSeconds in your Kubernetes pod spec minus a small buffer (e.g., 25s when terminationGracePeriodSeconds = 30).

Override with FRAISEQL_SHUTDOWN_TIMEOUT_SECS.

Implementations§

Source§

impl ServerConfig

Source

pub fn from_file(path: impl AsRef<Path>) -> Result<Self, String>

Load server configuration from a TOML file.

§Errors

Returns an error string if the file cannot be read or the TOML cannot be parsed.

Source

pub fn is_production_mode() -> bool

Check if running in production mode.

Production mode is detected via FRAISEQL_ENV environment variable.

  • production or prod (or any value other than development/dev) → production mode
  • development or dev → development mode
Source

pub fn validate(&self) -> Result<(), String>

Validate configuration.

§Errors

Returns error if:

  • metrics_enabled is true but metrics_token is not set
  • metrics_token is set but too short (< 16 characters)
  • auth config is set but invalid (e.g., empty issuer)
  • tls is enabled but cert or key path is missing
  • TLS minimum version is invalid
  • In production mode: playground_enabled is true
  • In production mode: cors_enabled is true but cors_origins is empty
Source

pub const fn auth_enabled(&self) -> bool

Check if authentication is enabled.

Trait Implementations§

Source§

impl Clone for ServerConfig

Source§

fn clone(&self) -> ServerConfig

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ServerConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ServerConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for ServerConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for ServerConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,