diff --git a/website/src/docs/bananacakepop/v2/apis.md b/website/src/docs/bananacakepop/v2/apis.md deleted file mode 100644 index 20f6a71d6e8..00000000000 --- a/website/src/docs/bananacakepop/v2/apis.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Apis ---- - -![Image](images/apis-0.png) -An API within the context of Banana Cake Pop, refers to an representation of your GraphQL Servers. -This representation is more than a mere conceptual framework — it serves as a practical tool that allows you to group your documents and share common settings like connection and authorization parameters among them. - -An API also serves as the basis for your client and schema registry setup. You can find more information about this feature in the [Schema & Client Registry](/docs/bananacakepop/v2/schema-client-registry) guide. - - -# Creating an API -![Image](images/apis-1.png) - -Creating an API in Banana Cake Pop is a straightforward task. Here's are two ways to do it: - -1. The first way is to click on the `Create Api` button located at the top of the document explorer toolbar. -2. The second way is to right-click within the document explorer and select `New Api` from the context menu. This will create a new api within the currently selected folder. Apis can be in folders but cannot be nested within each other. diff --git a/website/src/docs/bananacakepop/v2/apis/client-registry.md b/website/src/docs/bananacakepop/v2/apis/client-registry.md new file mode 100644 index 00000000000..2e22b6b7041 --- /dev/null +++ b/website/src/docs/bananacakepop/v2/apis/client-registry.md @@ -0,0 +1,175 @@ +--- +title: "Client Registry" +--- + +![Image](images/client-registry-1.png) +The client registries is an important tool for managing your GraphQL Clients. It provides a centralized location for clients and queries. + +You can use the client registry to manage your clients and their queries. It allows you to validate your queries against the schema, ensuring that all the operations defined by a client are compatible with the current schema. This validation step is critical to prevent the execution of invalid queries that might result in runtime errors. + +# Understanding Clients + +A client, in the context of a GraphQL API, is an entity that interacts with the API by defining and executing GraphQL operations. These operations are stored on the API as persisted queries. + +## What is a Persisted Query? + +A persisted query is a GraphQL operation that has been sent to the server, stored, and assigned an unique identifier (hash). Instead of sending the full text of a GraphQL operation to the server for execution, clients can send the hash of the operation, reducing the amount of data transmitted over the network. This practice is particularly beneficial for mobile clients operating in environments with limited network capacity. + +Persisted queries also add an extra layer of security as the server can be configured to only execute operations that have been previously stored, which prevents malicious queries. This is the cheapest and most effective way to secure your GraphQL API from potential attacks. + +![Image](images/client-registry-2.png) +Persisted queries can be inspected in the `Operations` tab. + +## The Role of the Client Registry + +The client registry plays a crucial role in managing these persisted queries. It is used to validate the queries against the schema, ensuring that all the operations defined by a client are compatible with the current schema. This validation step is critical to prevent the execution of invalid queries that might result in runtime errors. + +Additionally, the client registry is responsible for distributing the queries to the GraphQL server. It maintains a mapping of hashes to query keys, informing the server which hash corresponds to which query. This allows the server to efficiently look up and execute the appropriate query when it receives a request from a client. + +## Client Versions + +A client can have multiple versions, with each version containing a different set of persisted queries. This versioning system allows for incremental updates and changes to the client's operations without disrupting the existing functionality. As new versions are released, they can be validated and registered with the client registry, ensuring that they are compatible with the current schema and can be executed by the server. + +By managing client versions and persisted queries, the client registry helps maintain the integrity and smooth operation of your GraphQL API. It ensures that your clients and API can evolve together without breaking, contributing to a more robust and reliable system. + +The number of active client versions can vary depending on the nature of the client. For instance, a website usually has one active client version per stage. However, during deployment, you might temporarily have two active versions as the new version is phased in and the old version is phased out. + +On the other hand, for mobile clients, you often have multiple versions active simultaneously. This is because users may be using different versions of the app, and not all users update their apps at the same time. + +Once a client version is no longer in use, it reaches its end of life. At this point, you can unpublish the client version from the client registry. This will remove its persisted queries from distribution, and they will no longer be validated against the schema. + +## The Operations File + +In the context of GraphQL, the operations file is a structured file that holds a collection of persisted queries for a client. This file serves as a reference for the client to manage and execute specific operations against a GraphQL API. + +### Understanding the Format and Structure + +The operations file typically adopts the JSON format as used by Relay. It comprises key-value pairs, with each pair representing a unique persisted query. The key corresponds to a hash identifier for the query, and the value is the GraphQL query string. Below is an illustrative example of an operations file (`operations.json`): + +```json +{ + "913abc361487c481cf6015841c0eca22": "{ me { username } }", + "0e7cf2125e8eb711b470cc72c73ca77e": "{ me { id } }" + ... +} +``` + +### Compatibility with GraphQL Clients + +Several GraphQL clients have built-in support for this Relay-style operations file format. This compatibility allows for a standardized way of handling persisted queries across different clients. For more details on how various clients implement and work with persisted queries, consider referring to their respective documentation: + +- [StrawberryShake](https://chillicream.com/docs/strawberryshake/v13/performance/persisted-queries) +- [URQL](https://formidable.com/open-source/urql/docs/advanced/persisted-queries/) +- [Relay](https://relay.dev/docs/guides/persisted-queries/) + +# Setting Up a Client Registry + +To set up a client registry, first, visit `eat.bananacakepop.com` and sign up for an account. Next, you'll need to download and install Barista, the .NET tool used to manage your client registry. You can find more information about Barista in the [Barista Documentation](/docs/barista/v1). + +After installing Barista, create a new API either through the Bananacakepop UI or the CLI. In the UI, simply right-click the document explorer and select "New API." If you prefer using the CLI, ensure you're logged in with the command `barista login`, then create a new API with the command `barista api create`. With these steps complete, you are ready to start using the client registry. + +To get the id of your API, use the command `barista api list`. This command will list all of your APIs, their names, and their ids. You will need the id of your API to perform most operations on the schema registry. + +# Using Persisted Queries + +To use persisted queries, the server needs to know how to translate the hash into the corresponding GraphQL operation. This is where the client registry comes in. The client registry maintains a mapping of hashes to query keys, informing the server which hash corresponds to which query. This allows the server to efficiently look up and execute the appropriate query when it receives a request from a client. + +To connect your HotChocolate server to the client registry, you need the `BananaCakePop.Services` NuGet package. This package contains the `AddBananaCakePopServices()` extension method, which can be used to configure the client registry. + +To install the Banana Cake Pop services, run the following command in your project's root directory: + +```bash +dotnet add package BananaCakePop.Services +``` + +After installing the package, you need to configure the services in your startup class. Below is a sample implementation in C#: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services + .AddGraphQLServer() + .AddQueryType() + .AddBananaCakePopServices(x => // Connect to the client registry + { + x.ApiKey = "<>"; + x.ApiId = "QXBpCmc5NGYwZTIzNDZhZjQ0NjBmYTljNDNhZDA2ZmRkZDA2Ng=="; + x.Stage = "dev"; + }) + .UsePersistedQueryPipeline(); // Enable the persisted query pipeline +} +``` + +> **Tipp: Using Environment Variables** +> +> Alternatively, you can set the required values using environment variables. This method allows you to call `AddBananaCakePopServices` without explicitly passing parameters. +>- `BCP_API_KEY` maps to `ApiKey` +>- `BCP_API_ID` maps to `ApiId` +>- `BCP_STAGE` maps to `Stage` +>```csharp +>public void ConfigureServices(IServiceCollection services) +>{ +> services +> .AddGraphQLServer() +> .AddQueryType() +> .AddBananaCakePopServices() // Connect to the client registry +> .UsePersistedQueryPipeline(); // Enable the persisted query pipeline +>} +>``` +>In this setup, the API key, ID, and stage are set through environment variables. + +## Block Ad-Hoc Queries +While you want to allow ad-hoc queries during development, you might want to disable them in production. +This can be done by setting the `OnlyAllowPersistedQueries` option to `true` in the `ModifyRequestOptions` method. + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services + .AddGraphQLServer() + .AddQueryType() + .AddBananaCakePopServices() // Connect to the client registry + .ModifyRequestOptions(x => x.OnlyAllowPersistedQueries = true) + .UsePersistedQueryPipeline(); // Enable the persisted query pipeline +} +``` + +You can also customize the error message that is returned when an ad-hoc query is sent to the server. + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services + .AddGraphQLServer() + .AddQueryType() + .AddBananaCakePopServices() // Connect to the client registry + .ModifyRequestOptions(x => + { + x.OnlyAllowPersistedQueries = true; + x.OnlyPersistedQueriesAreAllowedError = ErrorBuilder.New() + .SetMessage("Persisted queries are only allowed.") + .Build(); + }) + .UsePersistedQueryPipeline(); // Enable the persisted query pipeline +} +``` + + +# Integrating with Continuous Integration + +Integrating the client registry into your Continuous Integration/Continuous Deployment (CI/CD) pipeline maximizes their benefits. It ensures that the clients in your API are always up-to-date and tested against potential breaking changes. + +The schema and client registries work hand-in-hand to ensure the smooth functioning of your API. As you make changes to your schema, the schema registry helps manage these changes, preventing inadvertent breaking changes and preserving a history of your schemas. As you validate, upload, and publish new schemas, the client registry ensures that your clients remain compatible with these changes. + +As you release new versions of your clients, the client registry helps manage these versions and the query documents associated with them. By working together, the schema and client registries help maintain the integrity of your API and the services that rely on it, ensuring that they can evolve together without breaking. + +## Understanding the Flow + +The general flow for the client registry involves three main steps: validating the client, uploading it to the registry, and publishing it. + +1. **Validate the Client**: The first step takes place during your Pull Request (PR) build. Here, you validate the client against the API using `barista client validate` command. This ensures that the client is compatible with the API and will not break existing functionality. + +2. **Upload the Client**: The second step takes place during your release build. Here, you upload the client to the registry using the `barista client upload` command. This command requires the `--tag` and `--api-id` options. The `--tag` option specifies the tag for the client, and the `--api-id` option specifies the ID of the API to which you are uploading. This command create a new version of the client with the specified tag. +The tag is a string that can be used to identify the client. It can be any string, but it is recommended to use a version number, such as `v1` or `v2`; or a commit hash, such as `a1b2c3d4e5f6g7h8i9j0k1l2m3n`. The tag is used to identify the client when publishing it. + +3. **Publish the Client **: The third step takes place just before the release. Here, you publish the client using the `barista client publish` commands. This command requires the `--tag` and `--api-id` options. The `--tag` option specifies the tag for the client, and the `--api-id` option specifies the ID of the API to which you are uploading. This command publishes the client with the specified tag, making it the active version for the specified API. diff --git a/website/src/docs/bananacakepop/v2/apis/fusion.md b/website/src/docs/bananacakepop/v2/apis/fusion.md new file mode 100644 index 00000000000..2fc4aae790f --- /dev/null +++ b/website/src/docs/bananacakepop/v2/apis/fusion.md @@ -0,0 +1,205 @@ +--- +title: "Fusion" +--- +![Image](images/fusion-0.png) + +BananaCakePop can be used as your orchestrator for your Fusion Gateway. It deeply integrates with your development workflow and allows you to publish, validate, consume and monitor your Fusion Gateway. + + +![Image](images/fusion-2.png) +On the fusion dashboard you can now see the tracing information of your gateway and your subgraphs. + +# Dashboard +The fusion dashboard gives you a quick overview of your gateway and subgraphs. It shows you the status of your gateway and the status of your subgraphs. You can also see the latest telemetry data insights of your gateway and subgraphs. + +## Topology +![Image](images/fusion-3.png) + +The topology view shows you the connections between your gateway and your subgraphs. You can also see which clients are connected to your gateway and how many operations they are executing. + +## Status +![Image](images/fusion-4.png) +The status view shows you a quick overview of the status of your gateway. With the indicators for latency, throughput and errors you see how your gateway statistics developed between the previous and the current time range. + +You also see the essential information about your gateway, such as the version, the stage, how many subgraphs are connected and how many clients are connected. + +## Insights +![Image](images/fusion-5.png) +The subgraph insights show you a quick overview over your connected subgraphs. You can see the latency, throughput and error rate of each subgraph. + +# Gateway Management +With fusion you compose your gateway configuration locally when you deploy a subgraph. This means that you somehow need to inform your gateway that there is a new configuration available. + +With Banana Cake Pop you can automate this process. You can configure your gateway to automatically pull the latest configuration from Banana Cake Pop. This way you can be sure that your gateway always has the latest configuration. You can also validate your configuration against the schema and client registry to make sure that your change does not break any clients. + +## Configure your gateway +To configure your fusion gateway to pull the configuration from Banana Cake Pop, you need to install the BananaCakePop.Services package. You can do this by running the following command in your project's root directory: + +```bash +dotnet add package BananaCakePop.Services +``` + +After installing the package, you need to configure the services in your startup class. Below is a sample implementation in C#: + +```csharp +builder.Services + .AddFusionGatewayServer() + .ConfigureFromCloud(x => + { + x.ApiKey = "<>"; + x.ApiId = "QXBpCmc5NGYwZTIzNDZhZjQ0NjBmYTljNDNhZDA2ZmRkZDA2Ng=="; + x.Stage = "dev"; + }) +``` + +> **Tipp: Using Environment Variables** +> +> Alternatively, you can set the required values using environment variables. This method allows you to call `ConfigureFromCloud` without explicitly passing parameters. +>- `BCP_API_KEY` maps to `ApiKey` +>- `BCP_API_ID` maps to `ApiId` +>- `BCP_STAGE` maps to `Stage` +>```csharp +> builder.Services +> .AddFusionGatewayServer() +> .ConfigureFromCloud(); +>``` +>In this setup, the API key, ID, and stage are set through environment variables. + +Now your gateway will be notified whenever there is a new configuration available and will automatically pull it. + +## Integration into your CI/CD pipeline +The deployment of a subgraph is a multi step process. To integrate BananaCakePop into this process you need to install Barista, the BananaCakePop CLI. You can find more information about Barista in the [Barista Documentation](/docs/barista/v1). +```bash +dotnet new tool-manifest +dotnet tool install Barista +``` + +You will also need the [Command Line Tools](https://www.nuget.org/packages/HotChocolate.Fusion.CommandLine) for packing and composing your subgraph. + +```bash +dotnet tool install HotChocolate.Fusion.CommandLine +``` + + +### 1. Pack the subgraph +All changes to the gateway originate from a subgraph. Once the subgraph is ready to be deployed, you need to pack it. Packing a subgraph will create a subgraph package file that contains the schema, the extensions and the configuration of the subgraph. + +To easily access the newest schema and extensions, you can use the `schema export` command from the [Command Line Extension](/docs/hotchocolate/v13/server/command-line). This command exports your current schema into a specified output file. + +```bash +dotnet run -- schema export --output schema.graphql +dotnet fusion subgraph pack +``` + +This step is usually done in a separate build step in your CI/CD pipeline where you build and test your project before you go into the deployment phase. + +### 2. Wait for a deployment slot +Once your changes are ready to be deployed, you need to wait for a deployment slot. There can only ever be one deployment at the time. If there is already a deployment in progress, you need to wait until it is finished. + +Banana Cake Pop helps you coordinate your subgraph deployments. You register for a deployment by calling: + +```bash +dotnet barista fusion-configuration publish begin \ + --tag <> \ + --api-id <> \ + --subgraph-name <> \ + --api-key <> +``` + +This command will complete once your turn has come and you can start deploying your subgraph. + +### 3. Start the deployment +Once you have a deployment slot, you need to notify Banana Cake Pop that you are still interested in the slot. You do this by calling: + +```bash +dotnet barista fusion-configuration publish start --api-key <> +``` + +### 4. Configure the subgraph +As most likely, your connection information is different from environment to environment, you need to configure the url of your subgraph. You can do this by calling: + +```bash +dotnet fusion subgraph config set http \ + --url <> + -c path/to/your/subgraph/config.fsp +``` + +### 5. Compose the subgraph +To compose the subgraph, you first need to fetch the latest configuration from Banana Cake Pop. You can do this by calling: + +```bash +dotnet barista fusion-configuration download \ + --api-id <> \ + --stage <> \ + --output-file ./gateway.fgp \ + --api-key <> +``` + +This will download the latest configuration from Banana Cake Pop and save it to the specified file (`gateway.fgp`). + +Now you can compose the subgraph by calling: + +```bash +dotnet fusion compose -p ./gateway.fgp -s path/to/your/subgraph/config.fsp +``` + +### 6. Validate the subgraph (optional) +If you want to make sure that your subgraph is compatible with the schema and client registry, you can validate it by calling: + +```bash +barista fusion-configuration publish validate --configuration ./gateway.fgp --api-key <> +``` + +In case the validation fails, you will get an error message. You have to cancel the deployment manually though. You can add deployment step to your CI/CD pipeline which will cancel the deployment if the validation fails by calling: + +```bash +dotnet barista fusion-configuration publish cancel --api-key <> +``` + +### 7. Deploy the subgraph +Now it's time to deploy your subgraph to your infrastructure + +### 8. Commit the deployment +To complete the deployment, you need to commit the deployment. This will notify Banana Cake Pop that you are done with the deployment and that the next deployment can start. Banana Cake Pop will also notify your gateway that the deployment is finished and that it can pull the latest configuration. + +You can commit the deployment by calling: + +```bash +dotnet barista fusion-configuration publish commit --api-key <> +``` + +# Distributed Telemetry +![Image](images/fusion-1.png) +Banana Cake Pop provides a distributed telemetry solution for your Fusion Gateway. It allows you to monitor your gateway and all your subgraphs in one place. You can inspect the traces of your operations on the gateway and see how they are executed on the subgraphs. + +To enable telemetry for your gateway and subgraphs, all of them need to be configured to send telemetry data to Banana Cake Pop. Your subgraphs can be configured to send telemetry data by using the [BananaCakePop.Services](https://www.nuget.org/packages/BananaCakePop.Services/) package. You can find more information about how to configure your subgraphs in the [Open Telemetry](/docs/bananacakepop/v2/apis/open-telemetry) guide. + +To send telemetry data from the gateway you need to add the instrumentation and the exporter to your gateway. + +```csharp +builder.Services + .AddFusionGatewayServer() + .ConfigureFromCloud() + .CoreBuilder + .AddInstrumentation(); + +builder.Services + .AddOpenTelemetry() + .WithTracing(b => b + .AddHttpClientInstrumentation() + .AddAspNetCoreInstrumentation() + .AddBananaCakePopExporter()); +``` + +Now your gateway will send the telemetry data to Banana Cake Pop. To connect your subgraphs to the gateway, you need to add an extension to your `subgraph-config.json`. You need to specify the `apiId` of the subgraph +```json +{ + "subgraph": "Order", + "http": { "baseAddress": "http://localhost:59093/graphql" }, + "extensions": { + "bcp": { + "apiId": "QXBpCmc4ZjdhZTUxYjE5YTY0ZjFiYjcwNTc3NjJkMDkzOTg2Nw==" + } + } +} +``` diff --git a/website/src/docs/bananacakepop/v2/images/apis-0.png b/website/src/docs/bananacakepop/v2/apis/images/apis-0.png similarity index 100% rename from website/src/docs/bananacakepop/v2/images/apis-0.png rename to website/src/docs/bananacakepop/v2/apis/images/apis-0.png diff --git a/website/src/docs/bananacakepop/v2/images/apis-1.png b/website/src/docs/bananacakepop/v2/apis/images/apis-1.png similarity index 100% rename from website/src/docs/bananacakepop/v2/images/apis-1.png rename to website/src/docs/bananacakepop/v2/apis/images/apis-1.png diff --git a/website/src/docs/bananacakepop/v2/apis/images/apis-2.png b/website/src/docs/bananacakepop/v2/apis/images/apis-2.png new file mode 100644 index 00000000000..d4fcf5e529f Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/apis-2.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/apis-3.png b/website/src/docs/bananacakepop/v2/apis/images/apis-3.png new file mode 100644 index 00000000000..ed42a974e82 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/apis-3.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/apis-4.png b/website/src/docs/bananacakepop/v2/apis/images/apis-4.png new file mode 100644 index 00000000000..8b04526a7bc Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/apis-4.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/apis-5.png b/website/src/docs/bananacakepop/v2/apis/images/apis-5.png new file mode 100644 index 00000000000..28dc6b03f9a Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/apis-5.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/apis-6.png b/website/src/docs/bananacakepop/v2/apis/images/apis-6.png new file mode 100644 index 00000000000..88d81633c50 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/apis-6.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/client-registry-1.png b/website/src/docs/bananacakepop/v2/apis/images/client-registry-1.png new file mode 100644 index 00000000000..0706838495c Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/client-registry-1.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/client-registry-2.png b/website/src/docs/bananacakepop/v2/apis/images/client-registry-2.png new file mode 100644 index 00000000000..06d0d00a305 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/client-registry-2.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/fusion-0.png b/website/src/docs/bananacakepop/v2/apis/images/fusion-0.png new file mode 100644 index 00000000000..c984b94f13d Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/fusion-0.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/fusion-1.png b/website/src/docs/bananacakepop/v2/apis/images/fusion-1.png new file mode 100644 index 00000000000..0da92c3b8cb Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/fusion-1.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/fusion-2.png b/website/src/docs/bananacakepop/v2/apis/images/fusion-2.png new file mode 100644 index 00000000000..412af181a21 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/fusion-2.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/fusion-3.png b/website/src/docs/bananacakepop/v2/apis/images/fusion-3.png new file mode 100644 index 00000000000..a79cae61cd2 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/fusion-3.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/fusion-4.png b/website/src/docs/bananacakepop/v2/apis/images/fusion-4.png new file mode 100644 index 00000000000..747b3acbf6b Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/fusion-4.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/fusion-5.png b/website/src/docs/bananacakepop/v2/apis/images/fusion-5.png new file mode 100644 index 00000000000..2a1f0a711b3 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/fusion-5.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/operation-reporting-1.png b/website/src/docs/bananacakepop/v2/apis/images/operation-reporting-1.png new file mode 100644 index 00000000000..7da05902c13 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/operation-reporting-1.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/operation-reporting-2.png b/website/src/docs/bananacakepop/v2/apis/images/operation-reporting-2.png new file mode 100644 index 00000000000..d384b8f2f8c Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/operation-reporting-2.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/schema-registry-0.png b/website/src/docs/bananacakepop/v2/apis/images/schema-registry-0.png new file mode 100644 index 00000000000..c4f47afb5d5 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/schema-registry-0.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/schema-registry-1.png b/website/src/docs/bananacakepop/v2/apis/images/schema-registry-1.png new file mode 100644 index 00000000000..8aad1194fa4 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/schema-registry-1.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/schema-registry-2.png b/website/src/docs/bananacakepop/v2/apis/images/schema-registry-2.png new file mode 100644 index 00000000000..b3af8fef447 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/schema-registry-2.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/stages-0.png b/website/src/docs/bananacakepop/v2/apis/images/stages-0.png new file mode 100644 index 00000000000..e54a5ff156b Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/stages-0.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/stages-1.png b/website/src/docs/bananacakepop/v2/apis/images/stages-1.png new file mode 100644 index 00000000000..d467571945b Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/stages-1.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/stages-2.png b/website/src/docs/bananacakepop/v2/apis/images/stages-2.png new file mode 100644 index 00000000000..4bc71387fae Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/stages-2.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/stages-3.png b/website/src/docs/bananacakepop/v2/apis/images/stages-3.png new file mode 100644 index 00000000000..d2f2d566979 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/stages-3.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-0.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-0.png new file mode 100644 index 00000000000..4cd0ac0e849 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-0.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-1.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-1.png new file mode 100644 index 00000000000..39a72b933d9 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-1.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-10.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-10.png new file mode 100644 index 00000000000..569870cdab7 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-10.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-11.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-11.png new file mode 100644 index 00000000000..3ee063cd050 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-11.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-12.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-12.png new file mode 100644 index 00000000000..9bca23bc6a6 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-12.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-13.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-13.png new file mode 100644 index 00000000000..1d305ceee4c Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-13.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-2.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-2.png new file mode 100644 index 00000000000..d698fe90cec Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-2.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-3.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-3.png new file mode 100644 index 00000000000..2b6f9659a2e Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-3.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-4.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-4.png new file mode 100644 index 00000000000..fbad19a62c7 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-4.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-5.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-5.png new file mode 100644 index 00000000000..8b71132f664 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-5.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-6.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-6.png new file mode 100644 index 00000000000..9dd376a14a4 Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-6.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-7.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-7.png new file mode 100644 index 00000000000..76a7faec2cf Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-7.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-8.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-8.png new file mode 100644 index 00000000000..bc7fceea7cd Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-8.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/images/telemetry-9.png b/website/src/docs/bananacakepop/v2/apis/images/telemetry-9.png new file mode 100644 index 00000000000..67d74baafdc Binary files /dev/null and b/website/src/docs/bananacakepop/v2/apis/images/telemetry-9.png differ diff --git a/website/src/docs/bananacakepop/v2/apis/open-telemetry.md b/website/src/docs/bananacakepop/v2/apis/open-telemetry.md new file mode 100644 index 00000000000..4736b4ff6a4 --- /dev/null +++ b/website/src/docs/bananacakepop/v2/apis/open-telemetry.md @@ -0,0 +1,134 @@ +--- +title: "Open Telemetry" +--- + +![Image](images/telemetry-0.png) +Banana Cake Pop can collect your open telemetry data and visualize your traces in the app. +With telemetry you can get a better understanding of how your application is performing and where you can improve it. + +![Image](images/telemetry-1.png) +It helps you to understand which resolver is impacting your system the most, which queries are slow and which are fast and deeply analyze each trace to your system. + +## Connect your service to the telemetry system + +All the reporting is done on a per API basis. An api represents one of your deployments. To monitor you services you need to create an API in banana cake pop. +The api needs to be from type "Api Service" or "Api Gateway". + +To install the Banana Cake Pop services, run the following commands in your project's root directory: + +```bash +dotnet add package BananaCakePop.Services +dotnet add package OpenTelemetry.Extensions.Hosting +dotnet add package OpenTelemetry.Instrumentation.AspNetCore +``` + +After installing the package, you need to configure the services in your startup class. Below is a sample implementation in C#: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services + .AddGraphQLServer() + .AddQueryType() + .AddBananaCakePopServices(x => + { + x.ApiKey = "<>"; + x.ApiId = "QXBpCmc5NGYwZTIzNDZhZjQ0NjBmYTljNDNhZDA2ZmRkZDA2Ng=="; + x.Stage = "dev"; + }) + .AddInstrumentation(); // Enable the graphql telemetry + + services + .AddOpenTelemetry() + .WithTracing(x => + { + x.AddAspNetCoreInstrumentation(); + x.AddBananaCakePopExporter(); + }); +} +``` + +> **Tipp: Using Environment Variables** +> +> Alternatively, you can set the required values using environment variables. This method allows you to call `AddBananaCakePopServices` without explicitly passing parameters. +>- `BCP_API_KEY` maps to `ApiKey` +>- `BCP_API_ID` maps to `ApiId` +>- `BCP_STAGE` maps to `Stage` +>```csharp +>public void ConfigureServices(IServiceCollection services) +>{ +> services +> .AddGraphQLServer() +> .AddQueryType() +> .AddBananaCakePopServices() +> .AddInstrumentation(); // Enable the graphql telemetry +> +> services +> .AddOpenTelemetry() +> .WithTracing(x => +> { +> x.AddAspNetCoreInstrumentation(); +> x.AddBananaCakePopExporter(); +> }); +>} +>``` +>In this setup, the API key, ID, and stage are set through environment variables. + + +# Monitoring Dashboard +The monitoring dashboard in Banana Cake Pop offers various metrics and visualizations to understand your service's performance better. + +## Changing the time range +![Image](images/telemetry-2.png) +You can change the time range of the dashboard by clicking on the time range selector in the top right corner of the dashboard. +You can either customize the time range or select one of the predefined ranges. + +## Latency +![Image](images/telemetry-3.png) +The latency graph shows the average latency of your service over time. You can also see the 95th and the 99th percentile of the latency. + +## Throughput +![Image](images/telemetry-4.png) +The throughput graph shows you the operations per minute over time. You can see how many operations are executed on your service and how many of them failed. + +## Clients +![Image](images/telemetry-5.png) +You can track how many requests are done by each client. This helps you to understand which client is impacting your system the most. +To track this, your clients need to send two headers with each request: + +- `GraphQL-Client-Id` - The id of the client. You can get the id from the client by execution `barsita client list` in your terminal. +- `GraphQL-Client-Version` - The version of the client + +## Errors +![Image](images/telemetry-6.png) +Shows you the number of operations with errors over time. + +## Insights +![Image](images/telemetry-7.png) +This insights show you a list of executed operations. You can see the latency, the throughput and also how many percent of the operations had errors. You also have a column impact, which will help you to understand which operations are impacting your system the most. You can sort the columns by clicking on the column header. + +By clicking on an operation, you can see the telemetry information about the operation and it's traces. + +![Image](images/telemetry-8.png) +On the top right corner you can change from the operation insights to the resolver insights view. + +# Operation Dashboard +![Image](images/telemetry-9.png) +You can drill down into the telemetry information of a single operation by clicking on it in the insights view. + +## Latency Error and Throughput +Theses graphs show you the latency, error rate and throughput of the selected operation over time similar to the graphs on the monitoring dashboard. + +## Latency Distribution +![Image](images/telemetry-10.png) +This graph shows you the distribution of different traces of the selected operation. This way you can quickly see outliers and understand how the operation is performing. + +![Image](images/telemetry-11.png) +You can also select a time range in the graph. This selection will impact which traces are shown in the trace table. You can for example select the slow operations on the right and inspect why they are slow. + +## Traces +![Image](images/telemetry-12.png) +On the very bottom of the page you see sample traces of the selected operation with all of the spans. + +If you click on a trace, the sidebar will show additional information about the trace including all the attributes of it. +![Image](images/telemetry-13.png) diff --git a/website/src/docs/bananacakepop/v2/apis/operation-reporting.md b/website/src/docs/bananacakepop/v2/apis/operation-reporting.md new file mode 100644 index 00000000000..15830ee8745 --- /dev/null +++ b/website/src/docs/bananacakepop/v2/apis/operation-reporting.md @@ -0,0 +1,61 @@ +--- +title: "Operation Reporting" +--- + +![Image](images/operation-reporting-1.png) + +Banana Cake Pop's Operation Reporting feature provides comprehensive insights into the GraphQL operations executed on your server. This functionality is essential for maintaining visibility over server activities, including both persisted and executed operations. By leveraging Operation Reporting, developers and system administrators can gain a clearer understanding of what operations are executed and available on the server. + +# Enabling Operation Reporting + +Operation Reporting is an integrated feature in Banana Cake Pop and is enabled by default when using Banana Cake Pop services. To integrate these services into your project, the [`BananaCakePop.Services`](https://www.nuget.org/packages/BananaCakePop.Services/) NuGet package must be added. + +To install the Banana Cake Pop services, run the following command in your project's root directory: + +```bash +dotnet add package BananaCakePop.Services +``` + +After installing the package, you need to configure the services in your startup class. Below is a sample implementation in C#: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services + .AddGraphQLServer() + .AddQueryType() + .AddBananaCakePopServices(x => + { + x.ApiKey = "<>"; + x.ApiId = "QXBpCmc5NGYwZTIzNDZhZjQ0NjBmYTljNDNhZDA2ZmRkZDA2Ng=="; + x.Stage = "dev"; + }); +} +``` + +> **Tipp: Using Environment Variables** +> +> Alternatively, you can set the required values using environment variables. This method allows you to call `AddBananaCakePopServices` without explicitly passing parameters. +>- `BCP_API_KEY` maps to `ApiKey` +>- `BCP_API_ID` maps to `ApiId` +>- `BCP_STAGE` maps to `Stage` +>```csharp +>public void ConfigureServices(IServiceCollection services) +>{ +> services +> .AddGraphQLServer() +> .AddQueryType() +> .AddBananaCakePopServices() +>} +>``` +>In this setup, the API key, ID, and stage are set through environment variables. + +# Viewing Reported Operations + +Once Operation Reporting is enabled and configured, all GraphQL operations processed by your server will be reported to Banana Cake Pop. These operations can be viewed and analyzed in the `Operations` tab within the Banana Cake Pop interface. + +![Image](images/operation-reporting-2.png) +1. Click the `Operations` tab in Banana Cake Pop to view the list of reported operations. +2. The name of the executed operation. +3. Click on `V` to expand the operation and view the details. +4. The document id of the persisted operation. diff --git a/website/src/docs/bananacakepop/v2/apis/overview.md b/website/src/docs/bananacakepop/v2/apis/overview.md new file mode 100644 index 00000000000..bbac3578946 --- /dev/null +++ b/website/src/docs/bananacakepop/v2/apis/overview.md @@ -0,0 +1,35 @@ +--- +title: Apis +--- + +![Image](images/apis-6.png) +An API within the context of Banana Cake Pop, refers to an representation of your GraphQL Servers. +This representation is more than a mere conceptual framework — it serves as a practical tool that allows you to group your documents and share common settings like connection and authorization parameters among them. + +Additionally, an API forms the foundation for your client registry, schema registry setup and the telemetry. For more detailed information on these features, refer to the [Schema & Client Registry](/docs/bananacakepop/v2/schema-client-registry) guide and the [Telemetry](/docs/bananacakepop/v2/telemetry) guide. + + +# API Types +![Image](images/apis-2.png) + +## API Collection +![Image](images/apis-5.png) + +A compilation of GraphQL Documents with shared connection settings, enabling the grouping of documents for sharing with your t. + +## API Service +![Image](images/apis-3.png) +Incorporates all features of an API Collection and adds the capability to register your schema and clients in the schema registry. It also includes the use of telemetry for service monitoring. This type is ideal for representing a single deployment service or a subgraph. + +## API Gateway +![Image](images/apis-4.png) +Encompasses all the features of the API Service, along with the ability to publish and manage fusion configuration. Additionally, it supports distributed telemetry for comprehensive monitoring of your Gateway. + +# Creating an API +![Image](images/apis-1.png) + +Creating an API in Banana Cake Pop is a user-friendly process. There are three methods available: + +1. Click on the `Create Api` button located at the top of the document explorer toolbar. +2. Right-click within the document explorer and select `New Api` from the context menu. This creates a new API within the currently selected folder. Note: APIs can be organized in folders but cannot be nested within each other. +3. Choose the API Type. Options include `API Collection`, `API Service`, or `API Gateway`. diff --git a/website/src/docs/bananacakepop/v2/apis/schema-registry.md b/website/src/docs/bananacakepop/v2/apis/schema-registry.md new file mode 100644 index 00000000000..343a59d56e4 --- /dev/null +++ b/website/src/docs/bananacakepop/v2/apis/schema-registry.md @@ -0,0 +1,118 @@ +--- +title: "Schema & Client Registry" +--- + +![Image](images/schema-registry-0.png) +The schema registries is an essential tool for managing your GraphQL APIs. It provides a centralized location for storing, managing, and distributing your GraphQL schema definitions. + +With the schema registry, you can upload and store the schema of your API, making it accessible to your development team and other services. + +![Image](images/schema-registry-1.png) +The schema registry enables you to validate your schemas and clients against previous versions, ensuring that changes to your service do not break existing functionality, deeply integrated into your CI/CD pipeline. + +![Image](images/schema-registry-2.png) +They also maintain a version history, allowing you to track changes over time and revert to previous versions if necessary. + +Together with the client registry, you can maintain the integrity of your API and the services that rely on it, ensuring that they can evolve together without breaking. + +# Understanding Schemas + +In the context of GraphQL APIs, a schema is the blueprint that defines the shape of your data and specifies the capabilities of the API. It outlines the types of queries and mutations that can be executed against your API. + +A schema is more than just a technical specification; it is a contract between your API and your clients. By understanding and managing schema changes, you can ensure that this contract remains valid and that your API and clients can evolve together without breaking. + +Each stage of your API can have one active schema. This active schema is the one against which all requests are validated. + +## Schema Changes + +Changes to the schema can be categorized into three levels of severity based on their potential impact on the clients: safe, dangerous, and breaking. + +1. **Safe**: These changes don't affect the existing functionality. Examples include changes to descriptions or adding a new optional field to a type. Safe changes are generally backward compatible and don't require modifications to existing clients. + +Examples are: +- Adding a new field to an object type +- Adding a new optional argument to a field or directive +- Adding a new type + +2. **Dangerous**: These changes could potentially break existing functionality, depending on how your consumers interact with your API. An example of a dangerous change is adding a new member to an enum. If the client is not prepared to handle the new member, it might result in unexpected behavior. + +Examples are: +- Adding a new member to an enum +- Adding a new implementation to an interface + +3. **Breaking**: These changes will break existing functionality if the affected parts of the schema are being used by clients. Examples include changing the type of a field, adding a required field to an input type, removing a field, or adding a new required argument to a field or directive. + +Examples are: +- Removing a field from an object type +- Changing the type of a field +- Change a non-null field to a nullable field + +Breaking changes need to be managed with care to avoid disruptions to the service. It's important to ensure that all clients can handle these changes before they are introduced. This can be accomplished by versioning your clients and managing the lifecycle of client versions, as described in the section [Understanding Clients](#understanding-clients)]. + +## Extracting the Schema + +Extracting your GraphQL API's schema can be beneficial for various purposes, such as documentation, testing, and version control. Here are some methods to extract the schema: + +### Using Schema Export Command + +One of the simplest ways to extract the schema is by using the `schema export` command. This command exports your current schema into a specified output file. + +```shell +dotnet run -- schema export --output schema.graphql +``` + +For more details about this command and how to setup the command line extension, please refer to the [Command Line Extension documentation](/docs/hotchocolate/v13/server/command-line). + +### Utilizing Snapshot Testing + +If you have already established snapshot testing in your workflow, you can use it to extract the schema. Snapshot tests compare the current schema against a previously saved one. If the schemas differ, the test fails, ensuring unintentional schema changes are detected. + +Additionally, keeping a snapshot test in the repository aids in visualizing schema changes in pull requests. + +Here is a sample snapshot test using [Snapshooter](https://github.com/SwissLife-OSS/snapshooter): + +```csharp +[Fact] +public async Task Schema_Should_Not_Change() +{ + // Arrange + var executor = await new ServiceCollection() + .AddGraphQL() + .AddYourSchema() + .BuildRequestExecutorAsync(); + + // Act + var schema = executor.Schema.Print(); + + // Assert + schema.MatchSnapshot(); +} +``` +# Setting Up a Schema Registry + +To set up a schema registry, first, visit `eat.bananacakepop.com` and sign up for an account. Next, you'll need to download and install Barista, the .NET tool used to manage your schema registry. You can find more information about Barista in the [Barista Documentation](/docs/barista/v1). + +After installing Barista, create a new API either through the Bananacakepop UI or the CLI. In the UI, simply right-click the document explorer and select "New API." If you prefer using the CLI, ensure you're logged in with the command `barista login`, then create a new API with the command `barista api create`. With these steps complete, you are ready to start using the schema registry. + +To get the id of your API, use the command `barista api list`. This command will list all of your APIs, their names, and their ids. You will need the id of your API to perform most operations on the schema registry. + +# Integrating with Continuous Integration + +Integrating the schema registry and into your Continuous Integration/Continuous Deployment (CI/CD) pipeline maximizes their benefits. It ensures that the schemas in your API are always up-to-date and tested against potential breaking changes. + +To interact with the schema registry from the pipeline, you will need a API key. You can generate an api key directly with Barista using the command `barista api-key create`. Make sure to copy the key and store it in a secure location. The key will not be displayed again. + +You can then use the key to authenticate with the schema registry using the `--api-key` option. + +The schema and client registries work hand-in-hand to ensure the smooth functioning of your API. As you make changes to your schema, the schema registry helps manage these changes, preventing inadvertent breaking changes and preserving a history of your schemas. As you validate, upload, and publish new schemas, the client registry ensures that your clients remain compatible with these changes. + +## Understanding the Flow + +The general flow for the schema registry involves three main steps: validating the schema, uploading it to the registry, and publishing it. + +1. **Validate the Schema **: The first step takes place during your Pull Request (PR) build. Here, you validate the schema against the API using the `barista schema validate` command. This ensures that the schema is compatible with the API and will not break existing functionality. + +2. **Upload the Schema**: The second step takes place during your release build. Here, you upload the schema to the registry using the `barista schema upload` command. This command requires the `--tag` and `--api-id` options. The `--tag` option specifies the tag for the schema, and the `--api-id` option specifies the ID of the API to which you are uploading. This command create a new version of the schema with the specified tag. +The tag is a string that can be used to identify the schema. It can be any string, but it is recommended to use a version number, such as `v1` or `v2`; or a commit hash, such as `a1b2c3d4e5f6g7h8i9j0k1l2m3n`. The tag is used to identify the schema when publishing it. + +3. **Publish the Schema **: The third step takes place just before the release. Here, you publish the schema using the `barista schema publish` command. This command requires the `--tag` and `--api-id` options. The `--tag` option specifies the tag for the schema, and the `--api-id` option specifies the ID of the API to which you are uploading. This command publishes the schema with the specified tag, making it the active version for the specified API. diff --git a/website/src/docs/bananacakepop/v2/apis/stages.md b/website/src/docs/bananacakepop/v2/apis/stages.md new file mode 100644 index 00000000000..6f81ad606ed --- /dev/null +++ b/website/src/docs/bananacakepop/v2/apis/stages.md @@ -0,0 +1,59 @@ +--- +title: Stages +--- + +# Working with Stages + +![Screenshot of the Stages overview](images/stages-0.png) +A stage represents an environment of your service, such as development, staging, or production. Each stage can have an active schema and multiple active client versions. + +Stages are integral to the lifecycle management of your GraphQL APIs. They enable you to manage different environments of your service, such as development, staging, or production. Each stage can have an active schema, multiple active client versions and telemetry reports. The active schema and client versions for a stage represent the current state of your API for that environment. + +Stages in your development workflow can be arranged sequentially to represent progression of changes. For instance, in a simple flow like Development (Dev) - Quality Assurance (QA) - Production (Prod), each stage comes "after" the preceding one. This signifies that changes propagate from "Dev" to "QA", and finally to "Prod" + +## Managing Stages + +If you do not have stages yet, you can go the the `Stages` tab and click on `Use default stages`. This will add a stage `Development` and a stage `Production` to your service. + +![Screenshot of the Stages overview](images/stages-1.png) +You can always edit these stages or add new ones by clicking the `Edit Stages` button. +![Screenshot of the Stages overview](images/stages-2.png) + +The stages dialog allows you to add and edit stages. You can also delete stages, but only if they are not used by any client or schema. + +Stages are edited in a yaml editor. The default configuration looks like this: + +```yaml +dev: # define a stage by adding the identifier as a root node + displayName: Development # add a display name to a stage +prod: + displayName: Production + conditions: + - after: dev # this defines the connection to other stages. production comes after development +``` + +You can easily create more complex stage configurations. For example, if you have two different QA stages, you can define them like this: + +```yaml +dev: + displayName: Development +qa1: + displayName: QA 1 + conditions: + - after: dev +qa2: + displayName: QA 2 + conditions: + - after: dev +prod: + displayName: Production + conditions: + - after: qa1 + - after: qa2 +``` + +This configuration defines two QA stages, `QA 1` and `QA 2`. Both of them come after the `Development` stage. The `Production` stage comes after both QA stages. It will result in the following stage order: + +![Image](images/stages-3.png) + + diff --git a/website/src/docs/bananacakepop/v2/bcp-services.md b/website/src/docs/bananacakepop/v2/bcp-services.md index d64219eb01d..86ec77eac0c 100644 --- a/website/src/docs/bananacakepop/v2/bcp-services.md +++ b/website/src/docs/bananacakepop/v2/bcp-services.md @@ -2,7 +2,7 @@ title: Connect you API --- -BananaCake Pop can be smoothly integrated into your HotChocolate server, enabling utilization of the Persisted Query Storage found within the client registry. Your server will establish a connection with BananaCake Pop, retrieving persisted queries based on their unique hashes. Additional information on the client registry can be found [here](/docs/bananacakepop/v2/schema-client-registry). +BananaCake Pop can be smoothly integrated into your HotChocolate server, enabling utilization of the Persisted Query Storage found within the client registry, to report operations and collect open telemetry. Your server will establish a connection with BananaCake Pop, retrieving persisted queries based on their unique hashes. Additional information on the client registry can be found [here](/docs/bananacakepop/v2/schema-client-registry). ## Getting Started To get started, follow these steps: diff --git a/website/src/docs/bananacakepop/v2/schema-client-registry/index.md b/website/src/docs/bananacakepop/v2/schema-client-registry/index.md deleted file mode 100644 index dfb28a98da3..00000000000 --- a/website/src/docs/bananacakepop/v2/schema-client-registry/index.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: "Schema & Client Registry" ---- - -The schema and client registries are essential tools for managing your GraphQL APIs. They provide a centralized location for storing, managing, and distributing your GraphQL schema and client definitions. - -With the schema registry, you can upload and store the schema of your API, making it accessible to your development team and other services. In parallel, the client registry allows you to manage the clients of your API, each of which can have multiple versions. A version here refers to a collection of query documents. - -The registries enable you to validate your schemas and clients against previous versions, ensuring that changes to your service do not break existing functionality. They also maintain a version history, allowing you to track changes over time and revert to previous versions if necessary. - -By working harmoniously, the schema and client registries help maintain the integrity of your API and the services that rely on it, ensuring that they can evolve together without breaking. - -# Understanding Schemas - -In the context of GraphQL APIs, a schema is the blueprint that defines the shape of your data and specifies the capabilities of the API. It outlines the types of queries and mutations that can be executed against your API. -A schema is more than just a technical specification; it is a contract between your API and your clients. By understanding and managing schema changes, you can ensure that this contract remains valid and that your API and clients can evolve together without breaking. - -Each stage of your API can have one active schema. This active schema is the one against which all requests are validated. - -## Schema Changes - -Changes to the schema can be categorized into three levels of severity based on their potential impact on the clients: safe, dangerous, and breaking. - -1. **Safe**: These changes don't affect the existing functionality. Examples include changes to descriptions or adding a new optional field to a type. Safe changes are generally backward compatible and don't require modifications to existing clients. - -2. **Dangerous**: These changes could potentially break existing functionality, depending on how your consumers interact with your API. An example of a dangerous change is adding a new member to an enum. If the client is not prepared to handle the new member, it might result in unexpected behavior. - -3. **Breaking**: These changes will break existing functionality if the affected parts of the schema are being used by clients. Examples include changing the type of a field, adding a required field to an input type, removing a field, or adding a new required argument to a field or directive. - -Breaking changes need to be managed with care to avoid disruptions to the service. It's important to ensure that all clients can handle these changes before they are introduced. This can be accomplished by versioning your clients and managing the lifecycle of client versions, as described in the section [Understanding Clients](#understanding-clients)]. - -## Extracting the Schema - -Extracting your GraphQL API's schema can be beneficial for various purposes, such as documentation, testing, and version control. Here are some methods to extract the schema: - -### Using Schema Export Command - -One of the simplest ways to extract the schema is by using the `schema export` command. This command exports your current schema into a specified output file. - -```shell -dotnet run -- schema export --output schema.graphql -``` - -For more details about this command and how to setup the command line extension, please refer to the [Command Line Extension documentation](/docs/hotchocolate/v13/server/command-line). - -### Utilizing Snapshot Testing - -If you have already established snapshot testing in your workflow, you can use it to extract the schema. Snapshot tests compare the current schema against a previously saved one. If the schemas differ, the test fails, ensuring unintentional schema changes are detected. - -Additionally, keeping a snapshot test in the repository aids in visualizing schema changes in pull requests. - -Here is a sample snapshot test using [Snapshooter](https://github.com/SwissLife-OSS/snapshooter): - -```csharp -[Fact] -public async Task Schema_Should_Not_Change() -{ - // Arrange - var executor = await new ServiceCollection() - .AddGraphQL() - .AddYourSchema() - .BuildRequestExecutorAsync(); - - // Act - var schema = executor.Schema.Print(); - - // Assert - schema.MatchSnapshot(); -} -``` - -# Understanding Clients - -A client, in the context of a GraphQL API, is an entity that interacts with the API by defining and executing GraphQL operations. These operations are stored on the API as persisted queries. - -## What is a Persisted Query? - -A persisted query is a GraphQL operation that has been sent to the server, stored, and assigned an unique identifier (hash). Instead of sending the full text of a GraphQL operation to the server for execution, clients can send the hash of the operation, reducing the amount of data transmitted over the network. This practice is particularly beneficial for mobile clients operating in environments with limited network capacity. - -Persisted queries also add an extra layer of security as the server can be configured to only execute operations that have been previously stored, which prevents malicious queries. This is the cheapest and most effective way to secure your GraphQL API from potential attacks. - -## The Role of the Client Registry - -The client registry plays a crucial role in managing these persisted queries. It is used to validate the queries against the schema, ensuring that all the operations defined by a client are compatible with the current schema. This validation step is critical to prevent the execution of invalid queries that might result in runtime errors. - -Additionally, the client registry is responsible for distributing the queries to the GraphQL server. It maintains a mapping of hashes to query keys, informing the server which hash corresponds to which query. This allows the server to efficiently look up and execute the appropriate query when it receives a request from a client. - -## Client Versions - -A client can have multiple versions, with each version containing a different set of persisted queries. This versioning system allows for incremental updates and changes to the client's operations without disrupting the existing functionality. As new versions are released, they can be validated and registered with the client registry, ensuring that they are compatible with the current schema and can be executed by the server. - -By managing client versions and persisted queries, the client registry helps maintain the integrity and smooth operation of your GraphQL API. It ensures that your clients and API can evolve together without breaking, contributing to a more robust and reliable system. - -The number of active client versions can vary depending on the nature of the client. For instance, a website usually has one active client version per stage. However, during deployment, you might temporarily have two active versions as the new version is phased in and the old version is phased out. - -On the other hand, for mobile clients, you often have multiple versions active simultaneously. This is because users may be using different versions of the app, and not all users update their apps at the same time. - -Once a client version is no longer in use, it reaches its end of life. At this point, you can unpublish the client version from the client registry. This will remove its persisted queries from distribution, and they will no longer be validated against the schema. - -## The Operations File - -In the context of GraphQL, the operations file is a structured file that holds a collection of persisted queries for a client. This file serves as a reference for the client to manage and execute specific operations against a GraphQL API. - -### Understanding the Format and Structure - -The operations file typically adopts the JSON format as used by Relay. It comprises key-value pairs, with each pair representing a unique persisted query. The key corresponds to a hash identifier for the query, and the value is the GraphQL query string. Below is an illustrative example of an operations file (`operations.json`): - -```json -{ - "913abc361487c481cf6015841c0eca22": "{ me { username } }", - "0e7cf2125e8eb711b470cc72c73ca77e": "{ me { id } }" - ... -} -``` - -### Compatibility with GraphQL Clients - -Several GraphQL clients have built-in support for this Relay-style operations file format. This compatibility allows for a standardized way of handling persisted queries across different clients. For more details on how various clients implement and work with persisted queries, consider referring to their respective documentation: - -- [StrawberryShake](https://chillicream.com/docs/strawberryshake/v13/performance/persisted-queries) -- [URQL](https://formidable.com/open-source/urql/docs/advanced/persisted-queries/) -- [Relay](https://relay.dev/docs/guides/persisted-queries/) - -# Working with Stages -A stage represents an environment of your service, such as development, staging, or production. Each stage can have an active schema and multiple active client versions. - -Stages are integral to the lifecycle management of your GraphQL APIs. They enable you to manage different environments of your service, such as development, staging, or production. Each stage can have an active schema and multiple active client versions. The active schema and client versions for a stage represent the current state of your API for that environment. - -Stages in your development workflow can be arranged sequentially to represent progression of changes. For instance, in a simple flow like Development (Dev) - Quality Assurance (QA) - Production (Prod), each stage comes "after" the preceding one. This signifies that changes propagate from "Dev" to "QA", and finally to "Prod" - -## Managing Stages - -To manage stages, you'll use the `barista stage edit` command. After executing this command, you first select the API you want to modify. Then, you can add, edit, or delete stages using the provided interface. - -The interface displays a table showing the current stages, their names, and their order (defined in the 'After' column). Utilize the provided keys to add a new stage, save changes, edit a stage, or delete a stage. - -When you add or edit a stage, you'll need to provide a name for the stage and specify where it should be placed in the order of stages. When you delete a stage, be aware that this will also remove the active schema and client versions for that stage. - -# Setting Up a Schema Registry - -To set up a schema registry, first, visit `eat.bananacakepop.com` and sign up for an account. Next, you'll need to download and install Barista, the .NET tool used to manage your schema registry. You can find more information about Barista in the [Barista Documentation](/docs/barista/v1). - -After installing Barista, create a new API either through the Bananacakepop UI or the CLI. In the UI, simply right-click the document explorer and select "New API." If you prefer using the CLI, ensure you're logged in with the command `barista login`, then create a new API with the command `barista api create`. With these steps complete, you are ready to start using the schema registry. - -To get the id of your API, use the command `barista api list`. This command will list all of your APIs, their names, and their ids. You will need the id of your API to perform most operations on the schema registry. - -# Integrating with Continuous Integration - -Integrating the schema registry and the client registry into your Continuous Integration/Continuous Deployment (CI/CD) pipeline maximizes their benefits. It ensures that the schemas and clients in your API are always up-to-date and tested against potential breaking changes. - -The schema and client registries work hand-in-hand to ensure the smooth functioning of your API. As you make changes to your schema, the schema registry helps manage these changes, preventing inadvertent breaking changes and preserving a history of your schemas. As you validate, upload, and publish new schemas, the client registry ensures that your clients remain compatible with these changes. - -As you release new versions of your clients, the client registry helps manage these versions and the query documents associated with them. By working together, the schema and client registries help maintain the integrity of your API and the services that rely on it, ensuring that they can evolve together without breaking. - -## Understanding the Flow - -The general flow for the schema registry involves three main steps: validating the schema, uploading it to the registry, and publishing it. - -1. **Validate the Schema / Client**: The first step takes place during your Pull Request (PR) build. Here, you validate the schema or client against the API using the `barista schema validate` or `barista client validate` commands. This ensures that the schema or client is compatible with the API and will not break existing functionality. - -2. **Upload the Schema / Client**: The second step takes place during your release build. Here, you upload the schema or client to the registry using the `barista schema upload` or `barista client upload` commands. This command requires the `--tag` and `--api-id` options. The `--tag` option specifies the tag for the schema or client, and the `--api-id` option specifies the ID of the API to which you are uploading. This command create a new version of the schema or client with the specified tag. -The tag is a string that can be used to identify the schema or client. It can be any string, but it is recommended to use a version number, such as `v1` or `v2`; or a commit hash, such as `a1b2c3d4e5f6g7h8i9j0k1l2m3n`. The tag is used to identify the schema or client when publishing it. - -3. **Publish the Schema / Client **: The third step takes place just before the release. Here, you publish the schema or client using the `barista schema publish` or `barista client publish` commands. This command requires the `--tag` and `--api-id` options. The `--tag` option specifies the tag for the schema or client, and the `--api-id` option specifies the ID of the API to which you are uploading. This command publishes the schema or client with the specified tag, making it the active version for the specified API. diff --git a/website/src/docs/docs.json b/website/src/docs/docs.json index fcf195b70b4..3a745d815a8 100644 --- a/website/src/docs/docs.json +++ b/website/src/docs/docs.json @@ -42,7 +42,25 @@ }, { "path": "apis", - "title": "Apis" + "title": "Apis", + "items": [ + { "path": "overview", "title": "Overview" }, + { "path": "stages", "title": "Stages" }, + { "path": "fusion", "title": "Fusion" }, + { + "path": "schema-registry", + "title": "Schema Registry" + }, + { + "path": "client-registry", + "title": "Client Registry" + }, + { + "path": "operation-reporting", + "title": "Operation Reporting" + }, + { "path": "open-telemetry", "title": "Open Telemetry" } + ] }, { "path": "environments", @@ -56,10 +74,6 @@ "path": "organizations", "title": "Organizations" }, - { - "path": "schema-client-registry", - "title": "Schema & Client Registry" - }, { "path": "bcp-services", "title": "Connect you API"