Skip to content

Latest commit

 

History

History

configuration

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
icon description
sliders-up
Learn how to configure your router.

Configuration

The router provides three different ways of customization:

  1. Configure the router runtime: You can specify a config.yaml for convenience or pass environment variables. In both ways, you can configure the global behavior of the router. For a full reference of all available options see below or use your IDE of choice.
  2. Configure how your graph is served: This file can be provided as config option or is pulled automatically from the cdn. It contains information on how to resolve your federated schema. The engine uses the information to build a highly optimized query planner. For more information see wgc router compose to build the file locally for development or wgc router fetch to download the latest production version.
  3. Customize the router programatically through Go modules. It is unlikely that we will provide every possible feature as an in-built functionality. For advanced use cases or more control, you can build Go modules and compile the Router in a few commands. If you are uncertain about if your use case should be implemented as a custom module, don't hesitate to open an issue. We might already have a plan for this or can assist you with the implementation.

{% hint style="info" %} Recommendation Create a config file and use environment variable expansion to avoid storing secrets on the file system. {% endhint %}

Config file

For convenience, you can create a config.yaml to specify all router options. Start the router in the same directory or pass the path to the file as a CONFIG_PATH environment variable.

{% code title="config.yaml" %}

version: '1'

graph:
    token: "${GRAPH_API_TOKEN}"

{% endcode %}

{% hint style="warning" %} Values specified in the config file have precedence over Environment variables. This also includes empty values so only specify values that should be overwritten. That means, you can see the config file as a single source of truth. {% endhint %}

Expand Environment Variables

You can expand environment variables in the file like this:

{% code title="config.yaml" %}

version: '1'

log_level: "${LOG_LEVEL}"

{% endcode %}

This will replace the value of the environment variable LOG_LEVEL with the value of the key log_level in your config file. For numeric values, ensure quotes are omitted.

Config Validation & Auto-completion

We know configuration is hard, especially for a software component like the router that can be customized entirely to your needs. In order to simplify this, we use JSON schema to validate the router configuration. This comes with huge benefits, all right at your fingertips:

  • Auto-completion
  • Documentation (Usage, Examples)
  • Detect deprecated fields
  • Detect typos or invalid values.

Some options require the router to validate them. This requires starting the router. Once your router has started successfully, you can be sure that your configuration is valid.

IDE Configuration

  • VsCode: Install the YAML extension in your IDE.
  • JetBrains: Support out of the box but in some circumstances it conflicts with other default mappings. Go to Languages & Frameworks -> Schemas and DTDs -> JSON Schemas Mappings configure the mapping yourself.

As the next step, add the following line to the head of your config.yamlfile. This line informs your IDE, to download the correct JSON schema file to validate the config file.

{% code title="config.yaml" %}

# yaml-language-server: $schema=https://raw.githubusercontent.com/wundergraph/cosmo/main/router/pkg/config/config.schema.json

version: '1'

{% endcode %}

If you want to pin to a specific router version use the following URL:

{% code title="config.yaml" %}

# yaml-language-server: $schema=https://raw.githubusercontent.com/wundergraph/cosmo/router%400.67.0/router/pkg/config/config.schema.json

{% endcode %}

Now, you should get auto-completion 🌟 .

Environment Variables

Many configuration options can be set as environment variables. For a complete list of options, please look at the Router config tables.

Router

The following sections describe each configuration in detail with all available options and their defaults.

{% hint style="info" %} Intervals, timeouts, and delays are specified in Go duration syntax e.g 1s, 5m or 1h.

Sizes can be specified in 2MB, 1mib. {% endhint %}

Environment VariableYAMLRequiredDescriptionDefault Value
LISTEN_ADDRlisten_addrfalseThe server listener address.localhost:3002
CONTROLPLANE_URLcontrolplane_urltrueThe controlplane url. Not required when a static execution config is provided.https://cosmo-cp.wundergraph.com
PLAYGROUND_ENABLEDplayground_enabledfalseEnables the GraphQL playground on ($LISTEN_ADDR/)true
PLAYGROUND_PATHplayground_pathfalseThe path where the playground is served"/"
INTROSPECTION_ENABLEDintrospection_enabledfalsetrue
QUERY_PLANS_ENABLEDquery_plans_enabledfalseThe Router can return Query plans as part of the response, which might be useful to understand the execution.true
LOG_LEVELlog_levelfalsedebug / info / warning / error / fatal / panicinfo
JSON_LOGjson_logfalseRender the log output in JSON format (true) or human readable (false)true
SHUTDOWN_DELAYshutdown_delayfalseMaximum time in seconds the server has to shutdown gracefully. Should be higher than GRACE_PERIOD60s
GRACE_PERIODgrace_periodfalseMaximum time in seconds the server has between schema updates to gracefully clean up all resources. Should be smaller than SHUTDOWN_DELAY30s
POLL_INTERVALpoll_intervalfalseThe interval of how often the router should check for new schema updates10s
POLL_JITTERpoll_jitterfalseThe maximum delay added to the poll interval to mitigate thundering herd issues in router fleets scenarios.5s
HEALTH_CHECK_PATHhealth_check_pathfalseHealth check path. Returns 200 when the router is alive/health
READINESS_CHECK_PATHreadiness_check_pathfalseReadiness check path. Return 200 when the router is ready to accept traffic, otherwise 503/health/ready
LIVENESS_CHECK_PATHliveness_check_pathfalseLiveness check path. Return 200 when the router is alive/health/live
GRAPHQL_PATHgraphql_pathfalseThe path where the GraphQL Handler is served/graphql
PLAYGROUND_PATHplayground_pathfalseThe path where the playground is served/
LOCALHOST_FALLBACK_INSIDE_DOCKERlocalhost_fallback_inside_dockerfalseEnable fallback for requests that fail to connect to localhost while running in Dockertrue
DEV_MODEdev_modefalseEnables pretty log output and allows to use advanced-request-tracing-art.md without further security protection.false
INSTANCE_IDfalseIf not specified, a new ID will be generated with each router start. A stable ID ensures that metrics with the same ID are grouped together and the same server can be identified on the platform.

Example configuration:

{% code title="config.yaml" fullWidth="false" %}

version: "1"
  
log_level: "info"
listen_addr: "localhost:3002"
controlplane_url: "https://cosmo-cp.wundergraph.com"
playground_enabled: true
playground_path: "/"
introspection_enabled: true
json_log: true
shutdown_delay: 15s
grace_period: 20s
poll_interval: 10s
health_check_path: "/health"
readiness_check_path: "/health/ready"
liveness_check_path: "/health/live"
router_config_path: ""

{% endcode %}

Access Logs

For a detailed example, please refer to the Access Logs section.

Environment VariableYAMLRequiredDescriptionDefault Value
access_logsfalseEnable the access logs. The access logs are used to log the incoming requests. By default, the access logs are enabled and logged to the standard output.
ACCESS_LOGS_ENABLEDaccess_logs.enabledfalseEnable the access logs. The access logs are used to log the incoming requests. By default, the access logs are enabled and logged to the standard output.true
access_logs.bufferfalseThe buffer is used to buffer the logs before writing them to the output.
ACCESS_LOGS_BUFFER_ENABLEDaccess_logs.buffer.enabledfalseEnable the buffer.false
ACCESS_LOGS_BUFFER_SIZEaccess_logs.buffer.sizefalseThe size of the buffer. The default value is 256KB.
ACCESS_LOGS_FLUSH_INTERVALaccess_logs.buffer.flush_intervalfalseThe interval at which the buffer is flushed. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.
access_logs.outputfalseThe log destination. The supported destinations are stdout and file. Only one option can be enabled. The default destination is stdout.
ACCESS_LOGS_OUTPUT_STDOUT_ENABLEDaccess_logs.output.stdout.enabledfalsetrue
ACCESS_LOGS_OUTPUT_FILE_ENABLEDaccess_logs.output.file.enabledfalsefalse
ACCESS_LOGS_FILE_OUTPUT_PATHaccess_logs.output.file.pathfalseThe path to the log file. The path is used to specify the path to the log file.
access_logs.routerfalseThe configuration for access logs for the router.
access_logs.router.fieldsfalseThe fields to add to the access logs for router. The fields are added to the logs as key-value pairs.[]
access_logs.router.fields.keyfalseThe key of the field to add to the logs.
access_logs.router.fields.defaultfalseThe default value of the field. If the value is not set, value_from is used. If both value and value_from are set, value_from has precedence and in case of a missing value_from, the default value is used.
access_logs.router.value_fromfalseDefines a source for the field value e.g. from a request header. If both default and value_from are set, value_from has precedence.
access_logs.router.fields.value_from.request_headerfalseThe name of the request header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used.
access_logs.router.fields.value_from.context_fieldfalseThe field name of the context from which to extract the value. The value is only extracted when a context is available otherwise the default value is used.

One of:
[ "operation_name", "operation_type", "operation_service_names", "operation_hash", "persisted_operation_sha256", "operation_sha256", "response_error_message", "graphql_error_codes", "graphql_error_service_names", "operation_parsing_time", "operation_validation_time", "operation_planning_time", "operation_normalization_time" ]
access_logs.subgraphsfalseThe subgraph access logs configuration
access_logs.subgraphs.enabledfalseEnable the subgraphs access logs.false
access_logs.subgraphs.fieldsfalseThe fields to add to the logs when printing subgraph access logs. The fields are added to the logs as key-value pairs.
access_logs.subgraphs.fields.keyfalseThe key of the field to add to the logs.
access_logs.subgraphs.fields.defaultfalseThe default value of the field. If the value is not set, value_from is used. If both value and value_from are set, value_from has precedence and in case of a missing value_from, the default value is used.
access_logs.subgraphs.value_fromfalseDefines a source for the field value e.g. from a request header. If both default and value_from are set, value_from has precedence.
access_logs.subgraphs.fields.value_from.request_headerfalseThe name of the request header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used.
access_logs.subgraphs.fields.value_from.response_headerfalseThe name of the response header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used.
access_logs.subgraphs.fields.value_from.context_fieldfalseThe field name of the context from which to extract the value. The value is only extracted when a context is available otherwise the default value is used.

One of:
[ "operation_name", "operation_type", "operation_service_names", "operation_hash", "persisted_operation_sha256", "operation_sha256", "operation_parsing_time", "operation_validation_time", "operation_planning_time", "operation_normalization_time" ]

Example YAML config:

{% code title="config.yaml" %}

version: "1"

access_logs:
  enabled: true
  buffer:
    enabled: false
    size: 256KB
    flush_interval: 10s
  output:
    file:
      enabled: true
      path: "access.log"
  router: 
    fields:
    - key: "service"
      value_from:
        request_header: "x-service"
    - key: "operationName"
      value_from:
        context_field: operation_name
  subgraphs: 
    fields:
    - key: "service"
      value_from:
        request_header: "x-service"
    - key: "response-service"
      value_from:
        response_header: "x-response-service"
    - key: "operationName"
      value_from:
        context_field: operation_name

{% endcode %}

Telemetry

Graph

Overall configuration for the Graph that's configured for this Router.

Environment VariableYAMLRequiredDescriptionDefault Value
GRAPH_API_TOKENtokentrueThe token permits the router to communicate with the controlplane and export telemetry. Created with wgc router token create. (Can be empty when providing a static router configuration through ROUTER_CONFIG_PATHbut will disable the default telemetry stack)

Example YAML config:

{% code title="config.yaml" %}

version: "1"

graph:
  token: "<your-graph-token>"

{% endcode %}

TLS

The Router supports TLS and mTLS for secure communication with your clients and infrastructure components like load balancer.

Server TLS

Environment VariableYAMLRequiredDescriptionDefault Value
TLS_SERVER_ENABLEDenabledfalseEnables server TLS support.false
TLS_SERVER_CERT_FILEcert_filefalseThe path to the server certificate file.
TLS_SERVER_KEY_FILEkey_filefalseThe path to the server private key file.

Example YAML config:

{% code title="config.yaml" %}

version: "1"
 
tls:
  server:
    enabled: true
    key_file: ../your/key.pem
    cert_file: ../your/cert.pem

{% endcode %}

Client Authentication

Environment VariableYAMLRequiredDescriptionDefault Value
TLS_CLIENT_AUTH_CERT_FILEcert_filefalseEnables client authentication support. The file to the certificate file used to authenthicate clients.""
TLS_CLIENT_AUTH_REQUIREDrequiredfalseEnforces a valid client certificate to establish a connection.false

Example YAML config:

{% code title="config.yaml" %}

version: "1"
 
tls:
  server:
    enabled: true # Required for client_auth
    key_file: ../your/key.pem
    cert_file: ../your/cert.pem
    client_auth:
      required: true
      cert_file: ../your/cert.pem

{% endcode %}

Compliance

The configuration for the compliance. Includes for example the configuration for the anonymization of the IP addresses.

IP Anonymization

Environment VariableYAMLRequiredDescriptionDefault Value
SECURITY_ANONYMIZE_IP_ENABLEDenabledfalseEnables IP anonymization in traces and logs.true
SECURITY_ANONYMIZE_IP_METHODmethodfalseThe metod to anonymize IP addresses. Can be "hash" or "redact"."redact"

Example YAML config:

{% code title="config.yaml" %}

version: "1"
 
compliance:
  anonymize_ip:
    enabled: true
    method: redact # hash or redact

{% endcode %}

Cluster

Environment VariableYAMLRequiredDescriptionDefault Value
CLUSTER_NAMEnamefalseThe logical name of the router cluster. The name is used for analytic purpose.

Example YAML config:

{% code title="config.yaml" %}

version: "1"
 
# See "https://cosmo-docs.wundergraph.com/studio/cluster-management" for more information
cluster:
  name: "us-central1-cosmo-cloud "

{% endcode %}

Telemetry

Environment VariableYAMLRequiredDescriptionDefault Value
TELEMETRY_SERVICE_NAMEservice_nametruecosmo-router
resource_attributesfalseThe resource attributes to add to OTEL metrics and traces. The resource attributes identify the entity producing the traces and metrics.
resource_attributes.keytrueThe key of the attribute.
resource_attributes.valuetrueThe value of the attribute.
attributesfalseThe attributes to add to OTEL metrics and traces. Because Prometheus metrics rely on the OpenTelemetry metrics, the attributes are also added to the Prometheus metrics.[]
attributes.keyfalseThe key of the attribute.
attributes.defaultfalseThe value of the attribute.
attributes.value_fromfalseDefines a source for the attribute value e.g. from a request header. If both default and value_from are set, value_from has precedence.
attributes.value_from.request_headerfalseThe name of the request header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used. Don't forget to add the header to your CORS settings.

Example YAML config:

{% code title="config.yaml" %}

version: "1"

# Only needed when setting attributes based on a request header
cors:
  allow_headers:
    - "x-service"
 
# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # Common options
  service_name: "cosmo-router"
  resource_attributes:
    - key: env
      value: "prod"
  attributes:
    - key: service
      default: "static"
      value_from:
        request_header: "x-service"

{% endcode %}

Tracing

Environment VariableYAMLRequiredDescriptionDefault Value
TRACING_ENABLEDenabledfalsetrue
TRACING_SAMPLING_RATEsampling_ratetrueThe sampling rate for the traces. The value must be between 0 and 1. If the value is 0, no traces will be sampled. If the value is 1, all traces will be sampled.1
TRACING_PARENT_BASED_SAMPLERparent_based_samplertrueEnable the parent-based sampler. The parent-based sampler is used to sample the traces based on the parent trace.true
TRACING_BATCH_TIMEOUTfalseThe maximum delay allowed before spans are exported.10s
TRACING_EXPORT_GRAPHQL_VARIABLESexport_graphql_variablesfalseExport GraphQL variables as span attribute. Variables may contain sensitive data.false
with_new_rootfalseStarts the root span always at the router.false

Example YAML config:

{% code title="config.yaml" %}

version: "1"
 
# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # Common options
  service_name: "cosmo-router"
  # uses https://cosmo-otel.wundergraph.com for tracing and metrics

  # OpenTelemetry Tracing
  tracing:
    enabled: true
    sampling_rate: 1
    batch_timeout: '10s'
    export_graphql_variables: false
    with_new_root: false

{% endcode %}

Exporters

Environment VariableYAMLRequiredDescriptionDefault Value
disabledfalsebool
exporterfalseone of: http,grpc
endpointfalse
pathfalse
headersfalse

Example YAML config:

{% code title="config.yaml" %}

version: "1"
 
# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  tracing:
    enabled: true
    exporters:
      # If no exporters are defined, the default one is used
      - exporter: http # or grpc
        disabled: false
        endpoint: https://my-otel-collector.example.com
        # headers: {Authorization: Bearer <my-token>}
        batch_timeout: 10s
        export_timeout: 30s

{% endcode %}

Propagation

Environment VariableYAMLRequiredDescriptionDefault Value
trace_contextfalsetrue
jaegerfalse
b3false
baggagefalse
datadogfalseEnable Datadog trace propagationfalse

Example YAML config:

{% code title="config.yaml" %}

version: "1"
 
# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # OpenTelemetry Tracing
  tracing:
    propagation:
      # https://www.w3.org/TR/trace-context/
      trace_context: true
      # https://www.w3.org/TR/baggage/
      baggage: false
      # https://www.jaegertracing.io/ (compliant with opentracing)
      jaeger: false
      # https://github.com/openzipkin/b3-propagation (zipkin)
      b3: false
      # https://docs.datadoghq.com/tracing/trace_collection/trace_context_propagation/?tab=java#datadog-format
      datadog: false      

{% endcode %}

Metrics

OTLP

Environment VariableYAMLRequiredDescriptionDefault Value
METRICS_OTLP_ENABLEDenabledtrueEnables OTEL metrics instrumentationtrue
METRICS_OTLP_ROUTER_RUNTIMErouter_runtimefalseEnable the collection of metrics for the router runtime.true
METRICS_OTLP_GRAPHQL_CACHEgraphql_cachefalseEnable the collection of metrics for the GraphQL operation router caches.false
METRICS_OTLP_EXCLUDE_METRICSexclude_metricsfalseThe metrics to exclude from the OTEL metrics. Accepts a list of Go regular expressions. Use https://regex101.com/ to test your regular expressions.[]
METRICS_OTLP_EXCLUDE_METRIC_LABELSexclude_metric_labelsfalseThe metric labels to exclude from the OTEL metrics. Accepts a list of Go regular expressions. Use https://regex101.com/ to test your regular expressions.[]

Attributes

YAMLRequiredDescriptionDefault ValueEnvironment Variable
attributesfalseThe attributes to add to OTLP Metrics and Prometheus.[]
attributes.keyfalseThe key of the field.
attributes.defaultfalseThe default value of the field. If the value is not set, value_from is used. If both value and value_from are set, value_from has precedence and in case of a missing value_from, the default value is used.
attributes.value_fromfalseDefines a source for the field value e.g. from a request header or request context. If both default and value_from are set, value_from has precedence.
attributes.value_fromfalseDefines a source for the field value e.g. from a request header or request context. If both default and value_from are set, value_from has precedence.
attributes.value_from.request_headerfalseThe name of the request header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used.
attributes.value_from.context_fieldfalseThe field name of the context from which to extract the value. The value is only extracted when a context is available otherwise the default value is used.One of:
["operation_service_names", "graphql_error_codes", "graphql_error_service_names", "operation_sha256"]

Example YAML config:

{% code title="config.yaml" %}

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  metrics:
    otlp:
      enabled: true
      router_runtime: true
      graphql_cache: true
      exclude_metrics: []
      exclude_metric_labels: []
    attributes:
      - key: "x-new-attribute"
        default: "foo" 
        value_from:
          request_header: "X-Request-ID"

      - key: "error_codes"
        value_from:
          context_field: graphql_error_codes

{% endcode %}

Prometheus

Environment VariableYAMLRequiredDescriptionDefault Value
PROMETHEUS_ENABLEDenabledtrueEnables prometheus metrics supporttrue
PROMETHEUS_HTTP_PATHpathfalseThe HTTP path where metrics are exposed."/metrics"
PROMETHEUS_LISTEN_ADDRlisten_addrfalseThe prometheus listener address"127.0.0.1:8088"
PROMETHEUS_GRAPHQL_CACHEgraphql_cachefalseEnable the collection of metrics for the GraphQL operation router caches.false
PROMETHEUS_EXCLUDE_METRICSexclude_metricsfalse
PROMETHEUS_EXCLUDE_METRIC_LABELSexclude_metric_labelsfalse

Example YAML config:

{% code title="config.yaml" %}

version: "1"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  metrics:
    # Expose OpenTelemetry metrics for scraping
    prometheus:
      enabled: true
      path: "/metrics"
      listen_addr: "127.0.0.1:8088"
      graphql_cache: true
      exclude_metrics: []
      exclude_metric_labels: []

{% endcode %}

Exporter

YAMLRequiredDescriptionDefault ValueEnvironment Variable
disabledfalse
exporterfalseone of: http,grpc
endpointfalse
pathfalseThe path to which the metrics are exported. This is ignored when using 'grpc' as exporter and can be omitted.
headersfalse
temporalityfalseTemporality defines the window that an aggregation is calculated over.

one of: delta, cumulative

Example YAML config:

{% code title="config.yaml" %}

version: "1"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # Common options
  service_name: "cosmo-router"
  # uses https://cosmo-otel.wundergraph.com for tracing and metrics

  # OpenTelemetry Metrics
  metrics:
    otlp:
      enabled: true
      # If no exporters are defined, the default one is used
      exporters:
        - exporter: http # or grpc
          disabled: false
          endpoint: https://my-otel-collector.example.com
          temporality: delta # or cumulative
          # headers: {Authorization: Bearer <my-token>}
          
    # Expose OpenTelemetry metrics for scraping
    prometheus:
      enabled: true
      path: "/metrics"
      listen_addr: "127.0.0.1:8088"
      exclude_metrics: []
      exclude_metric_labels: []

{% endcode %}

GraphQL Metrics

Environment VariableYAMLRequiredDescriptionDefault Value
GRAPHQL_METRICS_ENABLEDenabledfalsetrue
GRAPHQL_METRICS_COLLECTOR_ENDPOINTcollector_endpointtrueDefault endpointhttps://cosmo-metrics.wundergraph.com

Example YAML config:

{% code title="config.yaml" %}

version: "1"

graphql_metrics:
    enabled: true
    collector_endpoint: 'https://cosmo-metrics.wundergraph.com'

{% endcode %}

CORS

Environment VariableYAMLRequiredDescriptionDefault Value
CORS_ENABLEDenabledfalseSet this to enable/disable the CORS middleware. It is enabled by default. When disabled, the rest of the properties for CORS have no effect.true
CORS_ALLOW_ORIGINSallow_originsfalseThis is a list of origins which are allowed. You can provide origins with wildcards*
CORS_ALLOW_METHODSallow_methodsfalseHEAD,GET,POST
CORS_ALLOW_HEADERSallow_headersfalseOrigin,Content-Length,Content-Type
CORS_ALLOW_CREDENTIALSallow_credentialsfalsetrue
CORS_MAX_AGEmax_agefalse5m

Example YAML config:

{% code title="config.yaml" %}

version: "1"

cors:
  allow_origins: ["*"]
  allow_methods:
    - HEAD
    - GET
    - POST
  allow_headers:
    - Origin
    - Content-Length
    - Content-Type
  allow_credentials: true
  max_age: 5m

{% endcode %}

Cache Control Policy

Configure your cache control policy. More information on this feature can be found here: #cache-control-policy

Environment VariableYAMLRequiredDescriptionDefault Value
CACHE_CONTROL_POLICY_ENABLEDenabledfalseSet this to enable/disable the strict cache control policy. It is false by defaultfalse
CACHE_CONTROL_POLICY_VALUEvaluefalseThe default value for the cache control policy. It will be applied to all requests, unless a subgraph has a more strict one

Example YAML Config:

{% code title="config.yaml" %}

version: "1"

cache_control_policy:
  enabled: true
  value: "max-age=180, public"
  subgraphs:
    - name: "products"
      value: "max-age=60, public"
    - name: "pricing"
      value: "no-cache"

{% endcode %}

Custom Modules

Configure your custom Modules. More information on this feature can be found here: custom-modules.md

Example YAML config:

{% code title="config.yaml" %}

version: "1"

modules:
  myModule:
    # Arbitrary values, unmarshalled by the module
    value: 1

{% endcode %}

Headers

Configure Header propagation rules for all Subgraphs or individual Subgraphs by name.

Global Header Rules

Apply to requests/responses to/from "all" Subgraphs. These will be applied globally in the graph

Environment VariableYAMLRequiredDescriptionDefault Value
requestfalseList of Request Header Rules
responsefalseList of Response Header Rules

Example YAML config:

{% code title="config.yaml" %}

version: "1"

# Header manipulation
# See "https://cosmo-docs.wundergraph.com/router/proxy-capabilities" for more information
headers:
  all: # Header rules for all origin requests.
    request:
      - op: "propagate"
        named: X-Test-Header
      - op: "propagate"
        matching: (?i)^x-deprecated-.*
      - op: "set"
        name: "X-API-Key"
        value: "my-secret-value"
    response:
      - op: "propagate"
        algorithm: "append"
        named: "X-Custom-Header"

{% endcode %}

Request Header Rule

Apply to requests to specific Subgraphs.

Environment VariableYAMLRequiredDescriptionDefault Value
optrueoneof=propagate, set
matchingfalsematching is the regex to match the header name against
namedfalsenamed is the exact header name to match
renamefalserenames the header's key to the provided value
defaultfalsedefault is the default value to set if the header is not present
namefalseIf op is set, name is the name of the desired header to set
valuefalseIf op is set, value is the value of the desired header to set

Example YAML config:

{% code title="config.yaml" %}

version: "1"

# Header manipulation
# See "https://cosmo-docs.wundergraph.com/router/proxy-capabilities" for more information
headers:
  subgraphs:
    product: # Header rules for the "product" Subgraph
      request:
        - op: "propagate"
          named: X-Test-Header
        - op: "set"
          name: "X-API-Key"
          value: "my-secret-value"

{% endcode %}

Response Header Rule

These rules can be applied to all responses, as well as just to specific subgraphs, and used to manipulate and propagate response headers from subgraphs to the client. By configuring the rule, users can define how headers should be handled when multiple subgraphs provide conflicting values for a specific header.

Environment VariableYAMLRequiredDescriptionDefault Value
optrueoneof=propagate
algorithmtrueoneof=first_write, last_write, append
matchingfalsematching is the regex to match the header name against. This
namedfalsenamed is the exact header name to match
defaultfalsedefault is the default value to set if the header is not present
renamefalserenames the header's key to the provided value

Example YAML config:

{% code title="config.yaml" %}

version: "1"

# Header manipulation
# See "https://cosmo-docs.wundergraph.com/router/proxy-capabilities" for more information
headers:
  subgraphs:
    product: # Header rules for the "product" Subgraph
      response:
        - op: "propagate"
          algorithm: "append"
          named: "X-Test-Header"
        - op: "propagate"
          algorithm: "last_write"
          named: "X-Test2-Header"
        - op: "set"
          name: "X-User-Key"
          value: "my-user-value"

{% endcode %}

Storage Providers

The configuration for the storage providers. Storage providers can be used to store the persisted operations and the execution config.

Example YAML config:

{% code title="" %}

version: "1"

storage_providers:
  cdn:
    - url: https://cosmo-cdn.wundergraph.com
      id: cdn
  s3:
    - id: "s3"
      endpoint: "localhost:10000"
      bucket: "cosmo"
      access_key: "key"
      secret_key: "secret"
      region: us-east-1
      secure: false
  redis:
    - id: "my-redis"
      cluster_enabled: false
      urls: 
        - "redis://localhost:6379"

{% endcode %}

{% hint style="info" %} Users can supply a list of URLs for their redis storage provider.

  • If cluster_enabled: false , then we will use the first URL for the connection URL.
  • If cluster_enabled: true , then we will use all of the URLs for the Redis Cluster connection.

URLs can be supplied with redis configuration options embedded, such as:
redis://myUser:myPass@localhost:6379?ssl=true&db=1@connectTimeout=2 {% endhint %}

{% hint style="warning" %} Prior to [email protected], the redis configuration looks like:

  redis:
    - id: "my_redis"
      url: "redis://localhost:6379"

{% endhint %}

Storage Provider Yaml Options

These rules apply to requests being made from the Router to all Subgraphs.

Environment VariableYAMLRequiredDescriptionDefault Value
cdnfalseCDN storage provider.
cdn.idtrueUnique ID of the provider. It is used as reference in persisted_operations and execution_config sections.
cdn.urlfalse"https://cosmo-cdn.wundergraph.com"
redisfalseRedis storage provider
STORAGE_PROVIDER_REDIS_IDredis.idtrueUnique ID of the provider. It is used as a reference in the automatic_persisted_queries section
STORAGE_PROVIDER_REDIS_CLUSTER_ENABLEDredis.cluster_enabledfalseIf the Redis instance is a Redis cluster
STORAGE_PROVIDER_REDIS_URLSredis.urlstrueList of Redis urls, containing port and auth information if necessary. Must contain at least one element
s3falseS3 storage provider
s3.idtrueUnique ID of the privider. It is used as reference in persisted_operations and execution_config sections.
s3.endpointfalseThe endpoint of the S3 bucket. The endpoint is used to specify the endpoint of the S3 bucket.
s3.bucketfalseThe name of the S3 bucket. The S3 bucket is used to store the execution config.
s3.access_keyfalseThe access key of the S3 bucket. The access key ID is used to authenticate with the S3 bucket.
s3.secret_keyfalseThe secret key of the S3 bucket. The secret access key is used to authenticate with the S3 bucket.
s3.regionfalseThe region of the S3 bucket. The region is used to specify the region of the S3 bucket
s3.securefalseEnables https in the provided endpoint. Must be set to false when accessing http endpointstrue
false

Persisted Operations

The configuration for the persisted operations allows you to maintain a fixed set of GraphQL operations that can be queried against the router without exposing your entire graph to the public. This approach enhances security and performance.

Example YAML config:

{% code title="" %}

version: "1"

persisted_operations:
  cache: 
    size: 100MB
  storage: 
    provider_id: s3
    object_prefix: wundergraph

{% endcode %}

Persisted Operations Configuration Options

These rules apply to requests being made from the Router to all Subgraphs.

Environment VariableYAMLRequiredDescriptionDefault Value
persisted_operationsfalseThe configuration for the persisted operations.
persisted_operations.cachefalseLRU cache for persisted operations.
PERSISTED_OPERATIONS_CACHE_SIZEpersisted_operations.cache.sizefalseThe size of the cache in SI unit."100MB"
persisted_operations.storagefalseThe storage provider for persisted operation. Only one provider can be active. When no provider is specified, the router will fallback to the Cosmo CDN provider to download the persisted operations.
PERSISTED_OPERATIONS_STORAGE_PROVIDER_IDpersisted_operations.storage.provider_idtrueThe ID of the storage provider. The ID must match the ID of the storage provider in the storage_providers section.
PERSISTED_OPERATIONS_STORAGE_OBJECT_PREFIXpersisted_operations.storage.object_prefixtrueThe prefix of the object in the storage provider location. The prefix is put in front of the operation SHA256 hash. $prefix/SHA256.json

Automatic Persisted Queries

The configuration for automatic persisted queries allows you to enable automated caching of select GraphQL operations that can be queried against the router, using both POST and GET requests. This approach enhances performance.

It defaults to using a local cache (with the size defined in cache.size), but users can optionally use a Redis storage

Example YAML config:

{% code title="" %}

version: "1"

automatic_persisted_queries:
  enabled: true
  cache:
    size: 10MB # This is only relevant for an in-memory cache that we maintain
    ttl: 900 # in seconds, set both for a local and a remote KV
  storage:
    provider_id: "my_redis"
    object_prefix: cosmo_apq    

{% endcode %}

Configuration Options

These rules apply to requests being made from the Router to all Subgraphs.

Environment VariableYAMLRequiredDescriptionDefault Value
automatic_persisted_queriesfalseThe configuration for the persisted operations.
automatic_persisted_queries.enabledfalseWhether or not automatic persisted queries is enabledTrue
automatic_persisted_queries.cachefalseLRU cache for persisted operations.
automatic_persisted_queries.cache.sizefalseThe size of the cache in SI unit."100MB"
automatic_persisted_queries.cache.ttlfalseThe TTL of the cache, in seconds. Set to 0 to set no TTL
automatic_persisted_queries.storagefalseThe external storage provider (redis) for automatic persisted operation. Only one provider can be active. When no provider is specified, the router will fallback to using a local in-memory cache (configured in the automatic_persisted_queries.cache options)
automatic_persisted_queries.storage.provider_idtrueThe ID of the Redis storage provider. The ID must match the ID of the storage provider in the storage_providers.redis section.
automatic_persisted_queries.storage.object_prefixtrueThe prefix of the object in the storage provider location. The prefix is put in front of the operation SHA256 hash. $prefix/SHA256

Execution Config

The configuration for the execution setup contains instructions for the router to plan and execute your GraphQL operations. You can specify the storage provider from which the configuration should be fetched.

Example YAML config:

{% code title="" %}

version: "1"

execution_config:
  storage:
    provider_id: s3
    object_path: /prod

{% endcode %}

Subgraph Request Rules

These rules apply to requests being made from the Router to all Subgraphs.

Environment VariableYAMLRequiredDescriptionDefault Value
execution_configfalseThe configuration for the execution config.
filefalseThe configuration for the execution config file. The config file is used to load the execution config from the local file system. The file has precedence over the storage provider.
EXECUTION_CONFIG_FILE_PATHfile.pathfalseThe path to the execution config file. The path is used to load the execution config from the local file system.
EXECUTION_CONFIG_FILE_WATCHfile.watchfalseEnable the watch mode. The watch mode is used to watch the execution config file for changes. If the file changes, the router will reload the execution config without downtime."true"
execution_config.storagefalseThe storage provider for the execution config. Only one provider can be active. When no provider is specified, the router will fallback to the Cosmo CDN provider to download the execution config.
EXECUTION_CONFIG_STORAGE_PROVIDER_IDexecution_config.storage.provider_idtrueThe ID of the storage provider. The ID must match the ID of the storage provider in the storage_providers section.
EXECUTION_CONFIG_STORAGE_OBJECT_PATHexecution_config.storage.object_pathtrueThe path to the execution config in the storage provider. The path is used to download the execution config from the S3 bucket.
EXECUTION_CONFIG_FALLBACK_STORAGE_ENABLEDexecution_config.fallback_storage.enabledfalseEnable a fallback storage to fetch the execution config in case the above primary source fails.
EXECUTION_CONFIG_FALLBACK_STORAGE_PROVIDER_IDexecution_config.fallback_storage.provider_idfalseThe ID of the storage provider. The ID must match the ID of the storage provider in the storage_providers section.
EXECUTION_CONFIG_FALLBACK_STORAGE_OBJECT_PATHexecution_config.fallback_storage.object_pathfalseThe path to the execution config in the storage provider. The path is used to download the execution config from the S3 bucket.

Traffic Shaping

Configure rules for traffic shaping like maximum request body size, timeouts, retry behavior, etc. For more info, check this section in the docs: traffic-shaping

{% hint style="warning" %} When overriding traffic shaping rules for a subgraph, you must specify all options, as they do not fallback to global or default values. This will be fixed in a future release. {% endhint %}

Example YAML config:

{% code title="" %}

version: "1"

# Traffic configuration
# See "https://cosmo-docs.wundergraph.com/router/traffic-shaping" for more information
traffic_shaping:
  # Apply to all requests from clients to the router
  router:
    # Is the maximum size of the request body in MB, mib
    max_request_body_size: 5MB
    max_header_bytes: 1MiB
    decompression_enabled: true
  all: # Rules are applied to all subgraph requests.
    # Subgraphs transport options
    request_timeout: 60s
    dial_timeout: 30s
    tls_handshake_timeout: 0s
    response_header_timeout: 0s
    expect_continue_timeout: 0s
    keep_alive_idle_timeout: 0s
    keep_alive_probe_interval: 30s
    max_idle_conns: 1024
    max_conns_per_host: 100
    max_idle_conns_per_host: 20
    # Retry
    retry: # Rule is only applied to GraphQL operations of type "query"
      enabled: true
      algorithm: "backoff_jitter"
      max_attempts: 5
      interval: 3s
      max_duration: 10s
  subgraphs: # allows you to create subgraph specific traffic shaping rules
    products: # Will only affect this subgraph, and override the options in "all" for that subgraph
      request_timeout: 60s
      dial_timeout: 30s
      keep_alive_idle_timeout: 0s
      keep_alive_probe_interval: 
      tls_handshake_timeout: 10s
      response_header_timeout: 0s
      expect_continue_timeout: 0s
      max_idle_conns: 1024
      max_conns_per_host: 100
      max_idle_conns_per_host: 20

{% endcode %}

Subgraph Request Rules

These rules apply to requests being made from the Router to all Subgraphs.

Environment VariableYAMLRequiredDescriptionDefault Value
retryfalse#traffic-shaping-jitter-retry
request_timeouttrue60s
dial_timeoutfalse30s
response_header_timeoutfalse0s
expect_continue_timeoutfalse0s
tls_handshake_timeoutfalse10s
keep_alive_idle_timeoutfalse0s
keep_alive_probe_intervalfalse30s
max_idle_connsfalse1024
max_conns_per_hostfalse100
max_idle_conns_per_hostfalse20

Subgraph specific request rules

In addition to the general traffic shaping rules, we also allow users to set subgraph specific timeout options, overriding the default traffic rules defined in all(if present)

Environment VariableYAMLRequiredDescriptionDefault Value
request_timeoutfalse60s
dial_timeoutfalse30s
response_header_timeoutfalse0s
expect_continue_timeoutfalse0s
tls_handshake_timeoutfalse10s
keep_alive_idle_timeoutfalse0s
keep_alive_probe_intervalfalse30s
max_idle_connsfalse1024
max_conns_per_hostfalse100
max_idle_conns_per_hostfalse20

Jitter Retry

Environment VariableYAMLRequiredDescriptionDefault Value
RETRY_ENABLEDenabledfalsetrue
algorithmfalsebackoff_jitterbackoff_jitter
max_attemptstrue
max_durationtrue
intervaltrue

Client Request Request Rules

These rules apply to requests being made from clients to the Router.

Environment VariableYAMLRequiredDescriptionDefault Value
max_request_body_sizefalse5mb
MAX_HEADER_BYTESmax_header_bytesfalse

Minimum Router version: 0.156.0

The maximum size of the request headers. Setting this to 0 uses the default value from the http standard lib, which is 1MiB.

1mib
decompression_enabledfalse

When enabled, the router will check incoming requests for a 'Content-Encoding' header and decompress the body accordingly.

Note: Currently only "gzip" is supported

true

WebSocket

Configure WebSocket handlers, protocols, and more.

WebSocket Configuration

Environment VariableYAMLRequiredDescriptionDefault Value
WEBSOCKETS_ENABLEDenabledtruetrue
absinthe_protocolfalse#absinthe-protocol-configuration
forward_upgrade_headersfalseForward all useful Headers from the Upgrade Request, like User-Agent or Authorization in the extensions field when subscribing on a Subgraph
forward_upgrade_query_paramsfalseForward all query parameters from the Upgrade Request in the extensions field when subscribing on a Subgraph
WEBSOCKETS_FORWARD_INITIAL_PAYLOADforward_initial_payloadfalseForward the initial payload from a client subscription in the extensions field when subscribing on a Subgraphtrue

Absinthe Protocol Configuration

Legacy WebSocket clients that use the Absinthe protocol might not be able to send a Subprotocol Header. For such clients, you can use the Absinthe Endpoint which automatically chooses the Subprotocol for them so that no Subprotocol Header needs to be set.

Environment VariableYAMLRequiredDescriptionDefault Value
WEBSOCKETS_ABSINTHE_ENABLEDenabledfalsetrue
WEBSOCKETS_ABSINTHE_HANDLER_PATHhandler_pathfalseThe path to mount the Absinthe handler on/absinthe/socket

WebSocket Authentication

It's possible that Authentication for a WebSocket connection is not possible at the HTTP layer. In such a case, you can enable Authentication "from_initial_payload". This will extract a value from the "initial_payload" field in the first WebSocket message which is responsible for negotiating the protocol between client and server.

In addition, it's possible to export the extracted value into a Request Header, which allows the Router to propagate it using Header Propagation Rules in subsequent Subgraph Requests.

Example WebSocket YAML config:

{% code title="config.yaml" %}

version: "1"

websocket:
  enabled: true
  absinthe_protocol:
    enabled: true
    handler_path: /absinthe/socket
  forward_initial_payload: true
  forward_upgrade_headers:
    enabled: true
    allow_list: # an empty list allows all headers
      - "Authorization" # forward only the Authorization Header
  forward_upgrade_query_params:
    enabled: true
    allow_list:
      - "Authorization"
  authentication:
    # enable authentication from the initial payload
    from_initial_payload:
      enabled: false
      # which key to use one the initial payload to "extract" the Authorization value
      key: "authorization"
      export_token:
        export_token: false
        # to enable Subgraph authentication, we can export the value into a Header
        header_key: "Authorization"

{% endcode %}

Authentication

Configure different authentication providers.

New Authentication Config (Router Version ≥ 0.169.0)

JWKS

YAMLRequiredDescriptionDefault Value
urltrueThe URL of the JWKs. The JWKs are used to verify the JWT (JSON Web Token). The URL is specified as a string with the format 'scheme://host:port'.
refresh_intervalfalseThe interval at which the JWKs are refreshed. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.1m
algorithmsfalseThe allowed algorithms for the keys that are retrieved from the JWKs. An empty list means that all algorithms are allowed.

The following algorithms are supported
"HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512", "EdDSA"
[] (all allowed)

JWT

YAMLRequiredDescriptionDefault Value
header_namefalseThe name of the header. The header is used to extract the token from the request. The default value is 'Authorization'.Authorization
header_value_prefixfalseThe prefix of the header value. The prefix is used to extract the token from the header value. The default value is 'Bearer'.Bearer

Header Sources

YAMLRequiredDescriptionDefault Value
typetrueThe type of the source. The only currently supported type is 'header'.
nametrueThe name of the header. The header is used to extract the token from the request.
value_prefixesfalseThe prefixes of the header value. The prefixes are used to extract the token from the header value.

Example YAML config V2:

authentication:
  jwt:
    jwks:
      - url: "https://example.com/.well-known/jwks.json"
        refresh_interval: 1m
        # Leaving algorithms empty will allow all supported algorithms from the config docs
      - url: "https://example2.com/.well-known/jwks.json"
        refresh_interval: 2m
        # optional list of allowed algorithms per JWKS
        algorithms: ["RS256", "EdDSA", "HS512"]
    header_name: Authorization # This is the default value
    header_value_prefix: Bearer # This is the default value
    header_sources:
      - type: header 
        name: X-Auth-Token
        value_prefixes: [Token, MyToken]
      - type: header
        name: X-Authorization

Old Authentication Config (Router Version < 0.XXX.X)

Provider

Environment VariableYAMLRequiredDescriptionDefault Value
namefalseName of the provider
jwksfalseJWK Provider

JWK Provider

Environment VariableYAMLRequiredDescriptionDefault Value
urlfalse
header_namesfalse
header_value_prefixesfalse
refresh_intervaltrue1m

Example YAML config:

{% code title="config.yaml" %}

version: "1"

# Authentication and Authorization
# See https://cosmo-docs.wundergraph.com/router/authentication-and-authorization for more information  
authentication:
  providers:
    - name: My Auth Provider # Optional, used for error messages and diagnostics
      jwks: # JWKS provider configuration
        url: https://example.com/.well-known/jwks.json # URL to load the JWKS from
        header_name: Authorization # Optional
        header_value_prefix: Bearer # Optional

{% endcode %}

Authorization

Environment VariableYAMLRequiredDescriptionDefault Value
REQUIRE_AUTHENTICATIONrequire_authenticationfalseSet to true to disallow unauthenticated requestsfalse
REJECT_OPERATION_IF_UNAUTHORIZEDreject_operation_if_unauthorizedfalseIf enabled, the Router will return 401 with no response data when the evaluation of field-based permissions (authenticated.mdor requiresscopes.mdfails)false

Example YAML config:

{% code title="config.yaml" %}

version: "1"

authorization:
  require_authentication: false
  reject_operation_if_unauthorized: false

{% endcode %}

CDN

Environment VariableYAMLRequiredDescriptionDefault Value
CDN_URLurltrueThe URL of the CDN where the Router will fetch its Config. Not required when a static execution config is provided.https://cosmo-cdn.wundergraph.com
CDN_CACHE_SIZEcache_sizefalseCosmo Router caches responses from the CDN in memory, this defines the cache size.100MB

Example YAML config:

{% code title="config.yaml" %}

version: "1"

cdn:
   url: https://cosmo-cdn.wundergraph.com
   cache_size: 100MB

{% endcode %}

Events

The Events section lets you define Event Sources for event-driven-federated-subscriptions-edfs.

We support NATS and Kafka as event bus provider.

{% code title="config.yaml" %}

version: "1"

events:
  providers:
    nats:
      - id: default
        url: "nats://localhost:4222"
        authentication:
          token: "token" # or
          user_info:
            username: "username"
            password: "password"
    kafka:
      - id: my-kafka
        tls:
          enabled: true
        authentication:
          sasl_plain:
            password: "password"
            username: "username"
        brokers:
          - "localhost:9092"

{% endcode %}

Provider

Environment VariableYAMLRequiredDescriptionDefault Value
providertrueone of: nats, kafka

NATS Provider

Environment VariableYAMLRequiredDescriptionDefault Value
idtrueThe ID of the provider. This have to match with the ID specified in the subgraph schema.
urltrueNATS Connection string
authenticationfalseAuthentication configuration for the NATS provider.
authentication.tokenfalseToken based authentication.
authentication.user_infofalseUser-Info based authentication.
authentication.user_info.usernamefalseUsername.
authentication.user_info.passwordfalsePassword.

Kafka Provider

Environment VariableYAMLRequiredDescriptionDefault Value
idtrueThe ID of the provider. This have to match with the ID specified in the subgraph schema.
brokerstrueA list of broker URLs.[]
authenticationfalseAuthentication settings
authentication.sasl_plainfalseSASL/Plain Authentication method
authentication.sasl_plain.usernamefalseSASL/Plain Username
authentication.sasl_plain.passwordfalseSASL/Plain Password
tlsfalseTLS configuration for the Kafka provider. If enabled, it uses SystemCertPool for RootCAs by default.
tls.enabledfalseEnable the TLS.

Nats Provider

Router Engine Configuration

Configure the GraphQL Execution Engine of the Router.

Environment VariableYAMLRequiredDescriptionDefault Value
ENGINE_ENABLE_SINGLE_FLIGHTenable_single_flightfalseDeduplicate exactly the same in-flight origin requesttrue
ENGINE_ENABLE_REQUEST_TRACINGenable_request_tracingfalseEnable advanced-request-tracing-art.mdThis config is not correlated to OTEL tracing.true
ENGINE_ENABLE_EXECUTION_PLAN_CACHE_RESPONSE_HEADERenable_execution_plan_cache_response_headerfalseUsually only required for testing. When enabled, the Router sets the response Header "X-WG-Execution-Plan-Cache" to "HIT" or "MISS"false
ENGINE_MAX_CONCURRENT_RESOLVERSmax_concurrent_resolversfalseUse this to limit the concurrency in the GraphQL Engine. A high number will lead to more memory usage. A number too low will slow down your Router.32
ENGINE_ENABLE_NET_POLLenable_net_pollfalseEnables the more efficient poll implementation for all WebSocket implementations (client, server) of the router. This is only available on Linux and MacOS. On Windows or when the host system is limited, the default synchronous implementation is used.true
ENGINE_WEBSOCKET_CLIENT_POLL_TIMEOUTwebsocket_client_poll_timeoutfalseThe timeout for the poll loop of the WebSocket client implementation. The period is specified as a string with a number and a unit1s
ENGINE_WEBSOCKET_CLIENT_CONN_BUFFER_SIZEwebsocket_client_conn_buffer_sizefalseThe buffer size for the poll buffer of the WebSocket client implementation. The buffer size determines how many connections can be handled in one loop.128
ENGINE_WEBSOCKET_CLIENT_READ_TIMEOUTwebsocket_client_read_timeoutfalseThe timeout for the websocket read of the WebSocket client implementation.5s
ENGINE_EXECUTION_PLAN_CACHE_SIZEexecution_plan_cache_sizefalseDefine how many GraphQL Operations should be stored in the execution plan cache. A low number will lead to more frequent cache misses, which will lead to increased latency.1024
ENGINE_MINIFY_SUBGRAPH_OPERATIONSminify_subgraph_operationsfalseMinify the subgraph operations. If the value is true, GraphQL Operations get minified after planning. This reduces the amount of GraphQL AST nodes the Subgraph has to parse, which ultimately saves CPU time and memory, resulting in faster response times.false
ENGINE_ENABLE_PERSISTED_OPERATIONS_CACHEenable_persisted_operations_cachefalseEnable the persisted operations cache. The persisted operations cache is used to cache normalized persisted operations to improve performance.true
ENGINE_ENABLE_NORMALIZATION_CACHEenable_normalization_cachefalseEnable the normalization cache. The normalization cache is used to cache normalized operations to improve performance.true
ENGINE_NORMALIZATION_CACHE_SIZEnormalization_cache_sizefalseThe size of the normalization cache.1024
ENGINE_PARSEKIT_POOL_SIZEparsekit_pool_sizefalseThe size of the ParseKit pool. The ParseKit pool provides re-usable Resources for parsing, normalizing, validating and planning GraphQL Operations. Setting the pool size to a value much higher than the number of CPU Threads available will not improve performance, but only increase memory usage.8
ENGINE_RESOLVER_MAX_RECYCLABLE_PARSER_SIZEresolver_max_recyclable_parser_sizefalseLimits the size of the Parser that can be recycled back into the Pool. If set to 0, no limit is applied. This helps keep the Heap size more maintainable if you regularly perform large queries.32768
ENGINE_ENABLE_VALIDATION_CACHEenable_validation_cachefalseEnable the validation cache. The validation cache is used to cache results of validating GraphQL Operations.true
ENGINE_VALIDATION_CACHE_SIZEvalidation_cache_sizefalseThe size of the validation cache.1024
ENGINE_ENABLE_SUBGRAPH_FETCH_OPERATION_NAMEenable_subgraph_fetch_operation_namefalseEnable appending the operation name to subgraph fetches. This will ensure that the operation name will be included in the corresponding subgraph requests using the following format: $operationName__$subgraphName__$sequenceID.true

Example YAML config:

{% code title="config.yaml" %}

version: "1"

engine:
  enable_single_flight: true
  enable_request_tracing: true
  enable_execution_plan_cache_response_header: false
  max_concurrent_resolvers: 32
  enable_websocket_epoll_kqueue: true
  epoll_kqueue_poll_timeout: "1s"
  epoll_kqueue_conn_buffer_size: 128
  websocket_read_timeout: "1s"
  execution_plan_cache_size: 10000
  minify_subgraph_operations: true
  enable_persisted_operations_cache: true
  enable_normalization_cache: true
  normalization_cache_size: 1024
  parsekit_pool_size: 8
  enable_validation_cache: true
  validation_cache_size: 1024
  enable_subgraph_fetch_operation_name: true

{% endcode %}

Debug Configuration

Environment VariableYAMLRequiredDescriptionDefault Value
ENGINE_DEBUG_PRINT_OPERATION_TRANSFORMATIONSprint_operation_transformationsfalsePrint the operation transformations.false
ENGINE_DEBUG_PRINT_OPERATION_ENABLE_AST_REFSprint_operation_enable_ast_refsfalsePrint the operation enable AST refs.false
ENGINE_DEBUG_PRINT_PLANNING_PATHSprint_planning_pathsfalsePrint the planning paths.false
ENGINE_DEBUG_PRINT_QUERY_PLANSprint_query_plansfalsePrint the query plans.false
ENGINE_DEBUG_PRINT_NODE_SUGGESTIONSprint_node_suggestionsfalsePrint the node suggestions.false
ENGINE_DEBUG_CONFIGURATION_VISITORconfiguration_visitorfalsePrint the configuration visitor.false
ENGINE_DEBUG_PLANNING_VISITORplanning_visitorfalsePrint the planning visitor.false
ENGINE_DEBUG_DATASOURCE_VISITORdatasource_visitorfalsePrint the datasource visitor.false
ENGINE_DEBUG_REPORT_WEBSOCKET_CONNECTIONSreport_websocket_connectionsfalsePrint the websocket connections.false
ENGINE_DEBUG_REPORT_MEMORY_USAGEreport_memory_usagefalsePrint the memory usage.false
ENGINE_DEBUG_ENABLE_RESOLVER_DEBUGGINGenable_resolver_debuggingfalseEnable verbose debug logging for the Resolver.false
ENGINE_DEBUG_ENABLE_PERSISTED_OPERATIONS_CACHE_RESPONSE_HEADERenable_persisted_operations_cache_response_headerfalseEnable the persisted operations cache response header. The persisted operations cache response header is used to cache the persisted operations in the client.false
ENGINE_DEBUG_ENABLE_NORMALIZATION_CACHE_RESPONSE_HEADERenable_normalization_cache_response_headerfalseEnable the normalization cache response header. The normalization cache response header is used to cache the normalized operations in the client.false
ENGINE_DEBUG_ALWAYS_INCLUDE_QUERY_PLANalways_include_query_planfalseAlways include the query plan in the response.false
ENGINE_DEBUG_ALWAYS_SKIP_LOADERalways_skip_loaderfalseAlways skip the loader. This will return no data but only render response extensions, e.g. to expose the query plan.false

Example YAML config:

{% code title="config.yaml" %}

version: "1"

engine:
  debug:
    print_operation_transformations: false
    print_operation_enable_ast_refs: false
    print_planning_paths: false
    print_query_plans: false
    print_node_suggestions: false
    configuration_visitor: false
    planning_visitor: false
    datasource_visitor: false
    report_websocket_connections: false
    report_memory_usage: false
    enable_resolver_debugging: false
    enable_persisted_operations_cache_response_header: false
    enable_normalization_cache_response_header: false
    always_include_query_plan: false
    always_skip_loader: false

{% endcode %}

Rate Limiting

Configures a rate limiter on the outgoing subgraphs requests. When enabled, a rate of 10 req/s with a burst of 10 requests is configured.

{% hint style="info" %} The rate limiter requires Redis version 3.2 or newer since it relies on replicate_commands feature. ElastiCache for Redis only works in non-clustered mode. You can enable a failover instance to achieve high availability. {% endhint %}

Key Suffix Expression

As you can see in the config table below, you can define an expression to generate the a rate limiting key suffix. The evaluation of the expression must return a string, which will be appended to the key prefix.

Using a key suffix expression, you're able to dynamically choose a rate limiting key, e.g. based on the user authentication, a header, or a combination. Here's an example expression that uses the sub claim if available, and a Header as the fallback.

request.auth.claims.sub ?? request.header.Get('X-Forwarded-For')

For mor information on how to use the expression language, please refer to the template-expressions.mdsection.

General Rate Limiting Configuration

Environment VariableYAMLRequiredDescriptionDefault Value
RATE_LIMIT_ENABLEDenabledfalseEnable / Disable rate limiting globallyfalse
RATE_LIMIT_STRATEGYstrategytrueThe rate limit strategysimple
simple_strategyfalse#rate-limiting-simple-strategy
storagefalse#rate-limiting-redis-storage
RATE_LIMIT_KEY_SUFFIX_EXPRESSIONkey_suffix_expressionfalseThe expression to define a key suffix for the rate limit, e.g. by using request headers, claims, or a combination of both with a fallback strategy. The expression is specified as a string and needs to evaluate to a string. Please see https://expr-lang.org/ for more information.
error_extension_codefalse#rate-limit-error-extension-code

Rate Limiting Redis Storage

Environment VariableYAMLRequiredDescriptionDefault Value
RATE_LIMIT_REDIS_URLurlstrueList of the connection URL(s).[redis://localhost:6379]
RATE_LIMIT_REDIS_CLUSTER_ENABLEDcluster_enabledfalseIf the Redis instance is a Redis clusterfalse
RATE_LIMIT_REDIS_KEY_PREFIXkey_prefixfalseThis prefix is used to namespace the ratelimit keyscosmo_rate_limit

Rate Limiting Simple Strategy

Environment VariableYAMLRequiredDescriptionDefault Value
RATE_LIMIT_SIMPLE_RATEratetrueAllowed request rate (number)10
RATE_LIMIT_SIMPLE_BURSTbursttrueAllowed burst rate (number) - max rate per one request10
RATE_LIMIT_SIMPLE_PERIODperiodtrueThe rate limiting period, e.g. "10s", "1m", etc...1s
RATE_LIMIT_SIMPLE_REJECT_EXCEEDING_REQUESTSreject_exceeding_requestsfalseReject the complete request if a sub-request exceeds the rate limit. If set to false, partial responses are possible.false
RATE_LIMIT_SIMPLE_HIDE_STATS_FROM_RESPONSE_EXTENSIONhide_stats_from_response_extensionfalseHide the rate limit stats from the response extension. If the value is true, the rate limit stats are not included in the response extension.false

Rate Limit Error Extension Code

Environment VariableYAMLRequiredDescriptionDefault Value
RATE_LIMIT_ERROR_EXTENSION_CODE_ENABLEDenabledfalseIf enabled, a code will be added to the extensions.code field of error objects related to rate limiting. This allows clients to easily identify if an error happened due to rate limiting.true
RATE_LIMIT_ERROR_EXTENSION_CODEcodefalseThe error extension code for the rate limit.RATE_LIMIT_EXCEEDED

Rate Limiting Example YAML configuration

rate_limit:
    enabled: true
    strategy: "simple"
    simple_strategy:
        rate: 10
        burst: 10
        period: 1s
        reject_exceeding_requests: false
        reject_status_code: 200
        hide_stats_from_response_extension: false
    storage:
        cluster_enabled: false
        urls: 
         - "redis://localhost:6379"
        key_prefix: "cosmo_rate_limit"
    debug: false
    key_suffix_expression: ""
    error_extension_code:
        enabled: true
        code: "RATE_LIMIT_EXCEEDED"

Subgraph Error Propagation

The configuration for the subgraph error propagation. Errors can be exposed to the client in a "wrapped" form to hide Subgraph internals, or it's possible to "pass-through" Subgraph errors directly to the client.

Environment VariableYAMLRequiredDescriptionDefault Value
SUBGRAPH_ERROR_PROPAGATION_ENABLEDenabledfalseEnable error propagation. If the value is true (default: false), Subgraph errors will be propagated to the client.false
SUBGRAPH_ERROR_PROPAGATION_MODEmodefalseThe mode of error propagation. The supported modes are 'wrapped' (default) and 'pass-through'. The 'wrapped' mode wraps the error in a custom error object to hide internals. The 'pass-through' mode returns the error as is from the Subgraph.wrapped
SUBGRAPH_ERROR_PROPAGATION_REWRITE_PATHSrewrite_pathsfalseRewrite the paths of the Subgraph errors. If the value is true (default), the paths of the Subgraph errors will be rewritten to match the Schema of the Federated Graph.true
SUBGRAPH_ERROR_PROPAGATION_OMIT_LOCATIONSomit_locationsfalseOmit the location field of Subgraph errors. If the value is true, the location field of Subgraph errors will be omitted. This is useful because the locations of a Subgraph error is internal to the Subgraph and not relevant to the client.true
SUBGRAPH_ERROR_PROPAGATION_OMIT_EXTENSIONSomit_extensionsfalseOmit the extensions field of Subgraph errors. If the value is true, the extensions field of Subgraph errors will be omitted. This is useful in case you want to avoid leaking internal information to the client. Some users of GraphQL leverage the errors.extensions.code field to implement error handling logic in the client, in which case you might want to set this to false.false
SUBGRAPH_ERROR_PROPAGATION_STATUS_CODESpropagate_status_codesfalsePropagate Subgraph status codes. If the value is true, Subgraph Response status codes will be propagated to the client in the errors.extensions.code field.false
SUBGRAPH_ERROR_PROPAGATION_ALLOWED_FIELDSallowed_fieldsfalseIn passthrough mode, by default only message and path is propagated. You can specify additional fields here.
SUBGRAPH_ERROR_PROPAGATION_DEFAULT_EXTENSION_CODEdefault_extension_codefalseThe default extension code. The default extension code is used to specify the default code for the Subgraph errors when the code is not present.DOWNSTREAM_SERVICE_ERROR
SUBGRAPH_ERROR_PROPAGATION_ATTACH_SERVICE_NAMEattach_service_namefalseAttach the service name to each Subgraph error. If the value is true, the service name will be attached to the Subgraph errors.true
SUBGRAPH_ERROR_PROPAGATION_ALLOWED_EXTENSION_FIELDSallowed_extension_fieldsfalseThe allowed extension fields. The allowed extension fields are used to specify which fields of the Subgraph errors are allowed to be propagated to the client.["code"]

Example YAML configuration:

version: "1"

subgraph_error_propagation:
    enabled: true
    propagate_status_codes: false
    mode: "wrapped"
    rewrite_paths: true
    omit_locations: true
    omit_extensions: false
    default_extension_code: DOWNSTREAM_SERVICE_ERROR
    attach_service_name: true
    allowed_extension_fields:
      - "code"

Security

The configuration for the security. The security is used to configure the security settings for the Router.

Environment VariableYAMLRequiredDescriptionDefault Value
SECURITY_BLOCK_MUTATIONSblock_mutationsfalseBlock mutation Operations.
SECURITY_BLOCK_MUTATIONS_ENABLEDblock_mutations.enabledfalseIf the value is true, the mutations are blocked.false
SECURITY_BLOCK_MUTATIONS_CONDITIONblock_mutations.conditionfalseThe expression to evaluate if the operation should be blocked.
SECURITY_BLOCK_SUBSCRIPTIONSblock_subscriptionsfalseBlock subscription Operations.
block_subscriptions.enabledfalseIf the value is true, the subscriptions are blocked.false
block_subscriptions.conditionfalseThe expression to evaluate if the operation should be blocked.
SECURITY_BLOCK_NON_PERSISTED_OPERATIONSblock_non_persisted_operationsfalseBlock non-persisted Operations.
SECURITY_BLOCK_NON_PERSISTED_OPERATIONS_ENABLEDblock_non_persisted_operations.enabledfalseIf the value is true, the non-persisted operations are blocked.false
SECURITY_BLOCK_NON_PERSISTED_OPERATIONS_CONDITIONblock_non_persisted_operations.conditionfalseThe expression to evaluate if the operation should be blocked.
complexity_calculation_cachefalseComplexity Cache configuration
complexity_limitsfalseComplexity limits configuration

Example YAML Configuration

version: "1"

security:
    block_mutations:
      enabled: false
      condition: "request.header.Get('x-block-mutation') == 'yes'"
    block_subscriptions:
      enabled: false
    block_non_persisted_operations:
      enabled: false
    complexity_calculation_cache: # This is for a local in-memory cache, to persist the calculation results
      enabled: true
      size: 1024
    complexity_limits:
        depth: # the equivalent of `security.depth_limit` prevoiusly
          enabled: true
          limit: 7
          ignore_persisted_operations: true
        total_fields:
          enabled: true
          limit: 128
          ignore_persisted_operations: true
        root_fields:
          enabled: true
          limit: 3
          ignore_persisted_operations: true
        root_field_aliases:
          enabled: false
          limit: 3
          ignore_persisted_operations: true

{% hint style="danger" %} Query Depth is now deprecated. We recommend using the security.complexity_calculation_cache and security.complexity_limits configurations instead, which provide that functionality. {% endhint %}

Complexity Calculation Cache

The configuration for the in-memory complexity cache, to help speed up the calculation process in the event of a recurring query

Environment VariableYAMLRequiredDescriptionDefault Value
SECURITY_COMPLEXITY_CACHE_ENABLEDenabledfalseEnable the complexity cachefalse
SECURITY_COMPLEXITY_CACHE_SIZEsizefalseThe size of the complexity cache1024

Complexity Limits

The configuration for adding a complexity limits for queries. We currently expose 4 limits:

  • Query Depth - How many nested levels you can have in a query. This limit prevents infinite querying, and also limits the size of the data returned.
  • Total Fields in Query
  • Root Fields in Query
  • Root Field Aliases in Query

For all of the limits, if the limit is 0, or enabled isn't true, the limit isn't applied. All of them have the same configuration fields:

Environment VariableYAMLRequiredDescriptionDefault Value
enabledfalseEnable the specific limit. If the value is true (default: false), and a valid limit value is set, the limit will be appliedfalse
limitfalseThe limit amount for query. If the limit is 0, this limit isn't applied0
ignore_persisted_operationsfalseDisable the limit for persisted operations. Since persisted operations are stored intentionally, users may want to disable the limit to consciously allow nested persisted operationsfalse

File Upload

The configuration for file upload. Configure whether it should be enabled along with file size and number of files.

Environment VariableYAMLRequiredDescriptionDefault Value
FILE_UPLOAD_ENABLEDenabledfalseWhether the feature is enabled or nottrue
FILE_UPLOAD_MAX_FILE_SIZEmax_file_sizefalseThe maximum size of a file that can be uploaded. The size is specified as a string with a number and a unit, e.g. 10KB, 1MB, 1GB. The supported units are 'KB', 'MB', 'GB'.50MB
FILE_UPLOAD_MAX_FILESmax_filesfalseThe maximum number of files that can be uploaded per request.10

Example YAML Configuration

version: "1"

file_upload:
    enabled: true
    max_file_size: 1GB
    max_files: 2

Client Header

The configuration for custom names for client name and client version headers.

Environment VariableYAMLRequiredDescriptionDefault Value
namefalseThe custom name of the client name header.
versionfalseThe custom name of the client version header.

Example YAML Configuration

version: "1"

client_header:
  name: "Client-Name"
  version: "Client-Version"

By default, we support Graphql-Client-Name , Graphql-Client-Version, Apollo-Graphql-Client-Name, Apollo-Graphql-Client-Version.

The custom names are given more precedence.

Apollo Compatibility Flags

This configuration is used to enable full compatibility with Apollo Federation, Apollo Gateway and Apollo Router, you can enable certain compatibility flags, allowing you to use Cosmo Router as a drop-in replacement for Apollo.

Apollo Compatibility Value Completion

Invalid __typename values will be returned in extensions.valueCompletion instead of errors.

Apollo Compatibility Truncate Floats

Truncate floats like 1.0 to 1, 2.0 to 2, etc.. Values like 1.1 or 2.2 will not be truncated.

Apollo Compatibility Suppress Fetch Errors

Suppresses fetch errors. When enabled, only the ‘data’ object is returned, suppressing errors. If disabled, fetch errors are included in the ‘errors’ array.

Apollo Compatibility Replace Undefined Op Field Errors

Produces the same error message as Apollo when an invalid operation field is included in an operation selection set.
Extension code: "GRAPHQL_VALIDATION_FAILED"
Status code: 400

Apollo Compatibility Replace Invalid Var Errors

Produces the same error message as Apollo when an invalid variable is supplied.
Extension code: "BAD_USER_INPUT"

Environment VariableYAMLRequiredDescriptionDefault Value
APOLLO_COMPATIBILITY_ENABLE_ALLapollo_compatibility_flags:
enable_all: <bool>
falseEnables all the options of Apollo Compatibility.false
APOLLO_COMPATIBILITY_VALUE_COMPLETION_ENABLEDvalue_completion:
enabled: <bool>
falseEnables value completion.false
APOLLO_COMPATIBILITY_TRUNCATE_FLOATS_ENABLEDtruncate_floats:
enabled: <bool>
falseEnables truncate floats.false
APOLLO_COMPATIBILITY_SUPPRESS_FETCH_ERRORS_ENABLEDsuppress_fetch_errors:
enabled: <bool>
falseEnables suppress fetch errors.false
APOLLO_COMPATIBILITY_REPLACE_UNDEFINED_OP_FIELD_ERRORS_ENABLEDreplace_undefined_op_field_errors:
enabled: <bool>
falseReplaces undefined operation field errors.false
APOLLO_COMPATIBILITY_REPLACE_INVALID_VAR_ERRORS_ENABLEDreplace_invalid_var_errors:
enabled: <bool>
falseReplaces invalid variable errors.false

Example YAML Configuration

version: "1"

apollo_compatibility_flags:
    enable_all: false
    value_completion:
        enabled: true
    truncate_floats:
        enabled: false
    suppress_fetch_errors:
        enabled: true
    replace_undefined_op_field_errors:
        enabled: true
    replace_invalid_var_errors:
        enabled: true 

Cache warmer

Environment VariableYAMLRequiredDescriptionDefault Value
enabledfalseSet to true to enable the cache warmer.false
workersfalseThe number of workers for the cache warmup to run in parallel. Higher numbers decrease the time to warm up the cache but increase the load on the system.8
items_per_secondfalseThe number of cache warmup items to process per second. Higher numbers decrease the time to warm up the cache but increase the load on the system.50
timeoutfalseThe timeout for warming up the cache. This can be used to limit the amount of time cache warming will block deploying a new config. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.30s
sourcefalseThe source of the cache warmup items. Only one can be specified. If empty, the cache warmup source is the Cosmo CDN and it requires a graph to be set.

Example YAML config:

{% code title="config.yaml" %}

version: "1"

cache_warmup:
  enabled: true
  workers: 8
  items_per_second: 50
  timeout: 30s

{% endcode %}

Source

The source of the cache warmup items. Only one can be specified. If empty, the cache warmup source is the Cosmo CDN and it requires a graph to be set.

Environment VariableYAMLRequiredDescriptionDefault Value
pathfalseThe path to the directory containing the cache warmup items.

Example YAML config:

{% code title="config.yaml" %}

version: "1"

cache_warmup:
  enabled: true
  workers: 8
  items_per_second: 50
  timeout: 30s
  source:
    path: "./cache-warmer/operations"

{% endcode %}