Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(510): split directive configuration file #514

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion blog/graphql-and-ms-match-2024-08-18.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Designing scalable APIs that leverage both **GraphQL** and **microservices** req
3. **Caching:** Utilize effective caching strategies at both the GraphQL and microservice levels to enhance performance. Caching reduces the need for repeated data retrieval, lowering latency and improving the user experience. Consider using in-memory caches for frequently accessed data and implement cache invalidation strategies to ensure data consistency.
4. **Monitoring and Logging:** Comprehensive monitoring and logging are vital for tracking API performance, identifying potential bottlenecks, and quickly resolving issues. Implementing detailed logging with tools like OpenTelemetry provides valuable insights into the behavior of your API, helping you maintain high availability and optimize performance over time.

5. **Security:** With **Tailcall's** [built-in auth](https://tailcall.run/docs/field-level-access-control-graphql-authentication/) and [@protected](https://tailcall.run/docs/tailcall-dsl-graphql-custom-directives/#protected-directive) directive, you can add auth functionality and make fields protected with just a few lines of code - which is intelligent enough to protect any query that indirectly resolves to that field:
5. **Security:** With **Tailcall's** [built-in auth](https://tailcall.run/docs/field-level-access-control-graphql-authentication/) and [@protected](https://tailcall.run/docs/protected-directive) directive, you can add auth functionality and make fields protected with just a few lines of code - which is intelligent enough to protect any query that indirectly resolves to that field:

```graphql
type Reaction @protected {
Expand Down
2 changes: 1 addition & 1 deletion blog/tailcall-n+1-working-2024-08-04.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Now, here's where it gets fascinating. We use a Depth-First Search (DFS) algorit

1. Initialize two variables to track the currently traversed `path` and `visited` fields so that we can avoid cycles.
2. Start at the root query and begin traversing the graph data structure.
3. For each field in the current node, check if it has a resolver and is not batched. We know if the node contains a resolver if that node has a [`@http`](/docs/tailcall-dsl-graphql-custom-directives#http-directive) or a [`@grpc`](/docs/tailcall-dsl-graphql-custom-directives#grpc-directive). Tailcall supports powerful batching primitives and if a field uses a Batch API, then that resolver is whitelisted and dropped from the list of potential N+1 candidates.
3. For each field in the current node, check if it has a resolver and is not batched. We know if the node contains a resolver if that node has a [`@http`](/docs/directives/http-directive) or a [`@grpc`](/docs/directives/grpc-directive). Tailcall supports powerful batching primitives and if a field uses a Batch API, then that resolver is whitelisted and dropped from the list of potential N+1 candidates.
4. If the field has a resolver and is not batched, and the current path contains a list, then the current path is added to the result.
5. Otherwise, we recursively traverse the graph data structure, updating the current path and visited fields as necessary.
6. If a cycle is detected, return the cached result instead of re-traversing the path.
Expand Down
4 changes: 2 additions & 2 deletions docs/N+1.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,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](/docs/directives.md#dedupe) to `true` in [server](/docs/directives.md#server-directive).
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](/docs/directives/server.md#dedupe) to `true` in [server](/docs/directives/server.md).

```graphql {3}
schema
Expand Down Expand Up @@ -260,7 +260,7 @@ Incredible, isn't it? Tailcall has discovered that querying for posts followed b

![Batched API](../static/images/docs/n+1-batch.png)

An effective technique to mitigate the N+1 problem is deduplicating similar requests, significantly reducing the number of server calls. We achieved it previously using the [dedupe](/docs/directives.md#dedupe) setting. With Tailcall we can go one step further by giving hints about "batch APIs".
An effective technique to mitigate the N+1 problem is deduplicating similar requests, significantly reducing the number of server calls. We achieved it previously using the [dedupe](/docs/directives/server.md#dedupe) setting. With Tailcall we can go one step further by giving hints about "batch APIs".

**Batch APIs:** Are special APIs that allow us to query multiple things at once. In our case we can pass multiple user Ids as query params, to the `/users` API to resolve many users at once:

Expand Down
2 changes: 1 addition & 1 deletion docs/apollo-federation-subgraph.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.md#enablefederation). In case you've added the entity resolvers on the previous step then federation compatibility will be enabled even without the flag.
Federation is controlled by the flag [`enableFederation`](./directives/server.md#enablefederation). In case you've added the entity resolvers on the previous step then federation compatibility will be enabled even without the flag.

## Register your subgraph

Expand Down
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.md#telemetry-directive).
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
39 changes: 32 additions & 7 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.md#link-directive) connect multiple authentication files as you need for different provides. To connect it use either [`Htpasswd`](/docs/directives.md#htpasswd) or [`Jwks`](/docs/directives.md#jwks) link type
2. Mark that some type of field requires authentication to be fetched with the help of [`@protected` directive](/docs/directives.md#protected-directive)
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/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.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 All @@ -249,15 +274,15 @@ 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](/docs/directives.md#htpasswd).
To use Basic Auth you should first include htpasswd file generated from [Prerequisites](#prerequisites) with the help of [`@link` directive](/docs/directives/link.md#htpasswd).

We can use that file as an example for it that has data for `testuser:mypassword` credentials in encrypted format:

```plaintext title="htpasswd"
testuser:$2y$10$wJ/mZDURcAOBIrswCAKFsO0Nk7BpHmWl/XuhF7lNm3gBAFH3ofsuu
```

After adding `@link` you can use the [`@protected` directive](/docs/directives.md#protected-directive) 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 @@ -330,7 +355,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](/docs/directives.md#jwks).
To use JWT you should first include JWKS file generated from [Prerequisites](#prerequisites) with the help of [`@link` directive](/docs/directives/link.md#jwks).

We can use that file as an example for it:

Expand All @@ -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.md#protected-directive) 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
4 changes: 2 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,9 @@ preset:
}
```

2. **consolidateURL:** The setting identifies the most common base URL among multiple REST endpoints and uses this URL in the [upstream](directives.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`.
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](directives.md#http-directive) directives, `http://jsonplaceholder.typicode.com`, and add it to the upstream, cleaning the base URLs from the `Query` type.
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.

```graphql showLineNumbers
schema
Expand Down
Loading
Loading