From f3dc1cc7d47053eeba98e2c709e9edd749106409 Mon Sep 17 00:00:00 2001 From: Kiryl Mialeshka <8974488+meskill@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:20:53 +0100 Subject: [PATCH] docs: refactor to runtime configuration (#571) * docs: explain how linked config are merged * move runtime directives to config folder * migrate documentation to runtime config * fix references * add introduction doc to runtime configuration --- docs/N+1.md | 2 +- docs/apollo-federation-subgraph.md | 2 +- docs/apollo-studio.md | 2 +- docs/auth.md | 8 +- docs/client-tuning.md | 2 +- docs/{directives/link.md => config/links.md} | 215 ++++++++----- docs/{directives => config}/server.md | 315 ++++++++----------- docs/{directives => config}/telemetry.md | 163 ++++------ docs/config/upstream.md | 183 +++++++++++ docs/directives.md | 4 - docs/directives/http.md | 2 +- docs/directives/protected.md | 2 +- docs/directives/upstream.md | 223 ------------- docs/grpc.md | 6 +- docs/http2.md | 2 +- docs/rest.md | 2 +- docs/runtime-config.md | 52 +++ docs/scripting.md | 8 +- docs/telemetry.md | 6 +- sidebars.ts | 10 +- 20 files changed, 598 insertions(+), 611 deletions(-) rename docs/{directives/link.md => config/links.md} (62%) rename docs/{directives => config}/server.md (68%) rename docs/{directives => config}/telemetry.md (69%) create mode 100644 docs/config/upstream.md delete mode 100644 docs/directives/upstream.md create mode 100644 docs/runtime-config.md diff --git a/docs/N+1.md b/docs/N+1.md index 9b30f1dbad..d9688e7f35 100644 --- a/docs/N+1.md +++ b/docs/N+1.md @@ -176,7 +176,7 @@ If you run the query, at first you will observe a lot of duplicate requests are ![Duplicate Upstream Calls](../static/images/docs/n+1-duplicate.png) -This happens because of the 100 posts, a lot them are authored by the same user and by default Tailcall will make a request for every user when requested. You can fix this by setting [dedupe](./directives/graphQL.md#dedupe) to `true` in [server](./directives/server.md). +This happens because of the 100 posts, a lot them are authored by the same user and by default Tailcall will make a request for every user when requested. You can fix this by setting [dedupe](./directives/graphQL.md#dedupe) to `true` in [server](./config/server.md). ```graphql {3} schema diff --git a/docs/apollo-federation-subgraph.md b/docs/apollo-federation-subgraph.md index c56e32302d..8826dbe65f 100644 --- a/docs/apollo-federation-subgraph.md +++ b/docs/apollo-federation-subgraph.md @@ -40,7 +40,7 @@ Please, note that you don't need to specify the `@key` directive manually when d ## Enable federation in the Tailcall config -Federation is controlled by the flag [`enableFederation`](./directives/server.md#enablefederation). Define it with `true` value to enable federation support. +Federation is controlled by the flag [`enableFederation`](./config/server.md#enablefederation). Define it with `true` value to enable federation support. ## Register your subgraph diff --git a/docs/apollo-studio.md b/docs/apollo-studio.md index 4f878a8a36..421f158a80 100644 --- a/docs/apollo-studio.md +++ b/docs/apollo-studio.md @@ -34,7 +34,7 @@ This guide illustrates how to configure `tailcall` to send usage metrics to [Apo ![local-schema.png](../static/images/apollo-studio/local-schema.png) -You have now created a Monolith graph in Apollo Studio. The next step is to configure `tailcall` to use the `APOLLO_API_KEY` and `APOLLO_GRAPH_REF`. Follow detailed instructions [here](./directives/telemetry.md). +You have now created a Monolith graph in Apollo Studio. The next step is to configure `tailcall` to use the `APOLLO_API_KEY` and `APOLLO_GRAPH_REF`. Follow detailed instructions [here](./config/telemetry.md). ## Checking the metrics in Apollo Studio diff --git a/docs/auth.md b/docs/auth.md index c9efa82534..0179f2605f 100644 --- a/docs/auth.md +++ b/docs/auth.md @@ -46,7 +46,7 @@ to know more about how to use it, read the following articles: Enabling support for authentication in Tailcall could be done in two steps: -1. With the help of [`@link` directive](./directives/link.md) connect multiple authentication files as you need for different provides. To connect it use either [`Htpasswd`](./directives/link.md#htpasswd) or [`Jwks`](./directives/link.md#jwks) link type +1. With the help of [`@link` directive](./config/links.md) connect multiple authentication files as you need for different provides. To connect it use either [`Htpasswd`](./config/links.md#htpasswd) or [`Jwks`](./config/links.md#jwks) link type 2. Mark that some type of field requires authentication to be fetched with the help of [`@protected` directive](./directives/protected.md) Your config could look like this now: @@ -250,7 +250,7 @@ In case you linked multiple authentication files all of them will be used to exe ### Authentication headers -To validate authentication for user request the specific headers are used (like `Authorization` header). In case auth is enabled for tailcall those headers will be also added to the [`allowedHeaders` list](./directives/upstream.md#allowedheaders) and therefore they will be forwarded to the upstream requests implicitly. +To validate authentication for user request the specific headers are used (like `Authorization` header). In case auth is enabled for tailcall those headers will be also added to the [`allowedHeaders` list](./config/upstream.md#allowedheaders) and therefore they will be forwarded to the upstream requests implicitly. ## Basic Authentication @@ -270,7 +270,7 @@ Since this file stores secure information make sure to hash the password you use ### Basic Auth GraphQL Configuration -To use Basic Auth you should first include htpasswd file generated from [Prerequisites](#prerequisites) with the help of [`@link` directive](./directives/link.md#htpasswd). +To use Basic Auth you should first include htpasswd file generated from [Prerequisites](#prerequisites) with the help of [`@link` directive](./config/links.md#htpasswd). We can use that file as an example for it that has data for `testuser:mypassword` credentials in encrypted format: @@ -353,7 +353,7 @@ To create this file you can use available web-tools like [JWK creator](https://r ### JWT Auth GraphQL Configuration -To use JWT you should first include JWKS file generated from [Prerequisites](#prerequisites) with the help of [`@link` directive](./directives/link.md#jwks). +To use JWT you should first include JWKS file generated from [Prerequisites](#prerequisites) with the help of [`@link` directive](./config/links.md#jwks). We can use that file as an example for it: diff --git a/docs/client-tuning.md b/docs/client-tuning.md index 70eb34d5d2..e4402814e0 100644 --- a/docs/client-tuning.md +++ b/docs/client-tuning.md @@ -50,7 +50,7 @@ Connection pooling mitigates these issues by reusing existing connections for re ## Tuning HTTP Client -Tailcall uses connection pooling by default and sets up with default tuning suitable for most use cases. You might need to further tune the HTTP client to improve your application's performance. Tailcall DSL provides a directive named [`@upstream`](./directives/upstream.md) for this purpose. +Tailcall uses connection pooling by default and sets up with default tuning suitable for most use cases. You might need to further tune the HTTP client to improve your application's performance. Tailcall DSL provides a directive named [`@upstream`](./config/upstream.md) for this purpose. :::note Connection pooling optimizes HTTP/1. Since HTTP/2 and HTTP/3 support multiplexing, pooling enabled does not noticeably affect performance. diff --git a/docs/directives/link.md b/docs/config/links.md similarity index 62% rename from docs/directives/link.md rename to docs/config/links.md index d5a4a05a07..00f61989db 100644 --- a/docs/directives/link.md +++ b/docs/config/links.md @@ -1,60 +1,28 @@ --- -title: "@link" -description: The @link directive is used for bringing external resources into your GraphQL schema. -slug: ../link-directive +title: "links" +description: The links configuration is used for bringing external resources into your GraphQL schema. +slug: ../links-config --- -The `@link` directive is defined as follows: - -```graphql title="Directive Definition" showLineNumbers -directive @link( - """ - Source path or URL of the external resource - """ - src: String! - - """ - Type of the external resource - """ - type: LinkType! - - """ - Optional identifier for the link - """ - id: String - - """ - Optional headers for gRPC reflection server requests - """ - headers: [InputKeyValue!] - - """ - Optional directories to search for imported proto files. - """ - proto_paths: [String!] -) on SCHEMA - -""" -Available types for external resources -""" -enum LinkType { - Config - Protobuf - Script - Cert - Key - Operation - Htpasswd - Jwks - Grpc -} +The `links` configuration is defined in a YAML file as follows: + +```yaml title="Runtime Configuration" showLineNumbers +links: + - src: "path_or_url_of_external_resource" + type: "LinkType" + id: "optional_identifier" + headers: + - key: "header_key" + value: "header_value" + protoPaths: + - "path to proto" ``` -The `@link` directive is used for bringing external resources into your GraphQL schema. It makes it easier to include configurations, .proto files for gRPC services, and other files into your schema. With this directive, external resources are either merged with or used effectively in the importing configuration. +The `links` configuration is used for bringing external resources into your GraphQL schema. It makes it easier to include configurations, .proto files for gRPC services, and other files into your schema. With this configuration, external resources are either merged with or used effectively in the importing configuration. ## How it Works -The `@link` directive requires specifying a source `src`, the resource's type `type`, and an optional identifier `id`. +The `links` configuration requires specifying a source `src`, the resource's type `type`, and an optional identifier `id` for every entry: - `src`: The source of the link is defined here. It can be either a URL or a file path. When a file path is given, it's relative to the file's location that is importing the link. (This field also supports Mustache template) @@ -66,20 +34,116 @@ The `@link` directive requires specifying a source `src`, the resource's type `t - `proto_paths`: This is an optional field that specifies additional directories to search for imported proto files. It only takes effect when `type` is `Protobuf`. +### Linking other configs + +With `links` you can link [schema files](#config) that will be merged together. + +The schema definitions (i.e. types, unions, enums) are merged by the [federation composition rules](https://www.apollographql.com/docs/graphos/reference/federation/composition-rules) + +For example, consider the following files: + +```yaml title="Runtime Config" +server: + port: 8000 + +upstream: + httpCache: 10 + batch: + delay: 10 + +links: + - src: a.graphql + type: Config + - src: b.graphql + type: Config +``` + +```graphql title="a.graphql" +schema { + query: Query +} + +type User { + id: Int + age: Int +} + +union Media = Book | Movie + +type Query { + media: media + @http(url: "http://jsonplaceholder.typicode.com/media") +} +``` + +```graphql title="b.graphql" +schema { + query: Query +} + +type Query { + user(id: Int!): User + @http( + url: "http://jsonplaceholder.typicode.com/users/{{.args.id}}" + ) +} + +union Media = Book | Podcast + +type User { + id: Int + name: String +} +``` + +The merged result config will look like this: + +```graphql +union Media = Book | Movie | Podcast + +type Query { + media: Foo + @http(url: "http://jsonplaceholder.typicode.com/media") + post(id: Int!): Post + @http( + url: "http://jsonplaceholder.typicode.com/users/{{.args.id}}" + ) +} + +type User { + id: Int + age: Int + name: String +} +``` + ## Example -The following example illustrates how to utilize the `@link` directive to incorporate a Protocol Buffers (.proto) file for a gRPC service into your GraphQL schema. +The following example illustrates how to utilize the `links` configuration to incorporate a Protocol Buffers (.proto) file for a gRPC service into your GraphQL schema. -```graphql showLineNumbers -schema - @server(port: 8000) - @upstream(httpCache: 42, batch: {delay: 10}) - @link( - id: "news" +```yaml title="config.yaml" +server: + port: 8000 + +upstream: + httpCache: 10 + batch: + delay: 10 + +links: + - id: schema + src: schema.graphql + type: Config + - id: news src: "./src/grpc/news.proto" type: Protobuf - headers: [{key: "authorization", value: "Bearer 123"}] - ) { + headers: + - key: authorization + value: Bearer 123 +``` + +```graphql title="schema.graphql" showLineNumbers +schema { query: Query } @@ -102,23 +166,30 @@ type NewsData { ## Example using Mustache template -The following example illustrates how to utilize the `@link` directive to incorporate a Protocol Buffers (.proto) file for a gRPC service into your GraphQL schema using Mustache template. +The following example illustrates how to utilize the `links` configuration to incorporate a Protocol Buffers (.proto) file for a gRPC service into your GraphQL schema using Mustache template. + +```yaml title="config.yaml" +server: + port: 8000 + +upstream: + httpCache: 10 + batch: + delay: 10 -```graphql showLineNumbers -schema - @server(port: 8000) - @upstream(httpCache: 42, batch: {delay: 10}) - @link( - id: "news" +links: + - id: schema + src: schema.graphql + type: Config + - id: news src: "{{.env.NEWS_PROTO_PATH}}" type: Protobuf - headers: [ - {key: "authorization", value: "{{.env.BEARER}}"} - ] - ) { - query: Query -} + headers: + - key: authorization + value: "{{.env.BEARER}}" +``` +```graphql title="schema.graphql" showLineNumbers type Query { news: NewsData! @grpc(method: "news.NewsService.GetAllNews") @@ -145,7 +216,7 @@ and populate it with the values given. ## Supported Types -The `@link` directive enriches your configuration by supporting the integration of external resources. Each link type is designed to serve a specific purpose, enhancing the functionality and flexibility of your schema. Below is a detailed overview of each supported link type: +The `links` configuration enriches your configuration by supporting the integration of external resources. Each link type is designed to serve a specific purpose, enhancing the functionality and flexibility of your schema. Below is a detailed overview of each supported link type: ### Config diff --git a/docs/directives/server.md b/docs/config/server.md similarity index 68% rename from docs/directives/server.md rename to docs/config/server.md index 3b5d3f528f..23ad3300cf 100644 --- a/docs/directives/server.md +++ b/docs/config/server.md @@ -1,82 +1,58 @@ --- -title: "@server" -description: The @server directive provides a comprehensive set of server configurations. -slug: ../server-directive +title: "server" +description: The server configuration provides a comprehensive set of server settings. +slug: ../server-config --- -The `@server` directive is defined as follows: - -```graphql title="Directive Definition" showLineNumbers -directive @server( - workers: Int - port: Int - headers: ServerHeaders - introspection: Boolean - queryValidation: Boolean - responseValidation: Boolean - globalResponseTimeout: Int - version: Version - cert: String - key: String - showcase: Boolean - batchRequests: Boolean - routes: Routes - enableFederation: Boolean - vars: [InputKeyValue!] -) on SCHEMA - -input ServerHeaders { - cacheControl: Boolean - custom: [InputKeyValue!] - experimental: [String!] - setCookies: Boolean - cors: CorsConfig -} - -input CorsConfig { - allowCredentials: Boolean - allowHeaders: [String!] - allowMethods: [Method!] - allowOrigins: [String!] - allowPrivateNetwork: Boolean - exposeHeaders: [String!] - maxAge: Int - vary: [String!] -} - -input Routes { - graphQL: String - status: String -} - -enum Version { - HTTP1 - HTTP2 -} -``` - -The `@server` directive, applied at the schema level, provides a comprehensive set of server configurations. It dictates server behavior and helps tune Tailcall for a range of use-cases. +The `server` configuration is defined in a YAML file as follows: -```graphql showLineNumbers -schema @server(...[ServerSettings]...){ - query: Query - mutation: Mutation -} +```yaml title="Runtime Configuration" showLineNumbers +server: + workers: 32 + port: 8000 + headers: + cacheControl: true + setCookies: true + custom: + - key: "X-Custom-Header" + value: "custom-value" + cors: + allowCredentials: true + allowHeaders: ["*"] + allowMethods: ["*"] + allowOrigins: ["*"] + exposeHeaders: ["*"] + maxAge: 600 + vary: ["Origin"] + introspection: true + queryValidation: false + responseValidation: false + globalResponseTimeout: 5000 + version: "HTTP1" + cert: "./cert.pem" + key: "./key.pem" + showcase: false + batchRequests: false + routes: + graphQL: "/graphql" + status: "/status" + enableFederation: false + vars: + - key: "apiKey" + value: "YOUR_API_KEY_HERE" ``` -In this templated structure, replace `...[ServerSettings]...` with specific configurations tailored to your project's needs. Adjust and expand these settings as necessary. +The `server` configuration provides a comprehensive set of server configurations. It dictates server behavior and helps tune Tailcall for a range of use-cases. -The `ServerSettings` options and their details appear below. +The options and their details appear below. ## workers Setting `workers` to `32` means that the GraphQL server will use 32 worker threads. -```graphql showLineNumbers -schema @server(workers: 32) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + workers: 32 ``` This example sets the `workers` to `32`, meaning the GraphQL server will use 32 worker threads. @@ -85,11 +61,9 @@ This example sets the `workers` to `32`, meaning the GraphQL server will use 32 Setting the `port` to `8090` means that Tailcall will be accessible at `http://localhost:8000`. -```graphql showLineNumbers -schema @server(port: 8090) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + port: 8090 ``` This example sets the `port` to `8090`, making Tailcall accessible at `http://localhost:8090`. @@ -108,43 +82,33 @@ Activating the `cacheControl` configuration directs Tailcall to send [Cache-Cont [cache-control]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control -```graphql showLineNumbers -schema @server(headers: {cacheControl: true}) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + headers: + cacheControl: true ``` ## custom The `custom` is an array of key-value pairs. These headers get added to the response of every request made to the server. This can be useful for adding headers like `Access-Control-Allow-Origin` to allow cross-origin requests, or some headers like `X-Allowed-Roles` for use by downstream services. -```graphql showLineNumbers -schema - @server( - headers: { - custom: [ - {key: "X-Allowed-Roles", value: "admin,user"} - ] - } - ) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + headers: + custom: + - key: "X-Allowed-Roles" + value: "admin,user" ``` ## experimental When the `experimental` configuration is enabled, Tailcall can include headers starting with `X-` in its responses, which are sourced from its upstream. By default, this feature is disabled (`[]`), meaning Tailcall does not forward any such headers unless explicitly configured to do so. -```graphql showLineNumbers -schema - @server( - headers: {experimental: ["X-Experimental-Header"]} - ) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + headers: + experimental: + - "X-Experimental-Header" ``` ## setCookies @@ -153,26 +117,22 @@ Enabling the `setCookies` option instructs Tailcall to include `set-cookie` head [set-cookie]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/set-cookie -```graphql showLineNumbers -schema @server(headers: {setCookies: true}) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + headers: + setCookies: true ``` ## cors The `cors` configuration allows you to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) on Tailcall. This is useful when you want to access Tailcall in the browser. Here is a simple configuration to get started with cors: -```graphql showLineNumbers -schema - @server( - headers: { - cors: {allowHeaders: ["*"], allowOrigins: ["*"]} - } - ) { - query: Query -} +```yaml showLineNumbers +server: + headers: + cors: + allowHeaders: ["*"] + allowOrigins: ["*"] ``` The above setting will enable CORS on the server for all headers, origins & methods. You can further configure the cors settings to make it more secure with the following fields: @@ -186,41 +146,36 @@ The above setting will enable CORS on the server for all headers, origins & meth - `maxAge`: The maximum time (in seconds) that the client should cache preflight OPTIONS requests to avoid sending excessive requests to the server. - `vary`: A list of header names that indicate the values of which might cause the server's response to vary, potentially affecting caching. -```graphql showLineNumbers -schema - @server( - port: 8000 - hostname: "0.0.0.0" - headers: { - cors: { - allowCredentials: false - allowHeaders: ["Authorization"] - allowMethods: [POST, GET, OPTIONS] - allowOrigins: ["abc.xyz"] - allowPrivateNetwork: true - exposeHeaders: ["Content-Type"] - maxAge: 360 - vary: ["Origin"] - } - } - ) { - query: Query -} +```yaml showLineNumbers +server: + port: 8000 + hostname: "0.0.0.0" + headers: + cors: + allowCredentials: false + allowHeaders: ["Authorization"] + allowMethods: ["POST", "GET", "OPTIONS"] + allowOrigins: ["abc.xyz"] + allowPrivateNetwork: true + exposeHeaders: ["Content-Type"] + maxAge: 360 + vary: ["Origin"] ``` ## vars This configuration allows defining local variables for use during the server's operations. These variables are handy for storing constant configurations, secrets, or other shared information that operations might need. -```graphql showLineNumbers -schema - @server( - vars: {key: "apiKey", value: "YOUR_API_KEY_HERE"} - ) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + vars: + - key: "apiKey" + value: "YOUR_API_KEY_HERE" +``` + +Then in your schema file: +```graphql showLineNumbers type Query { externalData: Data @http( @@ -245,11 +200,9 @@ Local variables, like `apiKey`, are instrumental in securing access to external This setting controls the server's allowance of introspection queries. Introspection, a core feature of GraphQL, allows clients to directly fetch schema information. This capability proves crucial for tools and client applications in comprehending the available types, fields, and operations. By default, the server enables this setting (`true`). -```graphql showLineNumbers -schema @server(introspection: false) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + introspection: false ``` :::tip @@ -260,11 +213,9 @@ Although introspection is beneficial during development and debugging stages, co The `queryValidation` configuration determines if the server checks incoming GraphQL queries against the defined schema. Each query check ensures it matches the schema, preventing errors from incorrect or malformed queries. In some situations, you might want to disable it, notably to **enhance server performance** at the cost of these checks. This defaults to `false` if not specified. -```graphql showLineNumbers -schema @server(queryValidation: true) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + queryValidation: true ``` The example above sets `queryValidation` to `true`, enabling the validation phase for incoming queries. @@ -277,11 +228,9 @@ Enable this in the development environment to ensure the queries sent are correc Tailcall can automatically infer the schema of the HTTP endpoints for you. This information can check responses received from the upstream services. Enabling this setting allows you to do that. If not specified, the default setting for `responseValidation` is `false`. -```graphql showLineNumbers -schema @server(responseValidation: true) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + responseValidation: true ``` :::tip @@ -294,11 +243,9 @@ The `globalResponseTimeout` configuration sets the max duration a query can run If not explicitly defined, there might be a system-specific or default value that applies. -```graphql showLineNumbers -schema @server(globalResponseTimeout: 5000) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + globalResponseTimeout: 5000 ``` In this given example, setting the `globalResponseTimeout` to `5000` milliseconds, or 5 seconds, means any query execution taking longer than this duration will be automatically terminated by @@ -311,22 +258,18 @@ Setting an appropriate response timeout in production environments is crucial. T The server uses the HTTP version. If not specified, the default value is `HTTP1`. The available options are `HTTP1` and `HTTP2`. -```graphql showLineNumbers -schema @server(version: HTTP2) { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + version: "HTTP2" ``` ## cert The path to certificate(s) for running the server over HTTP2 (HTTPS). If not specified, the default value is `null`. -```graphql showLineNumbers -schema @server(cert: "./cert.pem") { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + cert: "./cert.pem" ``` @@ -339,11 +282,9 @@ The certificate can be of any extension, but it's highly recommended to use stan The path to the key for running the server over HTTP2 (HTTPS). If not specified, the default value is `null`. -```graphql showLineNumbers -schema @server(key: "./key.pem") { - query: Query - mutation: Mutation -} +```yaml showLineNumbers +server: + key: "./key.pem" ``` :::tip @@ -352,23 +293,21 @@ The key can be of any extension, but it's highly recommended to use standards (` ## showcase -The `@server` directive's `showcase` option allows for hands-on experimentation with server configurations in a controlled environment. This feature simplifies the process of exploring and testing different settings. +The `server` configurations's `showcase` option allows for hands-on experimentation with server configurations in a controlled environment. This feature simplifies the process of exploring and testing different settings. -```graphql showLineNumbers -schema @server(showcase: true) { - query: Query -} +```yaml showLineNumbers +server: + showcase: true ``` ## batchRequests Batching in GraphQL combines requests into one, reducing server round trips. -```graphql showLineNumbers -schema @server( +```yaml showLineNumbers +server: port: 8000 batchRequests: true -) ``` :::tip @@ -382,8 +321,11 @@ This optional field allows you to customize the server's endpoint paths, enablin - graphQL: `/graphql` - status: `/status` -```graphql showLineNumbers -schema @server(routes: {graphQL: "/tailcall-gql", status: "/health"}) +```yaml showLineNumbers +server: + routes: + graphQL: "/tailcall-gql" + status: "/health" ``` In this example, the GraphQL endpoint is changed to `/tailcall-gql` and the status endpoint to `/health`. @@ -392,6 +334,7 @@ In this example, the GraphQL endpoint is changed to `/tailcall-gql` and the stat A boolean flag, if set to `true` the Tailcall server will additionally act as federation subgraph. By default, it's disabled. -```graphql showLineNumbers -schema @server(enableFederation: true) +```yaml showLineNumbers +server: + enableFederation: true ``` diff --git a/docs/directives/telemetry.md b/docs/config/telemetry.md similarity index 69% rename from docs/directives/telemetry.md rename to docs/config/telemetry.md index 386f83db04..c4cdc60a45 100644 --- a/docs/directives/telemetry.md +++ b/docs/config/telemetry.md @@ -1,63 +1,39 @@ --- -title: "@telemetry" -description: The @telemetry directive facilitates seamless integration with OpenTelemetry, enhancing the observability of your GraphQL services. -slug: ../telemetry-directive +title: "telemetry" +description: The telemetry configuration facilitates seamless integration with OpenTelemetry, enhancing the observability of your GraphQL services. +slug: ../telemetry-config --- -The `@telemetry` directive is defined as follows: - -```graphql title="Directive Definition" showLineNumbers -directive @telemetry( - """ - Export configuration for telemetry data - """ - export: TelemetryExport - - """ - Headers from ingress request to be included in telemetry - """ - requestHeaders: [String!] -) on SCHEMA - -input TelemetryExport { - otlp: OtlpConfig - prometheus: PrometheusConfig - stdout: StdoutConfig - apollo: ApolloConfig -} - -input OtlpConfig { - url: String! - headers: [InputKeyValue!] -} - -input PrometheusConfig { - path: String - format: PrometheusFormat -} - -input StdoutConfig { - pretty: Boolean -} - -input ApolloConfig { - api_key: String! - graph_ref: String! - platform: String - version: String -} - -enum PrometheusFormat { - text - protobuf -} +The `telemetry` configuration is defined as follows: + +```yaml title="Runtime Configuration" showLineNumbers +telemetry: + export: + # oneof: + otlp: + url: string + headers: + - key: string + value: string + prometheus: + path: string + format: text # protobuf + stdout: + pretty: boolean + apollo: + api_key: string + graph_ref: string + platform: string + version: string + requestHeaders: + - string ``` -The `@telemetry` directive facilitates seamless integration with [OpenTelemetry](https://open-telemetry.io), enhancing the observability of your GraphQL services powered by Tailcall. By leveraging this directive, developers gain access to valuable insights into the performance and behavior of their applications. +The `telemetry` configuration facilitates seamless integration with [OpenTelemetry](https://open-telemetry.io), enhancing the observability of your GraphQL services powered by Tailcall. By leveraging this configuration, developers gain access to valuable insights into the performance and behavior of their applications. ## Traces -Here are the traces that are captured by the `@telemetry` directive: +Here are the traces that are captured by the `telemetry` configuration: | Trace Name | Description | | --------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -70,11 +46,11 @@ Here are the traces that are captured by the `@telemetry` directive: ## Metrics -The `@telemetry` directive also captures the following metrics: +The `telemetry` configuration also captures the following metrics: | Metric | Description | | ------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------- | -| cache.hit_rate | Reflects the cache hit rate for the cache powered by the [`@cache`](./cache.md) directive | +| cache.hit_rate | Reflects the cache hit rate for the cache powered by the [`@cache`](../directives/cache.md) directive | | http.server.request.count | Counts the number of incoming requests made to specific route. Optionally enriched with selected headers by [`requestHeaders`](#requestheaders) | | http.client.request.count | Counts the number of outgoing requests to specific upstream | @@ -88,24 +64,16 @@ Utilizes the OTLP format to export telemetry data to backend systems, supported [honecomb.io]: https://www.honeycomb.io/ -```graphql -schema - @telemetry( - export: { - otlp: { - url: "https://api.honeycomb.io:443" - headers: [ - { - key: "x-honeycomb-team" - value: "{{.env.HONEYCOMB_API_KEY}}" - } - {key: "x-honeycomb-dataset", value: "tailcall"} - ] - } - } - ) { - query: Query -} +```yaml +telemetry: + export: + otlp: + url: "https://api.honeycomb.io:443" + headers: + - key: "x-honeycomb-team" + value: "{{.env.HONEYCOMB_API_KEY}}" + - key: "x-honeycomb-dataset" + value: "tailcall" ``` You can configure the OTLP exporter with the following options: @@ -119,11 +87,11 @@ You can configure the OTLP exporter with the following options: Facilitates metrics export in a Prometheus compatible format, providing a dedicated endpoint for metrics. -```graphql -schema - @telemetry(export: {prometheus: {path: "/metrics"}}) { - query: Query -} +```yaml +telemetry: + export: + prometheus: + path: "/metrics" ``` You can configure the Prometheus exporter with the following options: @@ -137,10 +105,11 @@ You can configure the Prometheus exporter with the following options: Outputs all telemetry data to stdout, ideal for testing or local development environments. -```graphql -schema @telemetry(export: {stdout: {pretty: true}}) { - query: Query -} +```yaml +telemetry: + export: + stdout: + pretty: true ``` You can configure the stdout exporter with the following options: @@ -153,30 +122,24 @@ You can configure the stdout exporter with the following options: Specifies list of headers of ingress request the value of which will be sent to the telemetry as attributes. -```graphql -schema @telemetry(requestHeaders: ["X-User-Id"]) { - query: Query -} +```yaml +telemetry: + requestHeaders: + - "X-User-Id" ``` ## apollo Facilitates seamless integration with [Apollo Studio](https://studio.apollographql.com/), enhancing the observability of GraphQL services. By leveraging this field, developers gain access to valuable insights into the performance and behavior of their GraphQL APIs. -```graphql -schema - @telemetry( - export: { - otlp: { - api_key: "{{.env.APOLLO_API_KEY}}" - graph_ref: "graph-id@current" - platform: "website.com" - version: "1.0.0" - } - } - ) { - query: Query -} +```yaml +telemetry: + export: + apollo: + api_key: "{{.env.APOLLO_API_KEY}}" + graph_ref: "graph-id@current" + platform: "website.com" + version: "1.0.0" ``` You can configure the apollo exporter with the following options: @@ -188,4 +151,4 @@ You can configure the apollo exporter with the following options: | platform | An arbitrary value which can contain the name of your website or some other value to identify your deployment uniqely, in case you have multiple deployments. | | version | Version of Apollo which is being used. | -By integrating the `@telemetry` directive into your GraphQL schema, you empower your development teams with critical insights into application performance, enabling proactive optimization and maintenance. +By integrating the `telemetry` configuration into your GraphQL schema, you empower your development teams with critical insights into application performance, enabling proactive optimization and maintenance. diff --git a/docs/config/upstream.md b/docs/config/upstream.md new file mode 100644 index 0000000000..6cd771b4c8 --- /dev/null +++ b/docs/config/upstream.md @@ -0,0 +1,183 @@ +--- +title: "upstream" +description: The upstream configuration enables control over specific aspects of the upstream server connection. +slug: ../upstream-configuration +--- + +The `upstream` configuration is defined as follows: + +```yaml title="Runtime Configuration" showLineNumbers +upstream: + poolIdleTimeout: 60 + poolMaxIdlePerHost: 60 + keepAliveInterval: 60 + keepAliveTimeout: 60 + keepAliveWhileIdle: false + proxy: + url: "http://localhost:3000" + connectTimeout: 60 + timeout: 60 + tcpKeepAlive: 60 + userAgent: "Tailcall/1.0" + allowedHeaders: + - "Authorization" + - "X-Api-Key" + httpCache: 42 + batch: + maxSize: 1000 + delay: 10 + headers: + - "X-Server" + - "Authorization" + onRequest: "someFunctionName" +``` + +The `upstream` configuration enables control over specific aspects of the upstream server connection, including settings such as connection timeouts, keep-alive intervals, and more. The system applies default values if you do not specify them. + +## poolIdleTimeout + +The connection pool waits for this duration in seconds before closing idle connections. + +```yaml showLineNumbers +upstream: + poolIdleTimeout: 60 +``` + +## poolMaxIdlePerHost + +The max number of idle connections each host will maintain. + +```yaml showLineNumbers +upstream: + poolMaxIdlePerHost: 60 +``` + +## keepAliveInterval + +The time in seconds between each keep-alive message sent to maintain the connection. + +```yaml showLineNumbers +upstream: + keepAliveInterval: 60 +``` + +## keepAliveTimeout + +The time in seconds that the connection will wait for a keep-alive message before closing. + +```yaml showLineNumbers +upstream: + keepAliveTimeout: 60 +``` + +## keepAliveWhileIdle + +A boolean value that determines whether to send keep-alive messages while the connection is idle. + +```yaml showLineNumbers +upstream: + keepAliveWhileIdle: false +``` + +## proxy + +The `proxy` setting defines an intermediary server that routes upstream requests before they reach their intended endpoint. By specifying a proxy URL, you introduce a layer, enabling custom routing and security policies. + +```yaml showLineNumbers +upstream: + proxy: + url: "http://localhost:3000" +``` + +In the provided example, we've set the proxy's `url` to "http://localhost:3000". This configuration ensures that all requests aimed at the designated `url` first go through this proxy. To illustrate, if the `url` is "http://jsonplaceholder.typicode.com", any request targeting it initially goes to "http://localhost:3000" before the proxy redirects it to its final destination. + +## connectTimeout + +The time in seconds that the connection will wait for a response before timing out. + +```yaml showLineNumbers +upstream: + connectTimeout: 60 +``` + +## timeout + +The max time in seconds that the connection will wait for a response. + +```yaml showLineNumbers +upstream: + timeout: 60 +``` + +## tcpKeepAlive + +The time in seconds between each TCP keep-alive message sent to maintain the connection. + +```yaml showLineNumbers +upstream: + tcpKeepAlive: 60 +``` + +## userAgent + +The User-Agent header value for HTTP requests. + +```yaml showLineNumbers +upstream: + userAgent: "Tailcall/1.0" +``` + +## allowedHeaders + +The `allowedHeaders` configuration defines a set of whitelisted HTTP headers that can be forwarded to upstream services during requests. +Without specifying `allowedHeaders`, the system will not forward any incoming headers to upstream services, offering an extra security layer but potentially limiting necessary data flow. Tailcall compares the provided whitelisted headers in a case-insensitive format. + +```yaml showLineNumbers +upstream: + allowedHeaders: + - "Authorization" + - "X-Api-Key" +``` + +In the example above, the configuration for `allowedHeaders` permits `Authorization` and `X-Api-Key` headers. Thus, requests with these headers will forward them to upstream services; the system ignores all others. This configuration ensures communication of the expected headers to dependent services, emphasizing security and consistency. + +## httpCache + +When httpCache passed with value greater than 0 it directs Tailcall to use HTTP caching mechanisms, following the [HTTP Caching RFC](https://tools.ietf.org/html/rfc7234) to enhance performance by minimizing unnecessary data fetches. If left unspecified, this feature defaults to `0` disabling the caching mechanism. + +```yaml showLineNumbers +upstream: + httpCache: 42 +``` + +## Tips + +- Use batching when other optimization techniques fail to resolve performance issues. +- Apply batching and thoroughly assess its impact. +- Understand that batching may make debugging more challenging. + +## batch + +An object that specifies the batch settings, including `maxSize` (the max size of the batch), `delay` (the delay in milliseconds between each batch), and `headers` (an array of HTTP headers that the batch will include). + +```yaml showLineNumbers +upstream: + batch: + maxSize: 1000 + delay: 10 + headers: + - "X-Server" + - "Authorization" +``` + +## onRequest + +Similar to the [@http](../directives/http.md) property, this accepts a string value representing a middleware function defined in a JavaScript file. It intercepts all outgoing HTTP requests from the server. This interceptor, written in JavaScript, can be used to modify outgoing requests and also generate artificial responses to customize the behavior of the GraphQL server. + +```yaml showLineNumbers +upstream: + onRequest: "someFunctionName" + script: + type: Script + src: "path_to/worker.js" +``` diff --git a/docs/directives.md b/docs/directives.md index ab927107d1..ae18d6d17c 100644 --- a/docs/directives.md +++ b/docs/directives.md @@ -22,14 +22,10 @@ Here is a list of all the custom directives supported by Tailcall: | [`@graphQL`](./directives/graphQL.md) | Resolves a field or node by a GraphQL API. | | [`@grpc`](./directives/grpc.md) | Resolves a field or node by a gRPC API. | | [`@http`](./directives/http.md) | Resolves a field or node by a REST API. | -| [`@link`](./directives/link.md) | Imports external resources such as config files, certs, protobufs, etc in the schema. | | [`@modify`](./directives/modify.md) | Enables changes to attributes of fields or nodes in the schema. | | [`@omit`](./directives/omit.md) | Excludes fields or nodes from the generated schema, making them inaccessible through the GraphQL API. | | [`@protected`](./directives/protected.md) | Adds authentication and authorization controls to fields or nodes in the schema. | | [`@rest`](./directives/rest.md) | Allows exposing REST endpoints on top of GraphQL. | -| [`@server`](./directives/server.md) | Provides server configurations for behavior tuning and tailcall optimization in specific use-cases. | -| [`@telemetry`](./directives/telemetry.md) | Integrates with open-telemetry to provide observability of the running tailcall service. | -| [`@upstream`](./directives/upstream.md) | Controls aspects of the upstream server connection, including timeouts and keep-alive settings. | ### Resolvable Directives diff --git a/docs/directives/http.md b/docs/directives/http.md index eb09a137f9..bff81a2b02 100644 --- a/docs/directives/http.md +++ b/docs/directives/http.md @@ -176,7 +176,7 @@ type Post { The `onRequest` property accepts a string value representing the remote function to be called every time an HTTP request is initiated. Typically the remote function is defined in a linked JavaScript worker file. :::note -For defining a request middleware globally for all requests, refer to the [upstream directive documentation](./upstream.md#onrequest). +For defining a request middleware globally for all requests, refer to the [upstream config documentation](../config/upstream.md#onrequest). ::: ```graphql showLineNumbers diff --git a/docs/directives/protected.md b/docs/directives/protected.md index 8ae94dc27d..5dccf4bca1 100644 --- a/docs/directives/protected.md +++ b/docs/directives/protected.md @@ -21,7 +21,7 @@ The `@protected` directive designates a type or field as protected, meaning that ## Prerequisites -To use the `@protected` directive, you must configure at least one authentication provider using the [`@link`](./link.md) directive, such as `Htpasswd` or `Jwks`. +To use the `@protected` directive, you must configure at least one authentication provider using the [`links`](../config/links.md) configuration, such as `Htpasswd` or `Jwks`. ```graphql title="Authentication Provider Configuration" showLineNumbers schema diff --git a/docs/directives/upstream.md b/docs/directives/upstream.md deleted file mode 100644 index a365b0f56d..0000000000 --- a/docs/directives/upstream.md +++ /dev/null @@ -1,223 +0,0 @@ ---- -title: "@upstream" -description: The @upstream directive enables control over specific aspects of the upstream server connection. -slug: ../upstream-directive ---- - -The `@upstream` directive is defined as follows: - -```graphql title="Directive Definition" showLineNumbers -directive @upstream( - poolIdleTimeout: Int - poolMaxIdlePerHost: Int - keepAliveInterval: Int - keepAliveTimeout: Int - keepAliveWhileIdle: Boolean - proxy: ProxyConfig - connectTimeout: Int - timeout: Int - tcpKeepAlive: Int - userAgent: String - allowedHeaders: [String!] - httpCache: Int - batch: BatchConfig - onRequest: String -) on SCHEMA - -input ProxyConfig { - url: String! -} - -input BatchConfig { - maxSize: Int! - delay: Int! - headers: [String!] -} -``` - -The `upstream` directive enables control over specific aspects of the upstream server connection, including settings such as connection timeouts, keep-alive intervals, and more. The system applies default values if you do not specify them. - -```graphql showLineNumbers -schema @upstream(...[UpstreamSetting]...){ - query: Query - mutation: Mutation -} -``` - -The document below details the options for `UpstreamSetting`. - -## poolIdleTimeout - -The connection pool waits for this duration in seconds before closing idle connections. - -```graphql showLineNumbers -schema @upstream(poolIdleTimeout: 60) { - query: Query - mutation: Mutation -} -``` - -## poolMaxIdlePerHost - -The max number of idle connections each host will maintain. - -```graphql showLineNumbers -schema @upstream(poolMaxIdlePerHost: 60) { - query: Query - mutation: Mutation -} -``` - -## keepAliveInterval - -The time in seconds between each keep-alive message sent to maintain the connection. - -```graphql showLineNumbers -schema @upstream(keepAliveInterval: 60) { - query: Query - mutation: Mutation -} -``` - -## keepAliveTimeout - -The time in seconds that the connection will wait for a keep-alive message before closing. - -```graphql showLineNumbers -schema @upstream(keepAliveTimeout: 60) { - query: Query - mutation: Mutation -} -``` - -## keepAliveWhileIdle - -A boolean value that determines whether to send keep-alive messages while the connection is idle. - -```graphql showLineNumbers -schema @upstream(keepAliveWhileIdle: false) { - query: Query - mutation: Mutation -} -``` - -## proxy - -The `proxy` setting defines an intermediary server that routes upstream requests before they reach their intended endpoint. By specifying a proxy URL, you introduce a layer, enabling custom routing and security policies. - -```graphql showLineNumbers -schema @upstream(proxy: {url: "http://localhost:3000"}) { - query: Query - mutation: Mutation -} -``` - -In the provided example, we've set the proxy's `url` to "http://localhost:3000". This configuration ensures that all requests aimed at the designated `url` first go through this proxy. To illustrate, if the `url` is "http://jsonplaceholder.typicode.com", any request targeting it initially goes to "http://localhost:3000" before the proxy redirects it to its final destination. - -## connectTimeout - -The time in seconds that the connection will wait for a response before timing out. - -```graphql showLineNumbers -schema @upstream(connectTimeout: 60) { - query: Query - mutation: Mutation -} -``` - -## timeout - -The max time in seconds that the connection will wait for a response. - -```graphql showLineNumbers -schema @upstream(timeout: 60) { - query: Query - mutation: Mutation -} -``` - -## tcpKeepAlive - -The time in seconds between each TCP keep-alive message sent to maintain the connection. - -```graphql showLineNumbers -schema @upstream(tcpKeepAlive: 60) { - query: Query - mutation: Mutation -} -``` - -## userAgent - -The User-Agent header value for HTTP requests. - -```graphql showLineNumbers -schema @upstream(userAgent: "Tailcall/1.0") { - query: Query - mutation: Mutation -} -``` - -## allowedHeaders - -The `allowedHeaders` configuration defines a set of whitelisted HTTP headers that can be forwarded to upstream services during requests. -Without specifying `allowedHeaders`, the system will not forward any incoming headers to upstream services, offering an extra security layer but potentially limiting necessary data flow. Tailcall compares the provided whitelisted headers in a case-insensitive format. - -```graphql showLineNumbers -schema - @upstream( - allowedHeaders: ["Authorization", "X-Api-Key"] - ) { - query: Query - mutation: Mutation -} -``` - -In the example above, the configuration for `allowedHeaders` permits `Authorization` and `X-Api-Key` headers. Thus, requests with these headers will forward them to upstream services; the system ignores all others. This configuration ensures communication of the expected headers to dependent services, emphasizing security and consistency. - -## httpCache - -When httpCache passed with value greater than 0 it directs Tailcall to use HTTP caching mechanisms, following the [HTTP Caching RFC](https://tools.ietf.org/html/rfc7234) to enhance performance by minimizing unnecessary data fetches. If left unspecified, this feature defaults to `0` disabling the caching mechanism. - -```graphql showLineNumbers -schema @upstream(httpCache: 42) { - query: Query - mutation: Mutation -} -``` - -## Tips - -- Use batching when other optimization techniques fail to resolve performance issues. -- Apply batching and thoroughly assess its impact. -- Understand that batching may make debugging more challenging. - -## batch - -An object that specifies the batch settings, including `maxSize` (the max size of the batch), `delay` (the delay in milliseconds between each batch), and `headers` (an array of HTTP headers that the batch will include). - -```graphql showLineNumbers -schema - @upstream( - batch: { - maxSize: 1000 - delay: 10 - headers: ["X-Server", "Authorization"] - } - ) { - query: Query - mutation: Mutation -} -``` - -## onRequest - -Similar to the [@http](./http.md) property, this accepts a string value representing a middleware function defined in a JavaScript file. It intercepts all outgoing HTTP requests from the server. This interceptor, written in JavaScript, can be used to modify outgoing requests and also generate artificial responses to customize the behavior of the GraphQL server. - -```graphql showLineNumbers -schema @upstream(onRequest: 'someFunctionName') -@link(type: Script, src: "path_to/worker.js") { - query: Query - mutation: Mutation -} -``` diff --git a/docs/grpc.md b/docs/grpc.md index 373d2c197a..085ab86f38 100644 --- a/docs/grpc.md +++ b/docs/grpc.md @@ -123,7 +123,7 @@ type Query { } ``` -Also, let's specify options for Tailcall's ingress and egress at the beginning of the config using [`@server`](./directives/server.md) and [`@upstream`](./directives/upstream.md) directives. +Also, let's specify options for Tailcall's ingress and egress at the beginning of the config using [`server`](./config/server.md) and [`upstream`](./config/upstream.md) options. ```graphql schema @server(port: 8000) @upstream(httpCache: 42) { @@ -235,7 +235,7 @@ Or Another important feature of the `@grpc` directive is that it allows you to implement request batching for remote data almost effortlessly as soon as you have gRPC methods that resolve multiple responses for multiple inputs in a single request. -In our protobuf example file, we have a method called `GetMultipleNews` that we can use. To enable batching we need to enable [`@upstream.batch` option](./directives/upstream.md#batch) first and specify `batchKey` option for the `@grpc` directive. +In our protobuf example file, we have a method called `GetMultipleNews` that we can use. To enable batching we need to enable [`upstream.batch` option](./config/upstream.md#batch) first and specify `batchKey` option for the `@grpc` directive. ```graphql schema @@ -280,7 +280,7 @@ Those 2 requests will be executed inside a single request to the gRPC method `Ge gRPC reflection is a potent feature enabling clients to dynamically discover services and their methods at runtime. Tailcall enhances this capability by obviating the need for developers to link each proto file individually. This feature proves particularly valuable in environments where proto files are continuously evolving or when services dynamically expose varying methods. Here are the steps to follow: -1. Add the gRPC endpoint as a [link](directives/link.md) with type set to `Grpc`. This enables the GraphQL server to understand that the specified source is a gRPC endpoint that supports reflection. +1. Add the gRPC endpoint as a [link](./config/links.md) with type set to `Grpc`. This enables the GraphQL server to understand that the specified source is a gRPC endpoint that supports reflection. ```graphql schema diff --git a/docs/http2.md b/docs/http2.md index 8275aa8b78..fbe432dacd 100644 --- a/docs/http2.md +++ b/docs/http2.md @@ -57,7 +57,7 @@ Use self-signed certificates for HTTP/2 configurations in development environmen ## Configuration -Once the certificate and key are generated we can link them with our main configuration using the [@link](./directives/link.md) directive, to enable HTTPS. +Once the certificate and key are generated we can link them with our main configuration using the [links](./config/links.md) configuration, to enable HTTPS. ```graphql showLineNumbers schema diff --git a/docs/rest.md b/docs/rest.md index e88095b2b1..d84d7fa5ae 100644 --- a/docs/rest.md +++ b/docs/rest.md @@ -92,7 +92,7 @@ schema } ``` -To know more about the `@link` directive, please refer to the [Tailcall GraphQL Directives](./directives/link.md). +To know more about the `links` configuration, please refer [it's documentation](./config/links.md). #### Response diff --git a/docs/runtime-config.md b/docs/runtime-config.md new file mode 100644 index 0000000000..e5afb75a33 --- /dev/null +++ b/docs/runtime-config.md @@ -0,0 +1,52 @@ +--- +title: "Getting Started" +description: Detailed guide on the runtime configuration for Tailcall. +slug: runtime-configuration +--- + +The runtime configuration in Tailcall is designed to handle all runtime-related settings, such as server settings, upstream configurations, telemetry, and links to other resources. This configuration is written exclusively in `.json` or `.yml` format. + +## Introduction + +The runtime configuration separates runtime concerns from schema definitions, simplifying the management and merging of configurations. This approach ensures a clear distinction between runtime settings and schema definitions, making the configuration process more predictable and easier to manage. + +## Configuration Structure + +A typical runtime configuration file includes settings for the server, upstream services, telemetry, and links to other resources. Below is an example of a runtime configuration in YAML format: + +```yaml title="main.yaml" showLineNumbers +server: + port: 8000 + +upstream: + batch: + maxSize: 1000 + +telemetry: + export: + stdout: + pretty: true + +links: + - src: "./users.graphql" + - src: "./products.graphql" +``` + +## Example Usage + +To start the Tailcall server with the runtime configuration, use the following command: + +```sh +tailcall start ./main.yaml +``` + +This command will start the server using the settings defined in main.yml. + +## Configuration Options + +| Option | Description | +| ------------------------------------ | ----------------------------------------------------------------------------- | +| [`server`](./config/server.md) | Configuration settings for the Tailcall server, including port and host. | +| [`upstream`](./config/upstream.md) | Settings for upstream services, such as batching and timeouts. | +| [`telemetry`](./config/telemetry.md) | Configuration for telemetry export options, including format and endpoints. | +| [`links`](./config/links.md) | Links to other resources or schema files to be included in the configuration. | diff --git a/docs/scripting.md b/docs/scripting.md index e79e712598..3d9bb9c3cd 100644 --- a/docs/scripting.md +++ b/docs/scripting.md @@ -10,10 +10,10 @@ The runtime is not a full-fledged Node.js environment and has no access to the f ## Getting Started -To leverage this customization, JavaScript functions must be created in a JavaScript file and linked with the main configuration file using the [@link](./directives/link.md) directive. There are two primary ways to achieve this: +To leverage this customization, JavaScript functions must be created in a JavaScript file and linked with the main configuration file using the [links](./config/links.md) configuration. There are two primary ways to achieve this: 1. Define an `onRequest` property with the JS function name in the [http](./directives/http.md#onrequest) directive. -2. Define it in the [upstream](./directives/upstream.md#onrequest) directive, which acts as a global middleware for all requests. +2. Define it in the [upstream](./config/upstream.md#onrequest) configuration, which acts as a global middleware for all requests. :::tip If you specify a `onRequest` handler for both `http` and `upstream` the `http` one will always take precedence over the global `onRequest` handler. @@ -29,7 +29,7 @@ function foo({request}) { } ``` -Once you have a worker file ready, link that file to the GraphQL configuration using the [`@link`](./directives/link.md) directive and define the [onRequest](./directives/upstream.md#onrequest) property. +Once you have a worker file ready, link that file to the GraphQL configuration using the [`links`](./config/links.md) configuration and define the [onRequest](./config/upstream.md#onrequest) property. ```graphql schema @@ -123,7 +123,7 @@ type Request = { } ``` -By default the headers field will be empty in most cases, unless headers are whitelisted via the [allowedHeaders](./directives/upstream.md#allowedheaders) setting in [`@upstream`](./directives/upstream.md). +By default the headers field will be empty in most cases, unless headers are whitelisted via the [allowedHeaders](./config/upstream.md#allowedheaders) setting. The http filter doesn't have access to the request's body, hence you can't directly modify the body of an outgoing request. This is more of a design choice than a limitation we have made to ensure that developers don't misuse this API to write all kind of business logic in Tailcall. diff --git a/docs/telemetry.md b/docs/telemetry.md index 0e8e150613..002fb2d8cf 100644 --- a/docs/telemetry.md +++ b/docs/telemetry.md @@ -79,7 +79,7 @@ We will update that config with telemetry integration in following sections. By default, telemetry data is not generated by Tailcall since it requires some setup to know where to send this data and also that affects performance of server that could be undesirable in some cases. -Telemetry configuration is provided by [`@telemetry`](./directives/telemetry.md) directive to setup how and where the telemetry data is send. +Telemetry configuration is provided by [`telemetry`](./config/telemetry.md) configuration to setup how and where the telemetry data is send. To enable it we can update our config with something like config below: @@ -116,7 +116,7 @@ Prometheus integration works by adding a special route for the GraphQL server's ## Data generated -You can find a reference of type of info generated by Tailcall in the [`@telemetry` reference](./directives/telemetry.md) or consult examples in the next section, in order to gain some understanding. +You can find a reference of type of info generated by Tailcall in the [`telemetry` reference](./config/telemetry.md) or consult examples in the next section, in order to gain some understanding. ### Relation with other services @@ -130,7 +130,7 @@ Where Tailcall is a part of whole distributed trace ### Customize generated data -In some cases you may want to customize the data that were added to telemetry payload to have more control over analyzing process. Tailcall supports that customization for specific use cases described below. For eg. the metric [`http.server.request.count`](./directives/telemetry.md#metrics) can be customized with the [`requestHeaders`](./directives/telemetry.md#requestheaders) property to allow splitting the overall count by specific headers. +In some cases you may want to customize the data that were added to telemetry payload to have more control over analyzing process. Tailcall supports that customization for specific use cases described below. For eg. the metric [`http.server.request.count`](./config/telemetry.md#metrics) can be customized with the [`requestHeaders`](./config/telemetry.md#requestheaders) property to allow splitting the overall count by specific headers. :::important The value of specified headers will be sent to telemetry backend as is, so use it with care to prevent of leaking any sensitive data to third-party services you don't have control over. diff --git a/sidebars.ts b/sidebars.ts index 78097bba92..c2ca82ab82 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -20,6 +20,12 @@ const sidebars: SidebarsConfig = { collapsed: false, items: ["getting-started", "cli", "context", "playground", "conventions", "execution-strategy", "watch-mode"], }, + { + type: "category", + label: "Runtime configuration", + collapsed: false, + items: ["runtime-config", "config/links", "config/server", "config/telemetry", "config/upstream"], + }, { type: "category", label: "Directives", @@ -34,14 +40,10 @@ const sidebars: SidebarsConfig = { "directives/grpc", "directives/http", "directives/js", - "directives/link", "directives/modify", "directives/omit", "directives/protected", "directives/rest", - "directives/server", - "directives/telemetry", - "directives/upstream", "directives/discriminate", ].sort(), },