Skip to content

Commit

Permalink
resolved comments
Browse files Browse the repository at this point in the history
  • Loading branch information
mehulmathur16 committed Sep 25, 2024
1 parent 4544f56 commit 36643d7
Show file tree
Hide file tree
Showing 18 changed files with 507 additions and 527 deletions.
2 changes: 1 addition & 1 deletion docs/apollo-studio.md
Original file line number Diff line number Diff line change
Expand Up @@ -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](/docs/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](/docs/telemetry.md).

## Checking the metrics in Apollo Studio

Expand Down
33 changes: 29 additions & 4 deletions docs/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,37 @@ to know more about how to use it, read the following articles:
1. [Basic Auth](#basic-authentication)
2. [JWT](#jwt-authentication)

## @protected Directive

The `@protected` annotation designates a type or field as protected, meaning that a user must be authenticated to access that data.

```graphql
type Query {
protected: String! @protected
protectedType: ProtectedType
}

type ProtectedType @protected {
name: String!
nested: String!
}
```

:::important
To utilize the `@protected` directive, you must link at least one authentication provider in the configuration using the [`@link`](/docs/directives/link.md) directive (`Htpasswd` or `Jwks`).
:::

### How It Works

- When a field is annotated with `@protected`, an authentication check is performed upon receiving the request. Depending on the authentication result, either the requested data is provided in the response, or an authentication error is returned.
- If a type is annotated with `@protected`, all fields within that type inherit the protection, requiring user authentication for any field that's queried.

## GraphQL Configuration

Enabling support for authentication in Tailcall could be done in two steps:

1. With the help of [`@link` directive](/docs/directives/link.md) connect multiple authentication files as you need for different provides. To connect it use either [`Htpasswd`](/docs/directives/link.md#htpasswd) or [`Jwks`](/docs/directives/link.md#jwks) link type
2. Mark that some type of field requires authentication to be fetched with the help of [`@protected` directive](/docs/directives/protected.md)
2. Mark that some type of field requires authentication to be fetched with the help of [`@protected` directive](/docs/auth.md#protected-directive)

Your config could look like this now:

Expand Down Expand Up @@ -229,7 +254,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](/docs/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](/docs/client-tuning.md#allowedheaders) and therefore they will be forwarded to the upstream requests implicitly.

## Basic Authentication

Expand Down Expand Up @@ -257,7 +282,7 @@ We can use that file as an example for it that has data for `testuser:mypassword
testuser:$2y$10$wJ/mZDURcAOBIrswCAKFsO0Nk7BpHmWl/XuhF7lNm3gBAFH3ofsuu
```

After adding `@link` you can use the [`@protected` directive](/docs/directives/protected.md) to mark the fields that requiring success authentication to be requested.
After adding `@link` you can use the [`@protected` directive](/docs/auth.md#protected-directive) to mark the fields that requiring success authentication to be requested.

The whole example could look like this:

Expand Down Expand Up @@ -349,7 +374,7 @@ We can use that file as an example for it:
}
```

After adding `@link` you can use the [`@protected` directive](/docs/directives/protected.md) to mark the fields that requiring success authentication to be requested.
After adding `@link` you can use the [`@protected` directive](/docs/auth.md#protected-directive) to mark the fields that requiring success authentication to be requested.

The whole example could look like this:

Expand Down
2 changes: 1 addition & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ preset:
}
```

2. **consolidateURL:** The setting identifies the most common base URL among multiple REST endpoints and uses this URL in the [upstream](/docs/directives/upstream.md) directive. It takes a threshold value between 0.0 and 1.0 to determine the most common endpoint. The default is `0.5`.
2. **consolidateURL:** The setting identifies the most common base URL among multiple REST endpoints and uses this URL in the [upstream](/docs/client-tuning.md#upstream-directive) directive. It takes a threshold value between 0.0 and 1.0 to determine the most common endpoint. The default is `0.5`.

For example, if the `Query` type has three base URLs, using the `consolidateURL` setting with a `0.5` threshold will pick the base URL that is used in more than 50% of the [http](/docs/directives/http.md) directives, `http://jsonplaceholder.typicode.com`, and add it to the upstream, cleaning the base URLs from the `Query` type.

Expand Down
255 changes: 254 additions & 1 deletion docs/client-tuning.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,262 @@ Learn more about QUIC in detail [here](https://blog.cloudflare.com/the-road-to-q

Connection pooling mitigates these issues by reusing existing connections for requests, reducing connection establishment frequency (and thus handshake overhead) and conserving client-side ports. This approach enhances application performance by minimizing the resources and time spent on managing connections.

## @upstream Directive

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
baseURL: "http://jsonplaceholder.typicode.com"
) {
query: Query
mutation: Mutation
}
```

### poolMaxIdlePerHost

The max number of idle connections each host will maintain.

```graphql showLineNumbers
schema
@upstream(
poolMaxIdlePerHost: 60
baseURL: "http://jsonplaceholder.typicode.com"
) {
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
baseURL: "http://jsonplaceholder.typicode.com"
) {
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
baseURL: "http://jsonplaceholder.typicode.com"
) {
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
baseURL: "http://jsonplaceholder.typicode.com"
) {
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"}
baseURL: "http://jsonplaceholder.typicode.com"
) {
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 `baseURL` first go through this proxy. To illustrate, if the `baseURL` 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
baseURL: "http://jsonplaceholder.typicode.com"
) {
query: Query
mutation: Mutation
}
```

### timeout

The max time in seconds that the connection will wait for a response.

```graphql showLineNumbers
schema
@upstream(
timeout: 60
baseURL: "http://jsonplaceholder.typicode.com"
) {
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
baseURL: "http://jsonplaceholder.typicode.com"
) {
query: Query
mutation: Mutation
}
```

### userAgent

The User-Agent header value for HTTP requests.

```graphql showLineNumbers
schema
@upstream(
userAgent: "Tailcall/1.0"
baseURL: "http://jsonplaceholder.typicode.com"
) {
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.

### baseURL

This refers to the default base URL for your APIs. If it's not explicitly mentioned in the `@upstream` directive, then each [`@http`](/docs/directives/http.md) directive must specify its own `baseURL`. If neither `@upstream` nor [`@http`](/docs/directives/http.md) provides a `baseURL`, it results in a compilation error.

```graphql showLineNumbers
schema
@upstream(
baseURL: "http://jsonplaceholder.typicode.com"
) {
query: Query
mutation: Mutation
}
```

In this representation, `http://jsonplaceholder.typicode.com` serves as the `baseURL`. Thus, all API calls made by `@http` prepend this URL to their respective paths.

:::tip
Ensure that your base URL remains free from specific path segments.

- **GOOD:** `@upstream(baseURL: http://jsonplaceholder.typicode.com)`
- **BAD:** `@upstream(baseURL: http://jsonplaceholder.typicode.com/api)`

:::

### 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](/docs/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.

```graphql showLineNumbers
schema @upstream(onRequest: 'someFunctionName')
@link(type: Script, src: "path_to/worker.js") {
query: Query
mutation: Mutation
}
```

## 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`](/docs/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`](/docs/client-tuning.md#upstream-directive) for this purpose.

:::note
Connection pooling optimizes HTTP/1. Since HTTP/2 and HTTP/3 support multiplexing, pooling enabled does not noticeably affect performance.
Expand Down
6 changes: 3 additions & 3 deletions docs/config-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ This setting merges types in the configuration that satisfy the threshold criter

### consolidateURL

The setting identifies the most common base URL among multiple REST endpoints and uses this URL in the [upstream](/docs/directives/upstream.md) directive. It takes a threshold value between 0.0 and 1.0 to determine the most common endpoint. The default is `0.5`.
The setting identifies the most common base URL among multiple REST endpoints and uses this URL in the [upstream](/docs/client-tuning.md#upstream-directive) directive. It takes a threshold value between 0.0 and 1.0 to determine the most common endpoint. The default is `0.5`.

For example, if the `Query` type has three base URLs, using the `consolidateURL` setting with a `0.5` threshold will pick the base URL that is used in more than 50% of the [http](/docs/directives/http.md) directives, `http://jsonplaceholder.typicode.com`, and add it to the upstream, cleaning the base URLs from the `Query` type.

Expand Down Expand Up @@ -950,7 +950,7 @@ When setting up your configuration file for GraphQL generation with Tailcall, co
</TabItem>
</Tabs>

2. **[Consolidate URL](config-generation.md#consolidateurl)**: Identifies the most common base URL among multiple REST endpoints and uses it in the [@upstream](/docs/directives/upstream.md) directive. Set a threshold (0.0 to 1.0) to determine when to consolidate URLs. Recommended threshold is anything above `0.5`.
2. **[Consolidate URL](config-generation.md#consolidateurl)**: Identifies the most common base URL among multiple REST endpoints and uses it in the [@upstream](/docs/client-tuning.md#upstream-directive) directive. Set a threshold (0.0 to 1.0) to determine when to consolidate URLs. Recommended threshold is anything above `0.5`.
<Tabs>
<TabItem value="json" label="JSON">
```json showLineNumbers
Expand Down Expand Up @@ -1043,7 +1043,7 @@ curl:

**Q. What if I have multiple REST endpoints with different base URLs?**

**Answer:** Use the [consolidateURL](config-generation.md#consolidateurl) parameter to identify the most common base URL among multiple REST endpoints and it will automatically select the most common base url and add it to the [@upstream](/docs/directives/upstream.md) directive. Here is an example:
**Answer:** Use the [consolidateURL](config-generation.md#consolidateurl) parameter to identify the most common base URL among multiple REST endpoints and it will automatically select the most common base url and add it to the [@upstream](/docs/client-tuning.md#upstream-directive) directive. Here is an example:

<Tabs>
<TabItem value="json" label="JSON">
Expand Down
Loading

0 comments on commit 36643d7

Please sign in to comment.