<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://chillicream.com</id>
    <title>ChilliCream Blog</title>
    <updated>2026-02-06T10:49:50.509Z</updated>
    <generator>ChilliCream</generator>
    <author>
        <name>ChilliCream</name>
        <uri>https://chillicream.com</uri>
    </author>
    <link rel="alternate" href="https://chillicream.com"/>
    <link rel="self" href="https://chillicream.com/atom.xml"/>
    <subtitle>We help companies and developers to build next level APIs with GraphQL by providing them the right tooling.</subtitle>
    <logo>https://chillicream.com/favicon-32x32.png</logo>
    <icon>https://chillicream.com/favicon-32x32.png</icon>
    <rights>All rights reserved 2026, ChilliCream</rights>
    <category term="GraphQL"/>
    <category term="Products"/>
    <category term="Services"/>
    <entry>
        <title type="html"><![CDATA[Open Telemetry for All Your Services]]></title>
        <id>https://chillicream.com/blog/2025/03/17/telemetry</id>
        <link href="https://chillicream.com/blog/2025/03/17/telemetry"/>
        <updated>2025-03-17T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
# Open Telemetry for All Your Services (and More!)

We’re thrilled to introduce **OpenTelemetry support for all your .NET-based services** - not just your GraphQL Servers. Whether you have REST APIs, background workers, or any other .NET applications, you can now unify and analyze your telemetry data in Nitro. This marks a significant step in helping you gain deeper insights across your entire infrastructure.

With **ChilliCream.Nitro.Telemetry** version 15.0.0 and 14.1.0, simply call the extension method `AddNitroTelemetry` in your service registration to integrate Nitro with any .NET service. All you need to do is configure OpenTelemetry exporters, and Nitro will collect and visualize your logs and traces:

```csharp
services.ConfigureOpenTelemetryTracerProvider(x => x.AddNitroExporter());
services.ConfigureOpenTelemetryLoggerProvider(x => x.AddNitroExporter());

services.AddNitroTelemetry(options =>
{
    options.ApiId = apiId;
    options.ApiKey = apiKey;
    options.Stage = stage;
});
```

On the trace overview of your API in the Nitro dashboard, select **OpenTelemetry** from the dropdown on the top right. You’ll be able to inspect all your HTTP requests, background workers, or anything else you’re tracking with OTEL. We’ve also **drastically improved telemetry performance**, so these insights will load and refresh faster than ever.

![Telemetry Overview](./otel1.png)

In this post, you’ll also learn about:

- **Personal Access Tokens (PATs)**, which bring more secure and granular authentication options to your automation workflows.
- **Enhanced Non-Interactive Command Execution** in the Nitro CLI, enabling full automation for API lifecycle tasks.
- The difference between **API Keys** and **PATs**, helping you choose the right authentication mechanism for every scenario.

Read on to discover how you can level up your .NET observability and API management automation, all within one powerful platform.

---

## Introducing Personal Access Tokens (PATs)

To provide more flexibility and security in your automation processes, we have introduced **Personal Access Tokens (PATs)**. PATs allow you to authenticate with the Nitro platform in a secure and granular manner, ideal for scripting and automated tasks.

### What are PATs?

Personal Access Tokens are tokens associated with your user account that grant access to the Nitro API.

- **Automation-Friendly**: PATs are perfect for use in CI/CD pipelines, scripts, and other automated workflows where you need to authenticate non-interactively.
- **User-Specific**: Unlike API keys tied to a specific API, PATs are linked to your user account, providing access across multiple APIs.

### How to Create a PAT

You can create a PAT using the following command:

```shell
nitro pat create --description "My Automation Token" --expires 180
```

- `--description`: A description for the token to help you identify it later.
- `--expires`: The number of days after which the token will expire (default is 180 days).

## Non-Interactive Command Execution

We have improved the Nitro CLI to support full non-interactive execution for all commands. This enhancement empowers you to automate every aspect of your API lifecycle management, from creating APIs and editing stages to generating API keys.

### Benefits of Non-Interactive Commands

- **Automation**: Integrate Nitro CLI commands into your scripts and CI/CD pipelines without manual intervention.
- **Consistency**: Ensure consistent execution of tasks across different environments.
- **Efficiency**: Automate repetitive tasks to save time and reduce human error.

### How to Use Commands Non-Interactively

All commands now accept input via command-line options or environment variables, allowing you to bypass interactive prompts. For example, to create an API non-interactively:

```shell
nitro api create --name "My API" --path "/my-api" --workspace-id "workspace123"
```

You can also set environment variables for inputs:

```shell
export NITRO_API_NAME="My API"
export NITRO_API_PATH="/my-api"
export NITRO_WORKSPACE_ID="workspace123"
nitro api create
```

### Parsing Command Output

By default, Nitro CLI provides human-readable output. When automating, you might need machine-readable output. Use the `--output json` option to get the output in JSON format:

```shell
nitro api-key list --output json
```

This output can then be parsed using tools like `jq`:

```shell
nitro api-key list --output json | jq '.'
```

## API Keys vs. PAT

**API Keys**

- **Purpose**: Designed for application-level authentication, such as telemetry reporting from your GraphQL server.
- **Scope**: Tied to a specific API and workspace.
- **Creation**: Generated using the `nitro api-key create` command.
- **Usage**: Best for telemetry, fusion, client registry, or other application-level tasks where you need to authenticate a specific API.

**Personal Access Tokens (PATs)**

- **Purpose**: Intended for user-level authentication, suitable for automating tasks that require broader access across APIs.
- **Scope**: Associated with your user account, has workspace permissions.
- **Creation**: Generated using the `nitro pat create` command.
- **Usage**: Best for scripts, automation tools, and CI/CD pipelines that need to perform various operations on the Nitro platform.

---

## Get Started Today

With **expanded OpenTelemetry integration**, **personal access tokens**, and **full non-interactive command support**, it’s never been easier to automate your API management workflows while simultaneously gaining comprehensive insights into your.NET services. Try out the improved telemetry overview, create your first PAT, and add Nitro to your automation pipelines to take full advantage of these new features.

### Need Help? We’ve Got You Covered!

Whether you’re integrating OpenTelemetry for the first time or looking to streamline your API automation, our **support contracts** provide expert guidance to help you get up and running quickly. From troubleshooting to best practices, our team is here to ensure your success. [Learn more about our support plans](https://chillicream.com/services/support) and get tailored assistance for your specific needs.

### Resources

- **Documentation**: Check out our [updated documentation](https://chillicream.com/docs/nitro) for a deeper look at the new commands and options.
- **Support**: If you have any questions or need assistance, feel free to reach out to our support team on slack!
]]></content>
        <author>
            <name>Pascal Senn</name>
            <uri>https://github.com/pascalsenn</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[What's new for Hot Chocolate 15]]></title>
        <id>https://chillicream.com/blog/2025/02/01/hot-chocolate-15</id>
        <link href="https://chillicream.com/blog/2025/02/01/hot-chocolate-15"/>
        <updated>2025-02-01T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Originally, we did not plan on releasing another major version of Hot Chocolate before we release the next major version of Fusion. Really the whole team was focused on working in Fusion, our platform for building distributed GraphQL services. However, while I was upgrading Microsoft’s Azure Data API Builder to Hot Chocolate 14, I stumbled upon a regression introduced between Hot Chocolate 12 and Hot Chocolate 14. Unfortunately, fixing it in 14.4 would have required breaking changes.

## Type System

Microsoft’s Azure Data API Builder uses type interceptors to build a GraphQL schema from a database schema. The intermediary schema it produces is a heavily annotated GraphQL schema document. This approach is straightforward and we do something similar with Hot Chocolate Fusion. However, in the case of Azure Data API Builder, the directives used are more complex and utilize input object structures.

The issue here is that, when we complete a type while initializing the schema, we do not yet have the entire schema available. Parsing directives is thus not possible before all input types are available. While we have tests covering input objects in directives, they did not cover the specific complexity used by Azure Data API Builder. Also, a bit of randomness in the order of initialization exacerbated the problem.

In Hot Chocolate 15, we fixed this by introducing two additional steps to the initialization process of the type system:

- Complete types – This step no longer completes directives and default values; instead, it only completes types and directive definitions.
- Complete metadata – Directive annotations on type-system members and default values are now completed here, once all types have been fully established.

However, this change had broader implications, so we also introduced another step afterward to complete resolvers and make the schema executable.

**Why does this matter to you?**

If you are using type interceptors, the `OnAfterCompleteTypes` hook may no longer behave as before. This might cause errors that do not break compilation per se but do break the runtime behavior. Because of these changes, we decided to rename the Hot Chocolate 14.4 release to Hot Chocolate 15.

## Opportunities

If we are doing a major release, let’s not waste a version bump just for a regression fix. We decided to merge the changes of our current development branch and turn it into a proper major release, shipping a few nice features in the process.

## Supported .NET Versions

With Hot Chocolate 15, we have realigned the frameworks we support and dropped support for .NET Standard 2.0, .NET 6.0, and .NET 7.0. Going forward, Hot Chocolate 15 supports .NET 8.0 and .NET 9.0. This allows us to modernize a lot of code and remove many conditional compilation directives.

## Projections

One long-standing feature of Hot Chocolate is the `HotChocolate.Data` integration, which makes it easy to build on top of _Entity Framework_, Marten, _RavenDB_ or _MongoDB_. It also rich data features like pagination, sorting, filtering, and projections with minimal setup:

```csharp
[UsePaging]
[UseProjection]
[UseFiltering]
[UseSorting]
public static IQueryable<Product> GetProducts(CatalogContext dbContext)
    => dbContext.Products.AsNoTracking();
```

The drawback to this approach is that your GraphQL layer requires direct access to your data layer, which can be undesirable. It can also lead to a **cartesian explosion** issue, where users can traverse deeply into the graph, retrieving a huge number of rows in the process. This can be not only slow but also quite expensive in terms of database and network load.

Sure, you can use split queries in the case of Entity Framework:

```csharp
[UsePaging]
[UseProjection]
[UseFiltering]
[UseSorting]
public static IQueryable<Product> GetProducts(CatalogContext dbContext)
    => dbContext.Products.AsSplitQuery();
```

We introduced some **experimental** features in Hot Chocolate 14 to address these problems, but we weren’t fully satisfied with the implementation. The general direction was good, but the specifics needed work. So we took a step back, refined what worked, and turned it into a proper feature that is no longer experimental.

## DataLoader Basics

Let’s first discuss **DataLoader**, a fundamental concept in GraphQL for batching and deferring data fetching. What many people don’t know is that Meta (formals Facebook) used the concept of a "data loader" before GraphQL even existed, calling it "preparables" or "loader." The idea is to have a unified, interface for efficiently fetching data.

A DataLoader typically lives close to the data-access layer, and your business logic uses it to fetch data.

![Application Building Blocks](dataloader-1.png)

The business logic itself should remain simple. Don’t burden your business logic or your consumer with batching concerns or other complexities in fetching data.

**Lets start at the top!**

Ideally, we want our GraphQL layer to be as thin as possible. It serves us to expose our business logic to the outside world but should not be the business logic.

```csharp
public static async Task<Connection<Brand>> GetBrandByIdAsync(
    int id,
    BrandService brandService,
    CancellationToken cancellationToken)
    => await brandService.GetBrandsAsync(id, cancellationToken);
```

There can be many variants of this approach (e.g., using MediatR), but the important bit is: **the resolver is thin and has no direct access to your data layer**. It merely hooks into your business logic.

**Example using MediatR:**

```csharp
[UsePaging]
public static async Task<Connection<Brand>> GetBrandByIdAsync(
    int id,
    ISender sender,
    CancellationToken cancellationToken)
    => await sender.Send(new GetBrandByIdQuery(id), cancellationToken);
```

The business logic enforces rules, handles authorization, or any other checks. The same business logic applies whether you expose it through GraphQL, REST, or some internal service call.

Below is a simplified query/handler:

```csharp
public record GetBrandByIdQuery(int BrandId) : IRequest<Brand?>;

public class GetBrandByIdQueryHandler(IBrandByIdDataLoader dataLoader)
    : IRequestHandler<GetBrandsQuery, Brand?>
{
    public Task<Brand?> Handle(
        GetBrandsQuery request,
        CancellationToken cancellationToken)
        => dataLoader.LoadAsync(request.BrandId, cancellationToken);
}
```

In this example, we’re using a DataLoader (IBrandByIdDataLoader) that fetches a single brand by ID. Regardless of how many times a brand is requested in a GraphQL query, the DataLoader will batch these requests together into a single database call. That’s the power of DataLoader.

```graphql
query GetBrandById {
  brand(id: 1) {
    id
    name
  }
}

query GetBrandsByProducts {
  products {
    nodes {
      name
      brand {
        name
      }
    }
  }
}
```

With Hot Chocolate, writing a DataLoader only requires you to implementing your batch fetch logic. Our source generator takes care of interfaces, dispatching logic, and so forth:

```csharp
[DataLoader]
public static async Task<Dictionary<int, Brand>> GetBrandByIdAsync(
    IReadOnlyList<int> ids,
    CatalogContext context,
    CancellationToken cancellationToken)
    => await context.Brands
        .Where(t => ids.Contains(t.Id))
        .ToDictionaryAsync(t => t.Id, cancellationToken);
```

So, the example above will lead to the DataLoader interface `IBrandByIdDataLoader`.

## Adding Projections, Filtering, and Sorting

How do we now introduce _client-driven_ projections, filtering, and sorting without exposing `IQueryable` from our business layer?

In Hot Chocolate 15, we rethought and rewrote the **GreenDonut** (DataLoader) implementation and introduced some new packages that provide a few primitives to pass between layers while keeping them isolated.

![GreenDonut Packages](greendonut-1.png)

These packages introduce four foundational types:

- `Page<T>` represents a slice (page) of a larger data set.
- `PagingArguments` are used to page through a data set, define what slice you want to have the the larger data set.
- `QueryContext<T>`: Encapsulates a selector expression, a filter expression, and a sort definition.
- `SortDefinition<T>`: Defines how to sort a data set.

These primitives let us build _data-driven_ interactions into our business layer.

Let’s have a look how we might update our resolver to support projections or filtering by adding a `QueryContext<Brand>`.

First lets update our `GetBrandByIdQueryHandler` by adding the query context as optional argument that we pass on to the DataLoader.

```csharp
public record GetBrandByIdQuery(int BrandId, QueryContext<Brand>? Query = null) : IRequest<Brand?>;

public class GetBrandByIdQueryHandler(IBrandByIdDataLoader dataLoader)
    : IRequestHandler<GetBrandsQuery, Brand?>
{
    public Task<Brand?> Handle(
        GetBrandByIdQuery request,
        CancellationToken cancellationToken)
        => dataLoader.With(Query).LoadAsync(request.BrandId, cancellationToken);
}
```

The `QueryContext<Brand>` is simple to use and pass around. In this specific case where we do not need sorting or filtering, we could also just pass an `Expression<Func<Brand, Brand>>` to describe the properties requested by the client. Both will work just fine.

```csharp
public record GetBrandByIdQuery(int BrandId, Expression<Func<Brand, Brand>>? Selector = null) : IRequest<Brand?>;

public class GetBrandByIdQueryHandler(IBrandByIdDataLoader dataLoader)
    : IRequestHandler<GetBrandsQuery, Brand?>
{
    public Task<Brand?> Handle(
        GetBrandByIdQuery request,
        CancellationToken cancellationToken)
        => dataLoader.Select(Selector).LoadAsync(request.BrandId, cancellationToken);
}
```

> if you are using DTOs in your solution the mapping would already be done by the DataLoader. So the selector would be on the DTO type.

This is really a minimal optional change to our business layer but now allows us the specify a selector. Within our DataLoader we can now inject the `QueryContext<Brand>` as DataLoader state and apply this state to our queryable, which will rewrite the queryable to only select the properties the client requested.

```csharp
[DataLoader]
public static async Task<Dictionary<int, Brand>> GetBrandByIdAsync(
    IReadOnlyList<int> ids,
    QueryContext<Brand> query,
    CatalogContext context,
    CancellationToken cancellationToken)
    => await context.Brands
        .Where(t => ids.Contains(t.Id))
        .With(query)
        .ToDictionaryAsync(t => t.Id, cancellationToken);
```

Within our batching method it will never be null. The source generator will either give us an empty context which will select all properties from Brand or pass along the one from the business layer, that reflects the selection choices of the client request.

Within Hot Chocolate you can now register the `QueryContext<T>` so that the resolver compiler recognizes it and compiles an expression for it which defines the field selection.

```csharp
services
  .AddGraphQLServer()
  ...
  .AddQueryContext();
```

With that setup we can update our resolver.

```csharp
[UsePaging]
public static async Task<Connection<Brand>> GetBrandByIdAsync(
    int id,
    QueryContext<Brand> query,
    ISender sender,
    CancellationToken cancellationToken)
    => await sender.Send(new GetBrandByIdQuery(id, query), cancellationToken);
```

This is a very powerful feature that allows you to keep your business layer clean while still enabling client-driven data fetching. Since we are using DataLoader, we do not have to worry about split queries or other inefficiencies.

## Pagination

So, how does this change our resolver when we want to filter and sort? Lets say we have a top-level query that fetches all brands.

```csharp
[UsePaging]
[UseFiltering]
[UseSorting]
public static async Task<Brand[]> GetBrandsAsync(
    ISender sender,
    CancellationToken cancellationToken)
    => await sender.Send(new GetBrands(), cancellationToken);
```

Lets first look at the `GetBrandsQuery` so that we understand what we need to do under the hood.

```csharp
public record GetBrandsQuery(
    PagingArguments PagingArguments,
    QueryContext<Brand>? Query = null)
    : IRequest<Page<Brand>>;
```

The `GetBrandsQuery` is a simple record that takes paging arguments and an optional query context. The paging arguments specify which portion of the dataset to retrieve. The query returns a page of brands, which is one of our four GreenDonut primitives.

```csharp
public class GetBrandQueryHandler(CatalogContext context)
    : IRequestHandler<GetBrandsQuery, Page<Brand>>
{
    public async Task<Page<Brand>> Handle(
        GetBrandsQuery request,
        CancellationToken cancellationToken)
        => await context.Brands
            .With(request.Query)
            .ToPageAsync(request.PagingArguments, cancellationToken);
}
```

The handler in this case simply uses the `CatalogContext` and applies the query context to the queryable. With GreenDonut, we introduced the `ToPageAsync` extension method, which paginates the dataset and implements cursor-based paging algorithms.

For cursor pagination to work, we need a guaranteed order in the dataset. This ensures that we filter directly into the correct section rather than skipping rows and wasting performance on the database. The cursors encode the properties used for ordering. If we were not using client-controlled ordering, I would simply define an order with LINQ.

```csharp
context.Brands.OrderBy(t => t.Name).ThenBy(t => t.Id).ToPageAsync(request.PagingArguments cancellationToken);
```

The important point here is that the order must produce a unique cursor. That’s why we added the `Id` property as the last `ThenBy`. This is a common pattern to ensure the cursor remains unique

With client-controlled sorting, we cannot simply use LINQ, as we do not know whether the user has already applied an order. This is where the Wither method comes in — it allows us to rewrite the order to ensure that the sort definition produces a unique cursor.

```csharp
public class GetBrandQueryHandler(CatalogContext context)
    : IRequestHandler<GetBrandsQuery, Page<Brand>>
{
    public async Task<Page<Brand>> Handle(
        GetBrandsQuery request,
        CancellationToken cancellationToken)
        => await context.Brands
            .With(request.Query, s => s.AddAscending(t => t.Id))
            .ToPageAsync(request.PagingArguments, cancellationToken);
}
```

In the example above, we added the `Id` property in ascending order. However, we could also define a default order if the user has not specified one.

```csharp
public class GetBrandQueryHandler(CatalogContext context)
    : IRequestHandler<GetBrandsQuery, Page<Brand>>
{
    public async Task<Page<Brand>> Handle(
        GetBrandsQuery request,
        CancellationToken cancellationToken)
        => await context.Brands
            .With(request.Query, DefaultOrder)
            .ToPageAsync(request.PagingArguments, cancellationToken);

    private static SortDefinition<Brand> DefaultOrder(SortDefinition<Brand> sort)
        => sort.IfEmpty(o => o.AddDescending(t => t.Name)).AddAscending(t => t.Id);
}
```

Basically, ordering by name is only added if the user has not defined an order, whereas ordering by ID is always appended.

```csharp
[UsePaging]
[UseFiltering]
[UseSorting]
public static async Task<Brand[]> GetBrandsAsync(
    PagingArguments pagingArgs,
    QueryContext<Brand> query,
    ISender sender,
    CancellationToken cancellationToken)
    => await sender.Send(new GetBrands(pagingArgs, query), cancellationToken);
```

The resolver itself changes only slightly, simply passing along the selection, filter, and sorting context wrapped in a `QueryContext<T>`, along with some paging arguments. However, this alone is not sufficient. In GraphQL, the paging type is a connection, whereas in our business layer, we have designed it as a `Page<T>`. Therefore, we still need to convert the `Page<T>` to a `Connection<T>`. For this the `HotChocolate.Data` package provides an extension method called `ToConnectionAsync`.

```csharp
[UsePaging]
[UseFiltering]
[UseSorting]
public static async Task<Connection<Brand>> GetBrandsAsync(
    PagingArguments pagingArgs,
    QueryContext<Brand> query,
    ISender sender,
    CancellationToken cancellationToken)
    => await sender.Send(new GetBrands(pagingArgs, query), cancellationToken).ToConnectionAsync();
```

Awesome, we’re done! But wait — we didn’t use a DataLoader in this case since it’s a top-level functionality. DataLoaders are useful when fetching data by a specific key. For instance, if we were retrieving a product’s brand, we would need a DataLoader. Otherwise, a query like the following could result in an excessive number of database queries.

```graphql
query GetBrandsByProducts {
  brands {
    nodes {
      name
      products {
        nodes {
          name
        }
      }
    }
  }
}
```

If we were to fetch 50 brands, we would end up making 50 database requests to retrieve the products for each brand in view.

To optimize this, we could build a DataLoader following the same approach as we did for fetching a brand by ID. However, in this case, we need to batch, paginate, and slice the dataset using cursor pagination efficiently.

```csharp
[DataLoader]
public static async Task<Dictionary<int, Page<Product>>> GetProductsByBrandAsync(
    IReadOnlyList<int> brandIds,
    PagingArguments pagingArgs,
    QueryContext<Product> queryContext,
    CatalogContext context,
    CancellationToken cancellationToken)
{
    return await context.Products
        .Where(t => brandIds.Contains(t.BrandId))
        .With(queryContext)
        .ToBatchPageAsync(t => t.BrandId, pagingArgs, cancellationToken);
}
```

Again, we pass along the `QueryContext<T>`. However, instead of using `ToPageAsync`, we use ToBatchPageAsync, which batches data fetching and slicing into a single database request.

```csharp
public async Task<Page<Brand>> Handle(
    GetProductsByBrandsQuery request,
    CancellationToken cancellationToken = default)
    => await productsByBrand
        .With(request.PagingArguments, request.Query)
        .LoadAsync(brandId, cancellationToken) ?? Page<Product>.Empty;
```

The beauty of this approach is that the complexity in my business layer remains unchanged. Similarly, in my resolver, the complexity is the same as implementing a top-level query. Overall, while I gain full control over what happens in each layer, the complexity within each layer remains constant.

![GreenDonut Packages By Layer](greendonut-2.png)

## DataLoader Branching

But wait — if we use a DataLoader and fetch by key and path in different query contexts, wouldn’t that lead to conflicting data fetches? It would if we were using the same DataLoader. However, DataLoaders are immutable. When we apply a wither method, we are effectively branching the DataLoader as we are effectively changing what we fetch and how we fetch it.

Essentially, we create a unique key based on the state passed into the DataLoader, which generates a new branch. If another resolver with the same state requests a different entity key, we look up the corresponding branch of the DataLoader and delegate the request to the correct instance.

You can even branch further on top of the Wither method. For example, if you always need to ensure that data is queried within a specific customer context, you could add an additional where clause on top of our DataLoader. This would create a new branch of our DataLoader ensuring that only this `Handle` method will restrict data fetching.

```csharp
public async Task<Page<Brand>> Handle(
    GetProductsByBrandsQuery request,
    CancellationToken cancellationToken = default)
    => await productsByBrand
        .With(request.PagingArguments, request.Query)
        .Where(t => t.CustomerId == session.CustomerId)
        .LoadAsync(brandId, cancellationToken) ?? Page<Product>.Empty;
```

We distinguish between ordering, where clauses, and selections. Selections, for instance, can be merged within the same instance, resulting in slight overfetching but still retrieving the correct data within a single request.

```csharp
public async Task<Page<Brand>> Handle(
    GetProductsByBrandsQuery request,
    CancellationToken cancellationToken = default)
    => await productsByBrand
        .With(request.PagingArguments, request.Query)
        .Where(t => t.CustomerId == session.CustomerId)
        .Include(t => t.SomeInternalId)
        .LoadAsync(brandId, cancellationToken) ?? Page<Product>.Empty;
```

In this case, the Include is merged into the same DataLoader branch. The new DataLoader allows you to define custom branching rules and introduce custom state, enabling you to extend the base functionality as needed.

## Conclusion

While we hadn’t originally planned to release this at this time, I believe it brings a fantastic set of additions and will empower you to build layered and clean GraphQL services better than ever. With the new APIs — and I’ve only shown a fraction of them — you can now create well-structured GraphQL services without compromising performance or abstraction. At the same time, you can keep complexity low and productivity high.

Try it out and let us know what you think! We’re always looking to improve Hot Chocolate based on your feedback.

I will follow up the blog post with a couple of more detailed YouTube episodes on how to use these new features.

In the meantime, we’re hard at work on the next major Fusion update, which is going to be huge. I’d love to share some tidbits with you, but I don’t want to spoil the surprise! 😃

Join our community on [Slack](https://slack.chillicream.com) or follow us on Twitter — we’re always happy to help and chat with you!
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Newsletter October]]></title>
        <id>https://chillicream.com/blog/2024/10/30/newsletter-october</id>
        <link href="https://chillicream.com/blog/2024/10/30/newsletter-october"/>
        <updated>2024-10-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Hot Chocolate 14 is released, BCP is now Nitro and there is a new DDD Workshop]]></summary>
        <content type="html"><![CDATA[
Dear ChilliCream Community,

We hope this message finds you well and as excited as we are about the future of GraphQL development! We've been hard at work, and we have some big news to share with you.

# Hot Chocolate 14 is Here!

After over a year of dedication and over 500 commits from more than 50 contributors, we're thrilled to announce the release of **Hot Chocolate 14**. This is our biggest release since version 10.5 and marks a significant shift in how you build GraphQL servers.

**What's New:**

Hot Chocolate 14 brings a host of new features and improvements designed to make your development experience more intuitive, efficient, and secure.

- **Ease of Use and Simplified Dependency Injection:** We've streamlined dependency injection, allowing you to inject services directly into your resolvers without extra configuration. This leads to cleaner, more maintainable code. No more `[Service]` attribute needed!

- **Enhanced Query Inspection:** Easily check which fields are being requested within a resolver without complex syntax tree traversals. Optimize data fetching based on actual query needs with our new fluent selector inspection API.

- **Improved Pagination:** Implementing pagination is now more straightforward, whether you're building layered applications or using `DbContext` in your resolvers. We've introduced new primitives like `Page<T>` and `PagingArguments`, along with keyset pagination support for Entity Framework Core, enhancing performance and stability.

- **Advanced DataLoader Capabilities:** DataLoader now supports stateful operations, enabling you to batch multiple nested paging requests into a single database query. This optimizes performance, especially for complex queries with nested pagination. Projections in DataLoaders are now possible!

- **Source Generators for Resolvers:** We've expanded our use of source-generated code, allowing for the generation of resolvers and improving build-time feedback. This feature is opt-in and works with our new type extension API, combining the power of the implementation-first approach with the code-first fluent API. Checkout `[ObjectType<T>]`!

- **Enhanced Relay Support:** Hot Chocolate 14 offers better integration with Relay, including support for custom data on edges, control over the shape of connection types, and updated node ID serializers for more efficient handling.

- **Security Enhancements:** We've integrated the IBM cost specification directly into the core of Hot Chocolate. This means that even if you don't configure any security-related options, your GraphQL server is more secure by default. The cost analysis helps prevent expensive operations from overwhelming your server.

- **Optimized Transport Layer:** We've adopted the latest changes from the GraphQL over HTTP specification and reimplemented our persisted operation pipeline. This introduces end-to-end traceability and allows for more efficient operation execution with features like semantic routes.

- **Improved Fusion Support:** While focusing on stability, we've made it easier to configure Fusion with new attributes and improved error handling from source schemas to the composite schema.

**Learn More:**

For a detailed overview of these (and more) new features and improvements, please read our in-depth blog post:

🔗 **[Sneak Peek at Hot Chocolate 14](https://chillicream.com/blog/2024/08/30/hot-chocolate-14)**

---

# Introducing Nitro: A Unified GraphQL Ecosystem

We're also excited to unveil **Nitro**, the new name that brings together our suite of GraphQL tools under one unified ecosystem. Inspired by the smooth yet powerful kick of nitrogen-infused drinks, Nitro embodies the speed, efficiency, and energy we aim to provide in your development workflow.

**Why Nitro?**

As our products evolved, we wanted a name that reflects our commitment to delivering a seamless and powerful GraphQL experience. By **rebranding Banana Cake Pop and Barista to Nitro**, we're simplifying our ecosystem to make it more cohesive and easier to navigate.

**What's Included in Nitro:**

- **Nitro App (Formerly BananaCakePop):** Your all-in-one tool for developing, testing, and optimizing GraphQL APIs.

  - **Get the Nitro App:** [Download Here](https://get-nitro.chillicream.com)
  - **Try Nitro Cloud:** [Launch Now](https://nitro.chillicream.com)

- **Nitro CLI (Formerly Barista):** Manage APIs, publish schema versions, and deploy clients—all from your command line.

- **Nitro Server (Formerly Banana Cake Pop Services):** The backbone of Nitro, providing essential backend services for managing your GraphQL schemas and monitoring API performance.

**Migration Information:**

For details on migrating to Nitro and the changes to our NuGet and NPM packages, please refer to our blog post:

🔗 **[Introducing Nitro: A New Name, A Unified GraphQL Ecosystem](https://chillicream.com/blog/2024/10/07/introducing-nitro)**

## Full Open Telemetry

While our telemetry integration was previously focused only on GraphQL operations, we're excited to announce that we're expanding our telemetry capabilities to include full OpenTelemetry support. This means you can now also monitor your REST APIs, gRPC services, background jobs, and more—all within the same dashboard.

![image](./img1.png)

# Get Hands-On with DDD and GraphQL in Our One-Day Workshop  

Join us for a focused, one-day workshop on Domain-Driven Design with GraphQL, where we’ll guide you through practical DDD concepts and their implementation in .NET 9, ASP.NET Core 9, Aspire, Hot Chocolate and Fusion. Learn how CQRS and Domain Events work with GraphQL, and how to manage complex application domains with clean architecture practices. This session is ideal for developers who want to deepen their understanding of DDD principles and see them in action in a GraphQL environment.

Claim your **30% discount NOW**:

👉 [Register for the Workshop](https://www.eventbrite.com/e/enterprise-graphql-with-ddd-cqrs-and-clean-architecture-tickets-1057250156679)

# Share Your Success Story with Us!

Do you love using **Hot Chocolate**, **Fusion**, or **Nitro**? Have you built something amazing that you'd like the world to know about? **We want to hear from you!**

We're on the lookout for testimonials and case studies to feature on our website. Your experiences can inspire others and showcase the real-world impact of our tools.

**Interested in Sharing?**

👉 **[Click here to share your story with us!](https://tally.so/r/3j7R4E)**

---

# Thank You! ❤️

A huge congratulations and thank you to our incredible team and community contributors who poured countless hours into making these releases possible. We're eager to continue pushing the boundaries of what's possible with GraphQL, and we couldn't do it without your support.

Thank you for being a vital part of the ChilliCream community. Let's build the future of GraphQL together!

Warm regards,

The ChilliCream Team
]]></content>
        <author>
            <name>Pascal Senn</name>
            <uri>https://github.com/pascalsenn</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Nitro: A New Name, A Unified GraphQL Ecosystem]]></title>
        <id>https://chillicream.com/blog/2024/10/07/introducing-nitro</id>
        <link href="https://chillicream.com/blog/2024/10/07/introducing-nitro"/>
        <updated>2024-10-07T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
At ChilliCream, we’ve always had a playful and creative approach to naming our products. From **HotChocolate** to **StrawberryShake**, our GraphQL tools have been inspired by delicious drinks that keep things fresh and exciting. Today, we’re taking that tradition to the next level with **Nitro** – the newest addition to our product family that unifies and simplifies how you build, manage, and scale your GraphQL APIs.

# Why Nitro?

As we continue to evolve our offerings, we wanted to create a name that embodies the energy, speed, and efficiency of our tools. Inspired by nitrogen-infused drinks that deliver a smooth yet powerful kick, **Nitro** felt like the perfect fit. Just like those drinks, our Nitro tools are designed to give your GraphQL development process a boost – offering a fast, streamlined, and unified experience.

By renaming **Banana Cake Pop** and **Barista** to **Nitro**, we’re simplifying our ecosystem and making it easier for developers to navigate and interact with our suite of products. Nitro brings everything under one umbrella, making your workflow more cohesive and efficient.

# What’s in the Nitro Ecosystem?

- **Nitro App (Formerly Banana Cake Pop)**

  The Nitro App is your go-to tool for developing, testing, and optimizing GraphQL APIs. Whether you’re inspecting queries, visualizing schemas, or collaborating with your team, Nitro App provides the power and precision needed to supercharge your development workflows.
  Get the Nitro App at [get-nitro.chillicream.com.](https://get-nitro.chillicream.com) or try the Cloud version at [nitro.chillicream.com](https://nitro.chillicream.com).

- **Nitro CLI (Formerly Barista)**

  Nitro CLI offers full control from the command line. It’s perfect for managing APIs, publishing new schema versions, and deploying clients with ease. Whether automating tasks or handling complex GraphQL operations, Nitro CLI simplifies your workflow, allowing you to focus on what matters most – building great APIs.

- **Nitro Server (Formerly Banana Cake Pop Services)**

  Nitro Server is the backbone of the Nitro ecosystem. It provides essential backend services for managing your GraphQL schemas, monitoring API performance, and ensuring smooth operations across your gateways and services. With Nitro Server, you can confidently manage your GraphQL infrastructure, ensuring your clients and APIs remain stable, secure, and scalable as your business grows.

# Local Data Migration for Nitro App

Before upgrading from Banana Cake Pop to the Nitro App, please note that **local data will not be automatically migrated**. To avoid losing any of your documents, make sure to explicitly save them before signing in and syncing your data. Only saved documents will be synced to the cloud, ensuring they are safely stored and accessible when you switch to the Nitro App. Unsaved documents will not be included in the sync.

# New NuGet and NPM Packages

As part of our transition to Nitro, we’ve renamed our NuGet and NPM packages to create a more cohesive experience:

## NuGet Packages

| Old Name                   | New Name              |
| -------------------------- | --------------------- |
| Banana Cake Pop.Middleware | ChilliCream.Nitro.App |
| Banana Cake Pop.Services   | ChilliCream.Nitro     |
| Barista                    | ChilliCream.Nitro.CLI |

## NPM Packages

| Old Name                                         | New Name                                 |
| ------------------------------------------------ | ---------------------------------------- |
| @chillicream/bananacakepop-graphql-ide           | @chillicream/nitro-embedded              |
| @chillicream/bananacakepop-express-middleware    | @chillicream/nitro-express-middleware    |
| @chillicream/bananacakepop-server-adapter-plugin | @chillicream/nitro-server-adapter-plugin |

This unified naming approach isn’t just cosmetic – it simplifies how you interact with our tools, making it easier to find, install, and use everything Nitro has to offer.

# Why This Matters

The Nitro name represents more than just speed and energy. It symbolizes a unified, streamlined ecosystem designed to make your GraphQL development experience seamless. Whether you’re using the desktop app, cloud app, or the CLI tools, Nitro provides all the power and flexibility you need, without the complexity of managing disconnected tools.

# Ready to Experience Nitro?

We’re incredibly excited about this new chapter and can’t wait for you to try Nitro. Visit [nitro.chillicream.com](https://nitro.chillicream.com) to experience the Nitro Cloud App, or download the Nitro Desktop App at [get-nitro.chillicream.com.](https://get-nitro.chillicream.com).
Let’s build the future of GraphQL together, with Nitro powering the way forward.
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[What's new for Hot Chocolate 14]]></title>
        <id>https://chillicream.com/blog/2024/08/30/hot-chocolate-14</id>
        <link href="https://chillicream.com/blog/2024/08/30/hot-chocolate-14"/>
        <updated>2024-08-30T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
We are almost ready to release a new major version of Hot Chocolate, and with it come many new exciting features. We have been working on this release for quite some time, and we are thrilled to share it with you. In this blog post, we will give you a sneak peek at what you can expect with Hot Chocolate 14.

I will be focusing mainly on the Hot Chocolate server, but we have also been busy working on Hot Chocolate Fusion and the Composite Schema Specification. We will be releasing more information on these projects in the coming weeks.

# Ease of Use

We have focused on making Hot Chocolate easier to use and more intuitive. To achieve this, we have added many new features that will simplify your workflow. This will be apparent right from the start when you begin using Hot Chocolate 14. One major area where you can see this improvement is in dependency injection. Hot Chocolate 13 was incredibly flexible in this area, allowing you to specify which services are multi-thread capable, which services are pooled resources, or which services must be synchronized. While this was a powerful feature, it could be somewhat complex to use, especially for newcomers to our platform.

You either ended up with lengthy configuration code that essentially re-declared all services, or you ended up with very cluttered resolvers.

With Hot Chocolate 14, we have simplified this process by putting dependency injection on auto-pilot. Now, when you write your resolvers, you can simply inject services without the need to explicitly tell Hot Chocolate that they are services or what kind of services they are.

```csharp
public static IQueryable<Session> GetSessions(
    ApplicationDbContext context)
    => context.Sessions.OrderBy(s => s.Title);
```

This leads to dramatically clearer code that is more understandable and easier to maintain. For instance, the resolver above injects the `ApplicationDbContext`. There is no need to tell Hot Chocolate that this is a service or what characteristics this service has; it will just work. This is because we have simplified the way Hot Chocolate interacts with the dependency injection system.

In GraphQL, we essentially have two execution algorithms. The first, used for queries, allows for parallelization to optimize data fetching. This enables us to enqueue data fetching requests transparently and execute them in parallel. The second algorithm, used for mutations, is a sequential algorithm that executes one mutation after another.

So, how is this related to DI? In Hot Chocolate 14, if we have an async resolver that requires services from the DI container, we create a service scope around it, ensuring that the services you use in the resolver are not used concurrently used by other resolvers. Since query resolvers are, by specification, defined as side-effect-free, this is an excellent default behavior where you as the developer can just focus on writing code without concerning yourself with concurrency between resolver instances.

For mutations, the situation is different, as mutations inherently cause side effects. For instance, you might want to use a shared DbContext between two mutations. When executing a mutation Hot Chocolate will use the default request scope as it's guaranteed by the execution algorithm that there will only ever be a single mutation resolver executed at the same time for a request.

While the new default execution behavior is much more opinionated, it leads to a dramatically easier experience when implementing resolvers. However, we recognize that there are reasons you may want to use the request scope everywhere. That's why you can change the default configuration with the default schema options.

```csharp
builder
    .AddGraphQL()
    .AddTypes()
    .ModifyOptions(o =>
    {
        o.DefaultQueryDependencyInjectionScope = DependencyInjectionScope.Resolver;
        o.DefaultMutationDependencyInjectionScope = DependencyInjectionScope.Request;
    });
```

Also, you can override the defaults configured in the schema options, on a per resolver basis.

```csharp
[UseRequestScope]
[UsePaging]
public static async Task<Connection<Brand>> GetBrandsAsync(
    PagingArguments pagingArguments,
    BrandService brandService,
    CancellationToken cancellationToken)
    => await brandService
        .GetBrandsAsync(pagingArguments, cancellationToken)
        .ToConnectionAsync();
```

> We have applied the same DI handling to source generated DataLoader which by default will now use an explicit service scope for each DataLoader fetch.

# Query Inspection

<Video videoId="XZVpimb6sKg" />

Another area where we have made significant improvements is with query inspections. With Hot Chocolate 14, it’s now incredibly simple to check which fields are being requested within the resolver without the need for complex syntax tree traversals. You can now formulate a pattern with the GraphQL selection syntax and let the executor inject a simple boolean that tells you if your pattern matched the user query.

```csharp
public sealed class BrandService(CatalogContext context)
{
    public async Task<Brand> GetBrandAsync(
        int id,
        [IsSelected("products { details }")]
        bool includeProductDetails,
        CancellationToken ct = default)
    {
        var query = context.Brands
            .AsNoTracking()
            .OrderBy(t => t.Name)
            .ThenBy(t => t.Id);

        if (includeProductDetails)
        {
            query = query.Include(t => t.Products.Details);
        }

        return await query.FirstOrDefaultAsync(ct);
    }
}
```

The patterns also support inline fragments to match abstract types.

```graphql
products {
  ... on Book {
    isbn
  }
}
```

However, even with these complex patterns, it can be beneficial to write your own traversal logic without dealing with complex trees. For this, you can now simply inject the resolver context and use our fluent selector inspection API.

```csharp
public sealed class BrandService(CatalogContext context)
{
    public async Task<Brand> GetBrandAsync(
        int id,
        IResolverContext context,
        CancellationToken ct = default)
    {
        var query = context.Brands
            .AsNoTracking()
            .OrderBy(t => t.Name)
            .ThenBy(t => t.Id);

        if (context.Select("products").IsSelected(details))
        {
            query = query.Include(t => t.Products.Details);
        }

        return await query.FirstOrDefaultAsync(ct);
    }
}
```

If you want to go all in and have the full power of the operation executor, you can still inject `ISelection` and traverse the compiled operation tree.

# Pagination

Pagination is a common requirement in GraphQL APIs, and Hot Chocolate 14 makes it easier than ever to implement, no matter if you are building layered applications or using `DbContext` right in your resolvers.

For layered application patterns like DDD, CQRS, or Clean Architecture, we have built a brand new paging API that is completely separate from the Hot Chocolate GraphQL core. When building layered applications, pagination should be a business concern and should be handled in your repository or service layer. Doing so brings some unique concerns, like how the abstraction of a page looks. For this, we have introduced a couple of new primitives like `Page<T>`, `PagingArguments`, and others that allow you to build your own paging API that fits your needs and interfaces well with GraphQL and REST.

We have also implemented keyset pagination for Entity Framework Core, which you can use in your infrastructure layer. The Entity Framework team is planning to have, at some point, a paging API for keyset pagination natively integrated into EF Core ([Holistic end-to-end pagination feature](https://github.com/dotnet/efcore/issues/33160)). Until then, you can use our API to get the best performance out of your EF Core queries when using pagination with a layered application.

```csharp
public sealed class BrandService(CatalogContext context)
{
    public async Task<Page<Brand>> GetBrandsAsync(
        PagingArguments args,
        CancellationToken ct = default)
        => await context.Brands
            .AsNoTracking()
            .OrderBy(t => t.Name)
            .ThenBy(t => t.Id)
            .ToPageAsync(args, ct);
}
```

We are focusing on keyset pagination because it’s the better way to do pagination, as performance is constant for each page accessed, as opposed to a linearly growing performance impact with offset pagination. Apart from the better performance, keyset pagination also allows for stable pagination results even if the underlying data changes.

We also worked hard to allow for pagination in your DataLoader. In GraphQL, where nested pagination is a common requirement, having the capability to batch multiple nested paging requests into one database query is essential.

Let’s assume we have the following GraphQL query and we are using a layered architecture approach.

```graphql
query GetBrands {
  brands(first: 10) {
    nodes {
      id
      name
      products(first: 10) {
        nodes {
          id
          name
        }
      }
    }
  }
}
```

Let's assume we have the following two resolvers for the above query, fetching the brands and the products.

```csharp
[UsePaging]
public static async Task<Connection<Brand>> GetBrandsAsync(
    PagingArguments pagingArguments,
    BrandService brandService,
    CancellationToken cancellationToken)
    => await brandService
        .GetBrandsAsync(pagingArguments, cancellationToken)
        .ToConnectionAsync();

[UsePaging]
public static async Task<Connection<Product>> GetProductsAsync(
    [Parent] Brand brand,
    PagingArguments pagingArguments,
    ProductService productService,
    CancellationToken cancellationToken)
    => await productService
        .GetProductsByBrandAsync(brand.Id, pagingArguments, cancellationToken)
        .ToConnectionAsync();
```

With the above resolvers, the execution engine would first call the `BrandService`, and then for each `Brand`, it would call the `ProductService` to get the products per brand. This would lead to an N+1 query problem within our GraphQL server. To solve this, we can use a DataLoader within our `ProductService` and batch the product requests.

To enable this, we have worked extensively on DataLoader and now support stateful DataLoader. This means we can pass on state to a DataLoader separate from the keys. If we were to peek into the `ProductService`, we would see something like this:

```csharp
public async Task<Page<Product>> GetProductsByBrandAsync(
    int brandId,
    PagingArguments args,
    ProductsByBrandIdDataLoader productsByBrandId,
    CancellationToken ct = default)
    => await productsByBrandId
        .WithPagingArguments(args)
        .LoadAsync(brandId, ct);
```

Our DataLoader in this case would look like the following:

```csharp
public sealed class ProductDataLoader
{
    [DataLoader]
    public static async Task<Dictionary<int, Page<Product>>> GetProductsByBrandIdAsync(
        IReadOnlyList<int> keys,
        PagingArguments pagingArguments,
        CatalogContext context,
        CancellationToken ct)
        => await context.Products
            .AsNoTracking()
            .Where(p => keys.Contains(p.BrandId))
            .OrderBy(p => p.Name).ThenBy(p => p.Id)
            .ToBatchPageAsync(t => t.BrandId, pagingArguments, ct);
}
```

The `ToBatchPageAsync` extension method will rewrite the paging query so that each `brandId` will be a separate page, allowing us to make one database call to get, in this case, 10 products per brand for 10 brands.

An important aspect of keyset pagination is maintaining a stable order, which requires a unique key. In the above case, we order by `Name` and then chain the primary key `Id` in at the end. This ensures that the order remains stable even if the `Name` is not unique.

> If you want to read more about keyset pagination, you can do so [here](https://use-the-index-luke.com/no-offset).

We have brought the same capabilities to non-layered applications, where you now have a new paging provider for EF Core that allows for transparent keyset pagination.

So if you are doing something like this in your resolver:

```csharp
[UsePaging]
public static async IQueryable<Brand> GetBrands(
    CatalogContext context)
    => context.Brands.OrderBy(t => t.Name).ThenBy(t => t.Id);
```

By default, Hot Chocolate would emulate cursor pagination by using `skip/take` underneath. However, as I mentioned, we now have a new keyset pagination provider for EF Core that you can opt into. It's not the default, as it is not compatible with SQLite for instance.

```csharp
builder.Services
    .AddGraphQLServer()
    ...
    .AddDbContextCursorPagingProvider();
```

But what about user-controlled sorting? The above example would fall apart when using `[UseSorting]`, as we could not guarantee that the order is stable. To address this, we have added a couple of helpers to the `ISortingContext` that allow you to manipulate the sorting expression.

```csharp
[UsePaging]
[UseSorting]
public static async IQueryable<Brand> GetBrands(
    CatalogContext context,
    ISortingContext sorting)
{
    // this signals that the expression was not handled within the resolver
    // and the sorting middleware should take over.
    sorting.Handled(false);

    sorting.OnAfterSortingApplied<IQueryable<Brand>>(
        static (sortingApplied, query) =>
        {
            if (sortingApplied && query is IOrderedQueryable<Brand> ordered)
            {
                return ordered.ThenBy(b => b.Id);
            }

            return query.OrderBy(b => b.Id);
        });

    return context.Brands;
}
```

With the `ISortingContext`, we now have a hook that is executed after the user sorting has been applied. This allows us to append a stable order to the user sorting. Typically, this could be generalized and moved into a user extension method to make the resolver look cleaner.

```csharp
[UsePaging]
[UseSorting]
public static async IQueryable<Brand> GetBrands(
    CatalogContext context,
    ISortingContext sorting)
{
    sorting.AppendStableOrder(b => b.Id);
    return context.Brands;
}
```

You could even go further and bake this into a custom middleware.

```csharp
[UsePaging]
[UseCustomSorting]
public static async IQueryable<Brand> GetBrands(
    CatalogContext context)
    => context.Products;
```

With the new paging providers, we now also inline the total count into the database query that slices the page, meaning you have a single call to the database. The paging middleware will inspect what data is actually needed and either fetch the page and the total count in one database query, just the page if the total count is not needed, or just the total count if the page is not needed. All of this is built on top of the new `IsSelected` query inspection API.

# DataLoader

Let's talk about DataLoader. As we already touched on how DataLoader is now more flexible with pagination, what's underneath all of this is the new state that can be associated with DataLoader. Since DataLoader can be accessed from multiple threads concurrently and also be dispatched at multiple points during execution, you have unreliable state that can be used when it's available but should not cause the DataLoader to fail. However, you can also have state that is used to branch a DataLoader, where the state is guaranteed within that branch.

Let me give you some examples. In the following example, we are fetching brands for ID 1 and 2. We also provide some state when we ask for brand 2. The state is guaranteed to be there when I fetch the second brand, but it could be there for the first brand — this all depends on the dispatcher in this case.

```csharp
var task1 = brandById.LoadAsync(1);
var task2 = brandById.SetState("some-state", "some-value").LoadAsync(2);
Task.WaitAll(task1, task2);
```

However, in some cases like paging, we want the state to be guaranteed. This is where branching comes in. We can branch a DataLoader, and into this branch, we pass in some data that represents the context.

```csharp
var branch = brandById
  .Branch("SomeKey")
  .SetState("some-state", "some-value");

var task1 = branch.LoadAsync(1);
var task2 = branch.LoadAsync(2);
Task.WaitAll(task1, task2);
```

When we look at paging, for instance, we use the paging arguments to create a branch key. So, whenever you pass in the same paging arguments, you will get the same branch. This allows us to batch the paging requests for the same paging arguments.

```csharp
productsByBrandId.WithPagingArguments(args).LoadAsync(brandId, ct);
```

We also use the same state mechanism for DataLoader with projections.

```csharp
public class Query
{
    public async Task<Brand?> GetBrandByIdAsync(
        int id,
        ISelection selection,
        BrandByIdDataLoader brandById,
        CancellationToken cancellationToken)
        => await brandById
            .Select(selection)
            .LoadAsync(id, cancellationToken);
}
```

You can pass an `ISelection` into the DataLoader. Any selection that is structurally equivalent will point to the same DataLoader branch and be batched together. We can even chain other things to that branched state like properties we want include even if they were not requested by the user and even if they are not part of the schema.

```csharp
public class Query
{
    public async Task<Brand?> GetBrandByIdAsync(
        int id,
        ISelection selection,
        BrandByIdDataLoader brandById,
        CancellationToken cancellationToken)
        => await brandById
            .Select(selection)
            .Include(b => b.Products)
            .LoadAsync(id, cancellationToken);
}
```

From the DataLoader side, we can inject these selections and apply them to our queryable.

```csharp
internal static class BrandDataLoader
{
    [DataLoader]
    public static async Task<Dictionary<int, Brand>> GetBrandByIdAsync(
        IReadOnlyList<int> ids,
        CatalogContext context,
        ISelectorBuilder selector,
        CancellationToken ct)
        => await context.Brands
            .AsNoTracking()
            .Select(selector, key: b => b.Id)
            .ToDictionaryAsync(b => b.Id, ct);
}
```

When using our DataLoader projections, we are utilizing a new projection engine that is separate from `HotChocolate.Data`, and we are using this to redefine what projections are in Hot Chocolate. This is why `IsProjectedAttribute` is not supported by DataLoader projections. Instead, we have modified the `ParentAttribute` to specify requirements.

```csharp
public static class ProductExtensions
{
    [UsePaging]
    public static async Task<Connection<Product>> GetProductsAsync(
        [Parent(nameof(Brand.Id))] Brand brand,
        PagingArguments pagingArguments,
        ProductService productService,
        CancellationToken cancellationToken)
        => await productService
            .GetProductsByBrandAsync(brand.Id, pagingArguments, cancellationToken)
            .ToConnectionAsync();
}
```

The optional argument on the `ParentAttribute` specifies a selection set that describes the requirements for the parent object. In the example above, it defines that the brand ID is required. However, you could also specify that you need the IDs of the products as well, such as `Id Products { Id }`. The parent that is injected is guaranteed to have the properties filled with the required data. We evaluate this string representing the requirement in the source generator, and if it does not match the object structure, it would yield a compile-time error. The whole DataLoader projections engine is marked as experimental, and we are looking for feedback.

Apart from this, we have invested a lot into `GreenDonut` to ensure that you can use the source-generated DataLoader without any dependencies on `HotChocolate`, since DataLoader is ideally used between the business layer and the data layer, and is transparent to the REST or GraphQL layer.

With Hot Chocolate 14, you can now add the `HotChocolate.Types.Analyzers` package and the `GreenDonut` package to your data layer. The analyzers package is just the source generator and will not be a dependency of your own package. We will generate the DataLoader code plus the dependency injection code for registering your DataLoader. You simply need to add the `DataLoaderModuleAttribute` to your project like the following:

```csharp
[assembly: DataLoaderModule("CatalogDataLoader")]
```

Lastly, on the topic of DataLoader, we have made the DataLoader cache observable, allowing you to share entities between DataLoader for even more efficient caching. Let's for instance say that we have two Brand DataLoader, one fetches the entity by ID and the other one by name. How can we make sure that we do not fetch the same entity twice just because we have different keys?

```csharp
internal static class BrandDataLoader
{
    [DataLoader]
    public static async Task<Dictionary<int, Brand>> GetBrandByIdAsync(
        IReadOnlyList<int> ids,
        CatalogContext context,
        CancellationToken ct)
        => await context.Brands
            .AsNoTracking()
            .Where(t => ids.Contains(t.Id))
            .ToDictionaryAsync(t => t.Id, ct);

    [DataLoader]
    public static async Task<Dictionary<string, Brand>> GetBrandByNameAsync(
        IReadOnlyList<string> names,
        CatalogContext context,
        CancellationToken ct)
        => await context.Brands
            .AsNoTracking()
            .Where(t => names.Contains(t.Name))
            .ToDictionaryAsync(t => t.Name, ct);
}
```

This can be easily done by writing two observer methods that create a new cache lookup for the same object. So, at the moment one of the DataLoader instances is instantiated, it will subscribe for `Brand` entities on the cache and create lookups. After that, the DataLoader will receive real-time notifications if any other DataLoader has fetched a `Brand` entity and will be able to use the cached entity.

```csharp
internal static class BrandDataLoader
{
    [DataLoader(Lookups = [nameof(CreateBrandByIdLookup)])]
    public static async Task<Dictionary<int, Brand>> GetBrandByIdAsync(
        IReadOnlyList<int> ids,
        CatalogContext context,
        CancellationToken ct)
        => await context.Brands
            .AsNoTracking()
            .Where(t => ids.Contains(t.Id))
            .ToDictionaryAsync(t => t.Id, ct);

    private static int CreateBrandByIdLookup(Brand brand) => brand.Id;

    [DataLoader(Lookups = [nameof(CreateBrandByNameLookup)])]
    public static async Task<Dictionary<string, Brand>> GetBrandByNameAsync(
        IReadOnlyList<string> names,
        CatalogContext context,
        CancellationToken ct)
        => await context.Brands
            .AsNoTracking()
            .Where(t => names.Contains(t.Name))
            .ToDictionaryAsync(t => t.Name, ct);

    private static string CreateBrandByNameLookup(Brand brand) => brand.Name;
}
```

Where this really shines is with optional includes. For instance, when using the `BrandByIdDataLoader`, we could include the products in one request because we know that we will need them later.

```csharp
public sealed class BrandService(CatalogContext context)
{
    public async Task<Page<Brand>> GetBrandByIdAsync(
        PagingArguments args,
        BrandByIdDataLoader brandById,
        CancellationToken ct = default)
        => await brandById
            .AsNoTracking()
            .Include(b => b.Products)
            .ToPageAsync(args, ct);
}
```

In this case, we can subscribe to `Brand` entities on the cache and check if they have the products list populated. If they do, we can create lookups for the products.

```csharp
internal static class ProductDataLoader
{
    [DataLoader(Lookups = [nameof(CreateProductByIdLookups)])]
    public static async Task<Dictionary<int, Product>> GetProductByIdAsync(
        => ...

    private static IEnumerable<KeyValuePair<int, Product>> CreateProductByIdLookups(Brand brand)
      => brand.Products.Select(p => new KeyValuePair<int, Product>(p.Id, p));
}
```

# Source Generators

With Hot Chocolate 14, we have started to expand our use of source-generated code. We have already used source generators in the past to automatically register types or generate the boilerplate code for DataLoader. With Hot Chocolate 14, we are now beginning to use source generators to generate resolvers. This feature is opt-in and, at the moment, only available for our new type extension API.

The new `ObjectTypeAttribute<T>` will, over the next few versions, replace the `ExtendObjectType` attribute. The new attribute works only in combination with the source generator and combines the power of the implementation-first approach with the code-first fluent API.

```csharp
[ObjectType<Brand>]
public static partial class BrandNode
{
    static partial void Configure(IObjectTypeDescriptor<Brand> descriptor)
    {
        descriptor.Ignore(t => t.Subscriptions);
    }

    [UsePaging]
    public static async Task<Connection<Product>> GetProductsAsync(
        [Parent] Brand brand,
        PagingArguments pagingArguments,
        ProductService productService,
        CancellationToken cancellationToken)
        => await productService
            .GetProductsByBrandAsync(brand.Id, pagingArguments, cancellationToken)
            .ToConnectionAsync();
}
```

The beauty of the source generator is that, in contrast to expression compilation, the results are fully inspectable, and we can guide you by issuing compile-time warnings and errors. The source generator output can be viewed within your IDE and is debuggable.

![Rider - Source Generators](screen-source-generator-1.png)

With the new type extension API, we also allow for new ways to declare root fields and colocate queries, mutations, and subscriptions.

```csharp
public static class Operations
{
    [Query]
    public static async Task<Connection<Brand>> GetBrandsAsync(
        BrandService brandService,
        PagingArguments pagingArgs,
        CancellationToken ct)
        => await brandService.GetBrandsAsync(pagingArgs, ct);

    [Mutation]
    public static async Task<Brand> CreateBrand(
        CreateBrandInput input,
        BrandService brandService,
        CancellationToken ct)
        => await brandService.CreateBrandAsync(input, ct);
}
```

Operation fields can even be colocated into extension types.

```csharp
[ObjectType<Brand>]
public static partial class BrandNode
{
    static partial void Configure(IObjectTypeDescriptor<Brand> descriptor)
    {
        descriptor.Ignore(t => t.Subscriptions);
    }

    [UsePaging]
    public static async Task<Connection<Product>> GetProductsAsync(
        [Parent] Brand brand,
        PagingArguments pagingArguments,
        ProductService productService,
        CancellationToken cancellationToken)
        => await productService
            .GetProductsByBrandAsync(brand.Id, pagingArguments, cancellationToken)
            .ToConnectionAsync();

    [Query]
    public static async Task<Connection<Brand>> GetBrandsAsync(
        BrandService brandService,
        PagingArguments pagingArgs,
        CancellationToken ct)
        => await brandService.GetBrandsAsync(pagingArgs, ct);

    [Mutation]
    public static async Task<Brand> CreateBrand(
        CreateBrandInput input,
        BrandService brandService,
        CancellationToken ct)
        => await brandService.CreateBrandAsync(input, ct);
}
```

This allows for more flexibility in addition to the already established `QueryTypeAttribute`, `MutationTypeAttribute`, and `SubscriptionTypeAttribute`, we now have the new `QueryAttribute`, `MutationAttribute`, and `SubscriptionAttribute`.

With the new version of Hot Chocolate, we are also introducing a new type extension API for interfaces, which allows you to add base resolvers for common functionality. Think of this like base classes.

```csharp
public interface IEntity
{
    [ID] int Id { get; }
}

[InterfaceType<IEntity>]
public static partial class EntityInterface
{
    public static string SomeField([Parent] IEntity entity)
        => ...;
}
```

The field definition and the resolver are inherited by all implementing object types. So, if an object type does not declare `someField`, it will inherit the resolver from the interface declaration.

This is also available through the fluent API, where you now have `Resolve` descriptors on interface fields.

# Relay Support

With Hot Chocolate 14, we have also improved our Relay support. We have made it easier to integrate aggregations into the connection type and to add custom data to edges. You now have more control over the shape of the connection type, allowing you to disable the `nodes` field — either to remove it as unnecessary or to replace it with a custom field.

```csharp
builder
    .AddGraphQL()
    .ModifyPagingOptions(o => o.IncludeNodesField = false)
```

Additionally, we have reworked the node ID serializers to be extendable and support composite identifiers.

```csharp
builder
    .AddGraphQL()
    .AddNodeIdValueSerializer<SomeTypeSerializer>()
```

The new serializer is more efficient and aligns better with the ID serialization format of other GraphQL servers, where the encoded ID has the following format: `{TypeName}:{Id}`.

The new serializer still allows for the old format to be passed in, and you can also register the legacy serializer if you prefer the way we handled it before.

Relay remains the best GraphQL client library, with others still trying to catch up by copying Relay concepts. We have always been very vocal about this and use Relay as our first choice in customer projects. Relay is a smart GraphQL client that would benefit immensely from a feature called fragment isolation, where an error in one fragment would not cause the erasure of data from a colocated fragment.

The issue here is that the GraphQL specification defines that if a non-null field either returns null or throws an error, the selection set is erased, and the error is propagated upwards. This is a problem for Relay because it would cause the erasure of data from colocated fragments.

We have been working on a solution to this problem for years now within the GraphQL foundation, and Hot Chocolate has implemented, in past versions, a proposal called CCN (Client-Controlled-Nullability) where the user could change the nullability of fields.

However, there is now a new push to solve this problem in a simpler way with a proposal called true-nullability, which allows smart clients to simply disable null bubbling. In this case, a smart client could create a sort of fragment isolation on the client side by only deleting the fragment affected by an error or non-null violation.

With Hot Chocolate 14, we have decided to remove CCN and add a new HTTP header `hc-disable-null-bubbling` that allows you to disable null bubbling for a request. This is a first step towards true-nullability, which would also introduce a new semantic nullability type to the type system.

We have prefixed the header with `hc-` to signal that this is a Hot Chocolate-specific header and to avoid collision with the eventual GraphQL specification header.

# Data

To make it easier to integrate new data sources into Hot Chocolate, we have made our `IExecutable` abstraction simpler to implement and integrated it more fully into our resolver pipeline. This allows for easier integration of `IQueryable`-based data drivers, like Entity Framework Core or Cosmos DB, without the need to branch the entire data provider in Hot Chocolate.

We have integrated the current Cosmos DB driver with the new `HotChocolate.Data.Cosmos` package and added the new `AsCosmosExecutable` extension method to the `IQueryable` interface. This allows you to easily convert your Cosmos DB queryable into an `IExecutable` that can be used within the default Filter, Sorting, and Projection middleware.

```csharp
[QueryType]
public static class Query
{
    [UsePaging]
    [UseFiltering]
    [UseSorting]
    public static IExecutable<Book> GetBooks(Container container)
        => container
            .GetItemLinqQueryable<Book>(allowSynchronousQueryExecution: true)
            .AsCosmosExecutable();
}
```

However, if you are already trying out EF Core 9, you should give the new Cosmos driver within EF Core a second look, as it was rewritten from the ground up and is now on par with the Cosmos DB SDK driver.

# Query Conventions

<Video videoId="yoW2Mt6C0Cg" />

Our mutation conventions were very well received by the community when we introduced them. They help to implement a complex GraphQL pattern around mutations and errors. With mutation conventions, we provided consistency and removed the boilerplate from your code.

Ever since we introduced the mutation conventions, we have been asked to provide a similar pattern for queries. While in most cases, I would not recommend resorting to error patterns like those used for mutations — because queries are typically side-effect-free and should be easily queried without concern for complex result types — there are cases where you want to return a domain error as part of your query. For these situations, we recognized the need for a consistent pattern.

However, queries are different from mutations, and there is a better pattern than introducing payload-esque types. With our new query conventions, we are embracing a union type as the result type, where the first entry in the union represents success, and the following entries represent errors.

```graphql
type Query {
  book(id: ID!): BookResult
}

union BookResult = Book | BookNotFound | BookAccessDenied
```

This allows us to query like the following:

```graphql
query {
  book(id: "1") {
    ... on Book {
      title
    }
    ... on Error {
      code: __typename
      message
    }
    ... on BookNotFound {
      bookId
    }
    ... on BookAccessDenied {
      requiredRoles
    }
  }
}
```

To opt into the query conventions you can chain into the configuration builder `AddQueryConventions`.

```csharp
builder
  .AddGraphQL()
  .AddTypes()
  .AddQueryConventions();
```

This in turn allows you, as with mutation conventions, to annotate errors on your resolver or use the `FieldResult<TResult, TError>` type.

```csharp
public class Query
{
    [Error<BookNotFoundException>]
    [Error<BookAccessDeniedException>]
    public async Task<Book> GetBook(
        int id,
        BookService bookService,
        CancellationToken ct)
        => await bookService.GetBookAsync(id, ct);
}
```

# Transport

Let's talk about the GraphQL transport layer and what has changed with Hot Chocolate 14. The GraphQL over HTTP spec is now in its final stages, and we have been adopting the latest changes. This means that we no longer return status code 500 when the full result has been erased due to a non-null violation. Instead, we return status code 200 with a JSON body that contains the error information and `data` as null.

If you are interested in the spec, you can find the current version [here](https://github.com/graphql/graphql-over-http).

We have also reintroduced the error code for not authenticated errors to make it easier for authentication flows. This was something we originally dropped in Hot Chocolate 13, but because many of you struggled with this, we have reintroduced it.

<Video videoId="NK0Y1Y9NQrU" />

Apart from these smaller bits and pieces, we have completely rewritten our persisted operation pipeline, aka trusted document pipeline, to introduce end-to-end traceability across the entire transport layer. We have done this by implementing a feature we call semantic routes. The idea here is that each operation has a unique URI that is derived from the document hash and the operation name.

This new persisted operation transport pipeline can be mapped separately, as shown in the following example:

```csharp
app.MapGraphQLPersistedOperations();
```

> In production you could drop the standard GraphQL middleware and only map the persisted operations middleware.

By default, we would map the persisted operations to `/graphql/persisted/{documentHash}/{operationName}`, but you can change the root for this path.

Now, with this setup, only the variables and extensions are posted to the server. If you are using a query, you can also use a GET request, like the following:

```csharp
GET /graphql/persisted/1234/GetBook?variables={id:1}
```

This also makes it much easier to work with CDNs or to reroute certain operations to different servers.

For this release, we have also reimplemented our batching transport layer and now support both variable batching and request batching. Variable batching is a new batching proposal we have created for the upcoming Composite Schema Specification to transparently use batching in combination with standard GraphQL queries, instead of relying on special fields like the `_entities` field or the batching fields in Fusion.

With variable batching, you can batch multiple sets of variables for the same operation.

```json
{
  "query": "query GetBooks($id: ID!) { book(id: $id) { title } }",
  "variables": [{ "id": "1" }, { "id": "2" }]
}
```

Since a variable batch request has the same structure as a standard GraphQL request, except for the `variables` field, which in this case is a list, we can also batch these within a batch request.

```json
[
  {
    "query": "query GetBooks($id: ID!) { book(id: $id) { title } }",
    "variables": [{ "id": "1" }, { "id": "2" }]
  },
  {
    "query": "query GetBooks($id: ID!) { book(id: $id) { title } }",
    "variables": { "id": "3" }
  }
]
```

This new batching API within your backend allows for new use cases and is a great way to optimize your GraphQL server.

# Security

We have seen countless GraphQL servers over the last year as part of our consulting engagements, and in many cases, they were not configured in a secure way. This was not due to a lack of functionality in Hot Chocolate but because engineers transitioning to GraphQL often did not know good security practices for GraphQL.

GraphQL, as Facebook created and used it, was built around flexibility during development and persisted operations in production. This means that when Facebook deploys to production, the GraphQL server essentially becomes a REST server — there is no open GraphQL endpoint in production. The GraphQL server is only able to execute trusted operations that were exported from the various frontends into an operation store.

In the build pipeline, operations are stripped from the frontend code and replaced with a unique identifier. The stripped operation documents are stored in an operation store. In production, the frontend sends the unique identifier to the GraphQL server instead of a full operation. The GraphQL server only executes operations stored in the operations store and will deny execution of an arbitrary GraphQL requests.

This is the BEST way to do GraphQL and provides the best approach for schema evolvability, as operations are centrally known and can be statically analyzed. It also ensures that you know the performance characteristics and impact of operations on your backend. With Banana Cake Pop, you can set up a schema registry and an operation store in less than 5 minutes. Have a look [here](https://chillicream.com/docs/bananacakepop/v2/apis/schema-registry) for more information.

However, most new developers are not aware of how to do this or do not understand why they should do it in the first place. Another problem is that there is no easy path from an open GraphQL server to a closed system once you have clients working against your API.

With Hot Chocolate 14, we wanted to ensure that your GraphQL server is secure even if you do not configure any security related options, even if you do not know about persisted operations, or even if you explicitly want an open GraphQL server. Going forward, we have built into the core of Hot Chocolate the IBM cost specification to weigh the impact of your requests and to restrict expensive operations right from the start.

<Video videoId="R6Rq4kU_GfM" />

When you export your schema with Hot Chocolate 14, you will see that we have added cost directives to certain fields. We estimate costs automatically so that you do not have to do this manually. You can override these estimates where necessary. The IBM cost spec has two weights it calculates: type cost, which estimates the objects being produced (essentially the data cost), and field cost, which estimates the computational cost.

> With Hot Chocolate 14, we have implemented static analysis, but we will add runtime analysis and result analysis in later updates as well.

The static analysis estimates maximums, meaning if you request a list of 50 elements, it will estimate 50 elements, not the actual number of elements that is returned. This ensures that you do not overwhelm your server with a single request and provides a good estimate of what the request could mean for your backend.

You can combine the cost analysis scores with rate limiting to ensure that a user stays within cost boundaries over time.

```csharp
.UseRequest(next =>
{
    var rateLimiter = new SlidingWindowRateLimiter(
        new SlidingWindowRateLimiterOptions
        {
            PermitLimit = 10000,
            Window = TimeSpan.FromHours(1),
            SegmentsPerWindow = 6, // 10-minute segments
            QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
            QueueLimit = 1,
        });

    return async context =>
    {
        if (context.ContextData.TryGetValue(WellKnownContextData.CostMetrics, out var value)
            && value is CostMetrics metrics)
        {
            using RateLimitLease lease = await rateLimiter.AcquireAsync(
                permitCount: (int)metrics.TypeCost,
                context.RequestAborted);

            if (!lease.IsAcquired)
            {
                context.Result =
                    OperationResultBuilder.New()
                        .AddError(ErrorBuilder.New()
                            .SetMessage("Rate limit exceeded.")
                            .SetCode("RATE_LIMIT_EXCEEDED")
                            .Build())
                        .SetContextData(
                            WellKnownContextData.HttpStatusCode,
                            HttpStatusCode.TooManyRequests)
                        .Build();
                return;
            }
        }

        await next(context);
    };
})
```

While you would need a more sophisticated setup in production, such as using Redis to have a distributed rate limiter, this is a good start to ensure that your server is not overwhelmed and as predictable performance characteristics.

With the cost spec, you can also estimate a request's impact without executing the actual request by sending the header `GraphQL-Cost:validate`. If you want the request to be executed but still want to see the cost, even if the request is valid, you can send the header `GraphQL-Cost:report`.

With the IBM cost spec baked into the core, it's always on, making your GraphQL server more secure and predictable. However, it will also reveal the true cost of your requests, which might be challenging when you migrate.

We have also ensured that migrating from an open GraphQL server to trusted documents can now be done in a few minutes by integrating with Banana Cake Pop. Over a period of 30, 60, or 90 days, the GraphQL server will report executed operations to Banana Cake Pop which will store them in the operation store. You can manually decide which queries to exclude. After that period, you can switch to trusted operations, and only operations tracked in the operation store will be allowed from that day forward.

Another change we made with Hot Chocolate 14 is around introspection. When we detect a production environment in ASP.NET Core, we will automatically disable introspection and provide a schema file at the route `/graphql?sdl`, which is a one-time computed schema file that will be served as a simple file from your server. The misunderstanding with introspection is often that people think it's about hiding the schema. This actually is not the case since it's quite simple to infer the schema from requests observed in a web application. The problem with introspection is that it can easily produce very large results. When I say large, I mean 200-300 MB, depending on your schema. Most tools will work fine with a schema file, which is much smaller than the introspection result and costs virtually nothing in terms of compute and memory. You can override this behavior as follows:

```csharp
builder
    .AddGraphQLServer()
    .DisableIntrospection(false);
```

Also the schema file can be disabled like the following.

```csharp
builder
    .AddGraphQLServer()
    .ModifyRequestOptions(o => o.EnableSchemaFileSupport = false);
```

# Fusion

OK, with that, let's talk about Fusion, our GraphQL solution for federated APIs. With version 14, we have focused heavily on stability. Based on feedback from the community, we have improved how errors traverse from the source schemas to the composite schema.

We have also made the configuration process easier by providing a new package that offers attributes for Fusion. This allows you to use C# instead of GraphQL extension files.

```csharp
public static class Query
{
    [Lookup]
    public static async Task<Brand?> GetBrandByProductIdAsync(
        [Is("product { id }")] int id,
        ISelection selection,
        BrandByProductIdDataLoader brandByProductId,
        CancellationToken cancellationToken)
        => await brandByProductId
            .Select(selection)
            .LoadAsync(id, cancellationToken);
}
```

This is especially nice when we talk about `@require`.

```csharp
public static int EstimateShippingTime(
    [Require("dimension { weight }")] int productWeight)
```

We have also worked on experimental support for Aspire, which gives you a much nicer development workflow around distributed GraphQL.

Apart from these smaller changes, we are currently working on three major areas for Fusion. The first is implementing the composite schema specification, which will align Hot Chocolate Fusion with the open spec proposal. The second effort is achieving AOT compatibility for the gateway. This is a major undertaking, as we are essentially creating a second GraphQL server from scratch, focused solely on the gateway.

Additionally, recognizing that many people use Apollo Federation and may want to migrate to a pure .NET solution, we are also working on compatibility with the Apollo Federation spec. As the composite schema specification merges Fusion concepts around lookups and the Apollo Federation spec around schema evolution and traffic steering, the step from Fusion to supporting Apollo Federation is not that big anymore. However, we have moved these tasks from Hot Chocolate 14 to Hot Chocolate 15 as we still have lots to do here.

# Client

For Hot Chocolate Fusion, we have created a low-level GraphQL client that supports a variety of GraphQL protocols. We have refactored Strawberry Shake to use this basic client for HTTP traffic. For many server-to-server use cases, we recommend using this client as it is geared toward performance and allows you to bring your own models.

```csharp
var client = new DefaultGraphQLHttpClient(httpClient);

var query =
    """
    query($episode: Episode!) {
      hero(episode: $episode) {
        name
      }
    }
    """;

var variables = new Dictionary<string, object?>
{
    ["episode"] = "JEDI",
};

var response = await client.PostAsync(query, variables);

using var body = await response.ReadAsResultAsync(cts.Token);
var mode = body.Data.Deserialize<MyResponseModel>()
```

# GraphQL Cockpit

With Banana Cake Pop, we have further shifted to give you more control over your applications with an end-to-end GraphQL cockpit that provides a schema registry, client registry, operation store, GraphQL telemetry, end-to-end OpenTelemetry tracing, logging, metrics, and strong schema evolution workflows that put you in control.

![Banana Cake Pop](screen-banana-cake-pop-1.png)

With Banana Cake Pop you have the best solution to manage your distributed GraphQL setup.

<Video videoId="KfBV3GQ3760" />

# Community

In this release, we had a staggering **30** new contributors who helped alongside the team of core contributors. Overall, we had 46 contributors working on Hot Chocolate 14. These contributions ranged from fixing typos to optimizing our filter expressions, like the [pull request](https://github.com/ChilliCream/graphql-platform/pull/7311) from @nikolai-mb. We are very grateful to have such a vibrant community that helps us make Hot Chocolate better every day.

For this reason, we have now created a GitHub DevContainer template so that you can get started with contributing in about 2 minutes. You can either run the DevContainer directly on GitHub:

![GitHub Codespaces](screen-codespaces-1.png)

Or you can run it locally on your own Docker. If you do not know what DevContainers are, you can read up on them [here](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers).

# Documentation and Courses

We are still hard at work updating the documentation and are also taking feedback on this version. This post is based on 14.0.0-rc.1 which will be out in a couple of days.

If you want to learn all about the new features of Hot Chocolate, I have made a course on DomeTrain that gives you the ultimate introduction to GraphQL and uses Hot Chocolate in its preview builds.

If you use the code `STAIB`, you will get a 20% discount on the course.

[https://dometrain.com/course/getting-started-graphql-in-dotnet/](https://dometrain.com/course/getting-started-graphql-in-dotnet/)

Apart from the in-depth workshop at DomeTrain we have also reworked our Getting Started workshop that you can now find [here](https://github.com/ChilliCream/graphql-workshop).

# Hot Chocolate 15

Lastly, let's talk about the roadmap ahead. We have already started work on Hot Chocolate 15, which is slated for release in December/January. Hot Chocolate 15 will have a heavy focus on Hot Chocolate Fusion and will introduce a brand new gateway and new composition tooling. As I outlined in the Fusion section, we are working on three key areas that will reinvent what Fusion is.

Other areas we will focus on include DataLoader, with a new batch scheduler that uses its own `TaskScheduler` to better track DataLoader promises in batching and defer scenarios. We already have a PR up for this but had stability concerns for version 14. With version 15, we will have the time to get this right and provide a much more efficient DataLoader implementation.

Projections is another area where we are all in, working on a brand new projections engine. You can already see bits and pieces in Hot Chocolate 14 with the experimental features we've introduced around DataLoader projections. The new projection engine in `HotChocolate.Data` will be built on top of DataLoader and will offer a much more efficient way to project your data with proper data requirements.

With Hot Chocolate 15, we are dropping support for `.NETStandard 2.0`, `.NET 6.0`, and `.NET 7.0`. Going forward, you will need to run on `.NET 8.0` or `.NET 9.0`. This change will allow us to modernize a lot of code and eliminate many precompile directives.

Looking beyond Hot Chocolate 15, we will shift our focus back to Strawberry Shake, which will undergo a major overhaul.

With that, I encourage you to try out Hot Chocolate 14 RC.1 and give us your feedback as soon as it will drop on nuget.org. We have planned for three more RCs after RC.1 to address issues our community finds.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Logging in Banana Cake Pop]]></title>
        <id>https://chillicream.com/blog/2024/08/11/logging</id>
        <link href="https://chillicream.com/blog/2024/08/11/logging"/>
        <updated>2024-08-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We just released logging in Banana Cake Pop. Checkout the blog post to learn more!]]></summary>
        <content type="html"><![CDATA[
We’re thrilled to announce a new feature in Banana Cake Pop that will enhance your development and debugging experience—**Logging**! Now, you can seamlessly send logs to Banana Cake Pop and analyze them directly within the app, making it easier than ever to monitor and troubleshoot your APIs.

# What’s New?

## Service Logs

![Api Logs](api-logs-1.png)

![Api Logs - Expanded](api-logs-2.png)

APIs now have a dedicated **Logs** tab. This new tab allows you to view all the logs associated with a specific API. Whether you're tracking requests, debugging issues, or monitoring performance, this feature gives you a comprehensive view of what's happening under the hood.

## Trace Logs

![Trace Logs](api-logs-3.png)

We’ve also added the ability to inspect logs within individual traces. When you open a trace, you’ll now see all the logs corresponding to each trace. This granular level of detail is invaluable for pinpointing issues and analyze traces in detail.

## Log Retention

- **Shared Clusters:** Log retention in shared clusters is set to 1 day. This ensures that you can review recent logs.
  
- **Dedicated Clusters:** For those using dedicated clusters, we offer **dynamic log retention times**. This means you can configure log retention according to your specific needs, offering greater flexibility and control over your logging data.

# Getting Started with Logging

To start using this new logging feature, ensure that you are using **Banana Cake Pop version 13.9.0 or 14.x.x-preview.8**. Below is a sample setup to get you started:

```csharp
builder.Services
    .AddGraphQLServer()
    .AddInstrumentation()
    ... // your configuration here
    .AddBananaCakePopServices(x =>
    {
        x.ApiId = ""; // <-- Replace with your API ID
        x.ApiKey = ""; // <-- Replace with your API key
        x.Stage = "dev";
    });

builder.Services
    .AddLogging(x => x
        .AddBananaCakePopExporter()
        .AddOpenTelemetry(x =>
        {
            x.IncludeFormattedMessage = true;
            x.IncludeScopes = true;
        }));
```

You can find the full example over [in the example repository](https://link.chillicream.com/2024/08/11/logging-example) or check out the [documentation](https://link.chillicream.com/2024/08/11/logging-docs) for more details.

We hope this new logging capability helps you gain deeper insights into your APIs and streamline your development workflow. As always, we’re here to help with any questions or feedback you might have.
Don’t hesitate to reach out on <contact@chillicream.com> or on [slack.chillicream.com](https://link.chillicream.com/2024/08/11/slack)

# 🛠️ Announcing Our Enterprise GraphQL Workshop

In the fast-paced world of enterprise software development, mastering advanced architectural patterns is crucial for building robust and scalable applications.
Our upcoming Enterprise GraphQL with DDD, CQRS, and Clean Architecture Workshop is an immersive one-day experience designed to elevate your skills.

This workshop will guide you through the process of integrating GraphQL with DDD, CQRS, and Clean Architecture.
You'll gain hands-on experience in constructing a sophisticated enterprise-level system, starting from the basics and moving towards complex implementations.

Discover more about the workshop here: [DDD Workshop](https://link.chillicream.com/2024/08/11/ddd-workshop)

Happy logging! 🚀
]]></content>
        <author>
            <name>Pascal Senn</name>
            <uri>https://github.com/pascalsenn</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Recent Highlights]]></title>
        <id>https://chillicream.com/blog/2024/05/21/newsletter-may</id>
        <link href="https://chillicream.com/blog/2024/05/21/newsletter-may"/>
        <updated>2024-05-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We just released the Operation Builder, Telemetry, and a new Full Stack GraphQL Workshop. Checkout the blog post to learn more!]]></summary>
        <content type="html"><![CDATA[
We’re excited to bring you some significant updates from ChiliCream that can genuinely make a difference in your day-to-day development. This isn't just about new features—it's about making your workflow more effective and your projects more successful.

# Operation Builder

We’re proud to introduce the Operation Builder in Banana Cake Pop, a tool designed to make creating and managing your GraphQL operations a breeze.

![Operation Builder](img1.png)

The Operation Builder simplifies the process of creating and managing queries, making it easier than ever to draft, edit, and inspect your operations. Dive deep into your schema, seamlessly navigate fields and fragments, and gain instant insights into your data structure.

This is perfect for both quick edits and detailed explorations, helping you understand and optimize your queries with ease.

Try out the Operation Builder today and transform the way you work with GraphQL!

**[Check out the video here](https://link.chillicream.com/2024/05/21/ops-builder-video)**

# Telemetry

![Telemetry](img2.png)
We’re want to put a spotlight on our Telemetry integration. Why did we build this? The answer is simple. Understanding your application’s performance shouldn't be a guessing game and GraphQL Telemetry is difficult. With our telemetry integration, you can have complete visibility into your GraphQL server.

![Telemetry](img3.png)

- **Trace Visualization:** See every trace in detail. This helps you pinpoint precisely where your system can be improved.
- **Latency Monitoring:** Track average latency and critical percentiles to ensure top-notch performance.
- **Throughput Metrics:** Keep an eye on operations per minute, so you can manage and scale your resources effectively.
- **Client Insights:** Identify which clients impact your system the most, helping you make data-driven decisions.
- **Error Tracking:** Stay ahead of potential issues with real-time error reports.
- **In-depth Operation Analysis:** Gain a comprehensive overview of each operation's latency, throughput, and error rates.

The fusion dashboard offers extensive monitoring capabilities, presenting real-time tracing and telemetry insights of your gateway and subgraphs. The topology view reveals interconnections and client activities, while status indicators provide a quick overview of latency, throughput, and error rates.

_Create, Collaborate, Conquer! Get Started with Banana Cake Pop Pro. Use the promo code **BCPROCKS** to get a discount on your first year and start using our GraphQL IDE to enhance your projects efficiently._

**[Check out the video here](https://link.chillicream.com/2024/05/21/telemetry-video)**

or read the docs: [Open Telemetry Documentation](https://link.chillicream.com/2024/05/21/otel-docs)

# Announcing Our New Full Stack GraphQL Workshop

In today's rapidly evolving technology landscape, staying ahead requires not only understanding the latest technologies but also knowing how to implement them effectively. Our brand-new Full Stack GraphQL Workshop is a two-day, hands-on journey designed to demystify advanced concepts.

![Full Stack GraphQL Workshop](img4.png)

We'll start with the basics and progressively build a fully functional distributed web shop using HotChocolate, Relay.js, Fusion, multiple subgraphs, and .NET Aspire. We’ll also delve into foundational principles like domain-driven design, CQRS, and clean architecture.

Learn more about the workshop here: [learn.chillicream.com](https://link.chillicream.com/2024/05/21/learn)

## We Want to Hear From You

Your insights are invaluable to us. If you have questions, need more information, or want to discuss how our tools can fit into your projects, don’t hesitate to reach out on <contact@chillicream.com> or on [slack.chillicream.com](https://link.chillicream.com/2024/05/21/slack)

## Thank You

We appreciate your engagement and are thrilled to support your projects with our evolving GraphQL solutions. Keep an eye out for HotChocolate 14, and let us help you take your projects to the next level.
]]></content>
        <author>
            <name>Pascal Senn</name>
            <uri>https://github.com/pascalsenn</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Full Stack GraphQL Workshop]]></title>
        <id>https://chillicream.com/blog/2024/04/01/fullstack-workshop</id>
        <link href="https://chillicream.com/blog/2024/04/01/fullstack-workshop"/>
        <updated>2024-04-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We're excited to announce our new Full Stack GraphQL Workshop. Learn more about the workshop here!]]></summary>
        <content type="html"><![CDATA[
In today's rapidly evolving technology landscape, staying ahead requires not only understanding the latest technologies but also how to implement them effectively. This two-day workshop is a hands-on journey designed to demystify advanced concepts by building from the ground up. We'll start with the basics and progressively build a fully functional distributed web shop using HotChocolate, Relay.js, Fusion, multiple subgraphs .NET Aspire and also concepts like domain driven design, CQRS and clean architecture.

Book your seat now and learn more about the workshop [here](https://learn.chillicream.com/blog/2024-04-01/fullstack-workshop).

![Full Stack GraphQL Workshop](img1.png)

Over two days, we'll cover everything from basic concepts to advanced techniques. We start by getting to know GraphQL, learning about its features and benefits compared to traditional methods. Later, we introduce Relay.js, focusing on how it works with GraphQL to improve data handling and application performance.

**Day 1:** We begin with basic GraphQL concepts, then move on to how you can build efficient APIs. In the afternoon, we'll learn about Relay.js, starting with the fundamentals and advancing to more complex topics.

**Day 2:** We explore deeper topics like how to change and improve your GraphQL setup, how to handle data updates smoothly, and how other advanced techniques fit into the GraphQL world. We end by learning about real-time data updates with subscriptions.

For the next online workshop you [find more information here](https://learn.chillicream.com/blog/2024-04-01).

This workshop can also be tailored to meet your company's specific needs. We offer the flexibility to customize the content and focus areas to best match your team's requirements and goals.

Here are the detailed modules available:

**Module 1: Getting Started with GraphQL**

Kick off with GraphQL by understanding its fundamental concepts such as operations, types system, syntax, and reasons for using GraphQL over other APIs. The session ends with setting up a first GraphQL server, providing hands-on experience from the start.

**Module 2: Building a Database Driven Application**

Explore how to build GraphQL apis using Entity Framework Core, with features like paging, filtering, sorting, and projections. The session will also cover some advanced concepts like field middlewares.

**Module 3: Building APIs with Simple Layering**

This session focuses on API with simple layering, including applying filtering and pagination in layered architectures. It also covers best practices using DataLoaders for optimized data fetching operations.

**Module 4: GraphQL Query Patterns and Best Practices**

Detailed exploration of advanced GraphQL patterns such as evolving schemas, entity and connection patterns for large-scale applications, ensuring best practices are met for enterprise development.

**Module 5: Getting Started with Relay.js**

Introduction to Relay.js, focusing on queries, using fragments and arguments effectively.
Module 6: Advanced Fetching Patterns
This module covers complex data fetching strategies in Relay.js, including transitions, refetching, and pagination, essential for managing data in applications and providing peak user experience.

**Module 7: Understanding Relay**

Expands on Relay's core concepts, including store management, data prefetching methods, and internal workings of Relay for performance improvements and predictable state management.

**Module 8: GraphQL Mutations Patterns and Best Practices**

Deep dive into the structure and patterns of GraphQL mutations, focusing on how to effectively manage errors and ensure robust mutation operations.

**Module 9: Mutations In Relay**

This module focuses on teaching effective methods for managing mutations, error handling, and executing optimistic updates within Relay.

**Module 10: GraphQL Schema Evolution**

Review of techniques to evolve a GraphQL schema over time without breaking existing operations, including the use of client and schema registries and implementing open telemetry.

**Module 11: Introduction to Distributed GraphQL**

Covering the concepts and implementation of distributed GraphQL with fusion to allow scalable, efficiently distributed data across different services and servers.

**Module 12: Authentication / Authorization**

Detailed breakdown of implementing authentication and authorization in GraphQL applications, ensuring secure and controlled access to data through proper practices.

**Module 13: CQRS, DDD and GraphQL, the Perfect Fit?**

Exploration of how CQRS and Domain Driven Design can be integrated with GraphQL to optimize complexity management in large-scale domains.

**Module 14: GraphQL Subscriptions Patterns and Best Practices**

In-depth look at implementing real-time functionalities via GraphQL subscriptions, with specific focus on patterns. Implemented in both the backend and frontend..

**Closing Session: Q&A**

An open session where attendees can ask questions or clarify doubts about the topics covered, facilitating deeper understanding and practical implementations.

# We Want to Hear From You

Your insights are invaluable to us. If you have questions, need more information, or just want to talk to use, don’t hesitate to reach out on <contact@chillicream.com> or on [slack.chillicream.com](https://slack.chillicream.com/blog/2024/04/01/fullstack-workshop)
]]></content>
        <author>
            <name>Pascal Senn</name>
            <uri>https://github.com/pascalsenn</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL-Fusion: An open approach towards distributed GraphQL]]></title>
        <id>https://chillicream.com/blog/2023/08/15/graphql-fusion</id>
        <link href="https://chillicream.com/blog/2023/08/15/graphql-fusion"/>
        <updated>2023-08-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Together, we'll explore the new GraphQL-Fusion, the open approach towards distributed GraphQL.]]></summary>
        <content type="html"><![CDATA[
# In the beginning

Right from the beginning, people saw the potential of GraphQL as a gateway technology. GraphQL promised a single integrated schema to the API consumer while offering the flexibility to leverage various technologies and services behind the scenes.

When GraphQL was introduced, front-end engineers were the first to glimpse the power of it and started wrapping their REST services with GraphQL. This made data fetching more efficient by aggregating data calls close to downstream services and rendered the data more accessible. The straightforward, human-understandable schema made it easier to trace relations and reason about data and its connections in an entirely new way.

GraphQL offered a way to model an interface to our core business domain that often diverged from the technical realities of the REST, gRPC, or other APIs behind it. It eliminated the complexity of knowing which micro-service would provide the necessary data or mutations for a particular use case. While micro-service or domain-service architectures provided technical means to scale more efficiently and align with organizational needs, GraphQL introduced simplicity with its unified schema approach.

From the outset, GraphQL server developers were challenged to find ways to simplify distributed GraphQL setups. Over time, we've witnessed the evolution of various methods, from schema stitching techniques to federated solutions like Apollo Federation. However, many of these restrict users within a single-vendor ecosystem or, on the other end, are too rudimentary to cater to sophisticated enterprise requirements.

# Expectations

We believe that distributed GraphQL services — or composite GraphQL services — should be straightforward to set up and seamlessly integrate with the diverse range of CI/CD tools, schema registries, composition utilities, and gateways that enterprises might prefer. The current landscape should not dictate the choice of tools but provide flexibility.

Up to this point, the GraphQL landscape has lacked an open specification tailored for distributed setups – a framework designed from the ground up for extensibility and integration with diverse toolchains. We envisioned a platform where tools from various vendors could effortlessly work in tandem, ensuring that developers and enterprises never feel constrained by their technical choices.

# Let's share and compete

Late last year, [ChilliCream](https://chillicream.com) and [The Guild](https://the-guild.dev/) met in Paris and discussed their approaches towards distributed GraphQL. It became clear that both companies were solving similar problems, and we decided to join forces on this project. ChilliCream would provide the initial work on the Fusion spec and implementation. At the same time, The Guild would start specifying their work on [GraphQL Mesh Gateway](https://the-guild.dev/graphql/mesh) with [OpenAPI support](https://the-guild.dev/graphql/mesh/docs/handlers/openapi) and help shape the initial Fusion spec. As we started, work on prototypes and the initial spec texts, we reached out to more companies in the community to see if there was interest in collaboration. It turns out that the GraphQL community is hungry for an open specification to standardize distributed GraphQL application gateways. [Hasura](https://hasura.io/), [IBM](https://www.ibm.com), [solo.io](https://www.solo.io/), [AWS AppSync](https://aws.amazon.com/de/appsync/), [WunderGraph](https://wundergraph.com/) have all joined the effort for creating a common spec.

Today, we are thrilled to unveil GraphQL-Fusion, an open specification under the **MIT license**. This initiative empowers everyone to craft tools and solutions centered around distributed GraphQL services. Complementing this announcement, we're also introducing [Hot Chocolate](https://chillicream.com/docs/hotchocolate) Fusion, an early implementation of the GraphQL-Fusion spec draft.

The GraphQL-Fusion spec goes beyond what traditional federation approaches went after. It establishes GraphQL as an application gateway that allows integrating GraphQL APIs, REST APIs, gRPC APIs, or even databases. For this reason, in addition to The Guild's work on the Open API to GraphQL spec, Hasura will start specifying GraphQL Data Compliant APIs, the AWS AppSync team will focus on specs for throttling, authentication, and subscriptions and WunderGraph will specify adapter specs for gRPC and Kafka (AsyncApi). As mentioned initially, GraphQL is a great gateway technology, although it started from a different place. It gives the consumer the simplicity of the single schema and hides behind that schema the technical complexities of a heterogenous service landscape.

# A new way to distribute GraphQL schema components

GraphQL-Fusion presents a fresh approach to streamlining the complexities of assembling distributed schemas.

At its heart, GraphQL-Fusion pivots around two foundational principles: schema composition and query planning.

But before delving into these concepts, it's essential to retrace our steps. Let's revisit the challenges surfaced when people first tried GraphQL as a Gateway for constructing their GraphQL servers over REST APIs.

The ideal scenario is one where our teams operate autonomously, deploying updates at their pace. However, positioning a GraphQL server at the forefront as the gateway introduced an unexpected bottleneck to the development flow. Suddenly, updating downstream APIs required updates to the central GraphQL server, leading to inevitable synchronization hurdles. Burdening teams with higher maintenance and reduced flexibility.

While GraphQL schema stitching solutions simplified the composition of GraphQL Gateways, they still suffered from the same coordination dilemma since the gateway retained pivotal configuration logic. Federated GraphQL solutions emerged as a remedy, redistributing this configuration logic across subgraphs, thus enabling teams to work and release subgraphs autonomously.

Fusion represents a fully federated approach but also incorporates the capabilities of stitching solutions to rewrite and transform subgraph schemas. Further, Fusion removes the requirement of subgraph protocols we see in many federated GraphQL solutions. This means you can use any GraphQL server as a Fusion subgraph, and the capabilities of your subgraph within a Fusion setup are defined by the GraphQL spec version your GraphQL server implements.

The Fusion schema composition aims to infer the semantic meaning of a GraphQL schema, reducing annotations to the schema. Fusion schema composition recognizes GraphQL best practices like the Relay patterns or naming patterns and their semantics. Instead of treating fields and types bearing identical names as collisions, Fusion recognizes them as overlaps.

For clarity, consider the following GraphQL query type example:

```graphql
type Query {
  userByID(id: ID!): User
  productBySKU(sku: String!): Product
  articleBySlug(slug: String!): Article
}
```

In this example, fields follow the `{type}By{key}` naming convention:

- userByID for fetching users by ID
- productBySKU for retrieving products by SKU
- articleBySlug for obtaining articles by slug

Things we can fetch by one or multiple keys are entities to Fusion, allowing the Fusion query planner to create query plan tasks to fill in data from various subgraphs. Fusion does not need to know their keys spelled out, as this is inferred from their resolver signature.

Let's consider two subgraphs - one for product reviews and another for user data.

**Subgraph 1: Product Reviews**

```graphql
type Review {
  id: ID!
  body: String!
  product: Product!
  author: User!
}

type User {
  id: ID!
  name: String!
  reviews: [Review!]
}

type Product {
  sku: String!
  reviews: [Review!]
}

type Query {
  reviews: [Review!]
  reviewById(id: ID!): Review
  userById(id: ID!): User
  productBySKU(sku: String!): Product
}
```

**Subgraph 2: User Data**

```graphql
type User {
  id: ID!
  name: String!
  email: String!
}

type Query {
  userById(id: ID!): User
}
```

The outcome? An annotated Fusion graph document, which provides all the metadata for the Fusion gateway query planner.

**Composed Fusion Graph**

```graphql
type Review
  @variable(subgraph: "Reviews", name: "Review_id", select: "id")
  @resolver(
    subgraph: "Reviews"
    select: "{ reviewById(id: $Review_id) }"
    arguments: [{ name: "Review_id", type: "ID!" }]
  ) {
  id: ID! @source(subgraph: "Reviews")
  body: String! @source(subgraph: "Reviews")
  product: Product! @source(subgraph: "Reviews")
  author: User! @source(subgraph: "Reviews")
}

type User
  @variable(subgraph: "Reviews", name: "User_id", select: "id")
  @variable(subgraph: "Account", name: "User_id", select: "id")
  @resolver(
    subgraph: "Reviews"
    select: "{ userById(id: $id) }"
    arguments: [{ name: "User_id", type: "ID!" }]
  )
  @resolver(
    subgraph: "Account"
    select: "{ userById(id: $id) }"
    arguments: [{ name: "User_id", type: "ID!" }]
  ) {
  id: ID! @source(subgraph: "Reviews") @source(subgraph: "Account")
  name: String! @source(subgraph: "Reviews") @source(subgraph: "Account")
  email: String! @source(subgraph: "Account")
}

type Product
  @variable(subgraph: "Reviews", name: "Product_sku", select: "sku")
  @resolver(
    subgraph: "Reviews"
    select: "{ productBySKU(sku: $Product_sku) }"
    arguments: [{ name: "Product_sku", type: "String!" }]
  ) {
  sku: String! @source(subgraph: "Reviews")
  reviews: [Review!] @source(subgraph: "Reviews")
}

type Query {
  reviews: [Review!] @resolver(subgraph: "Reviews", select: "{ reviews }")
  userById(id: ID!): User
    @resolver(
      subgraph: "Reviews"
      select: "{ userById(id: $id) }"
      arguments: [{ name: "id", type: "ID!" }]
    )
    @resolver(
      subgraph: "Account"
      select: "{ userById(id: $id) }"
      arguments: [{ name: "id", type: "ID!" }]
    )

  reviewById(id: ID!): Review
    @resolver(
      subgraph: "Reviews"
      select: "{ reviewById(id: $id) }"
      arguments: [{ name: "id", type: "ID!" }]
    )

  productBySKU(sku: String!): Product
    @resolver(
      subgraph: "Reviews"
      select: "{ productBySKU(id: $id) }"
      arguments: [{ name: "id", type: "ID!" }]
    )
}
```

# Query Planning and Optimizations

The above-annotated schema document allows the Fusion gateway to plan data fetching from its subgraphs efficiently.

When executing a query like the following:

```graphql
query GetReviews {
  reviews {
    body
    author {
      name
      email
    }
  }
}
```

The query planner might produce two downstream queries:

**Query 1**

```graphql
query GetReviews_1 {
  reviews {
    body
    author {
      name
      __export__1: id
    }
  }
}
```

**Query 2**

```graphql
query GetReviews_2($__export__1: ID!) {
  userById(id: $__export__1) {
    email
  }
}
```

We are essentially doing an initial call to the reviews services, collecting all user ids, and then doing a call to our accounts subgraph for each user id we collected to get the emails. While this is not efficient, as we would have to make multiple subgraph requests, the Fusion composition and query planner also understand batching fields and how to integrate them into the query planning process. If we introduced the following root field to our accounts subgraph and recomposed:

```graphql
extend type Query {
  usersById(ids: [ID!]!): [User!]
}
```

The composition would add a batching resolver to the `User` type:

```graphql
extend type User
  @resolver(
    subgraph: "Account",
    select: "{ usersById(ids: $User_Id) }",
    arguments: [ { name: "User_Id", type: "[ID!]!" } ],
    kind: "BATCH_BY_KEY"
    ) {
}
```

With this new field in place, the query planner can prioritize batch resolvers whenever we branch off a request in a list context, even if that list context spreads multiple levels deep.

**Query 1**

```graphql
query GetReviews_1 {
  reviews {
    body
    author {
      name
      __export__1: id
    }
  }
}
```

**Query 2**

```graphql
query GetReviews_2($__export__1: [ID!]!) {
  usersById(id: $__export__1) {
    email
  }
}
```

The Fusion query plan is another standardized component that tooling (like [Banana Cake Pop](https://eat.bananacakepop.com)) can use to give you insights into how efficiently the gateway can resolve the requested data.

![Banana Cake Pop - Query Plan Viewer](bcp-1.png)
_Also available in black ;)_

The Fusion Query plan consists of the following query plan node kinds: `Compose`, `Defer`, `Stream`, `If`, `Introspect`, `Parallel`, `Resolve`, `ResolveByKeyBatch`, `ResolveNode`, `Sequence`, and `Subscribe`. With these abstract nodes, the query planner is able to create complex query plans that support every GraphQL feature and best practice right out of the gate.

While the `Fetch` and `Batch` nodes are clear about what they do in our query plan, the compose step might be a mystery to you. In essence, the query planner can fetch data that does not align with the current structure of the request. Compose will take in the raw data fetched by resolve nodes and composes it into the GraphQL request structure. It also ensures that result coercion rules are correctly applied to be GraphQL spec-compliant.

![Banana Cake Pop - Query Plan Viewer](bcp-5.png)
_In this case, compose creates the result of a single selection set from multiple resolve nodes._

The Hot Chocolate Fusion Gateway implementation supports all supported subscription protocols, from the legacy Apollo subscription protocol over graphql-ws to graphql-sse.

Further, it supports file uploads with the GraphQL multipart request protocol, Facebook-style batching with the `@export` directives, the newest `@defer` and `@stream` spec draft, the newest Client Controlled Nullability spec draft, and many more GraphQL features.

Distributed GraphQL should **not limit** what you can do with GraphQL.

# Relay

The schema composition can also introduce aspects such as the Relay conventions to your Gateway schema, even if they aren't implemented in your subgraphs.

Alternatively, if your subgraphs implement the Relay conventions, such as the global object identity convention, the schema composition will detect this and incorporate it into the Fusion graph document. For example, this can optimize your query planning by utilizing the node field. Further, this makes all object types that implement the `Node` interface an entity to Fusion.

```graphql
extend type User
  @resolver(
    subgraph: "User",
    select: "{ node(id: $User_id) { ... on User { ... User } } }",
    arguments: [ { name: "User_id", type: "ID!" } ])
  @resolver(
    subgraph: "User",
    select: "{ nodes(ids: $User_id) { ... on User { ... User } } }",
    arguments: [ { name: "User_id", type: "[ID!]!" } ],
    kind: "BATCH_BY_KEY") {
}
```

While using the `node` field to fetch entity data is straightforward for exposing the `node` fields to the gateway, we found it necessary to equip the Fusion gateway with data sharding capabilities. This is the ability to dispatch a query at runtime to a specific subgraph based on user-provided data. This can be applied to simple tasks like the node field but can also be harnessed to isolate data partitions by region or any other discriminants you desire.

![Banana Cake Pop - Query Plan Viewer](bcp-6.png)
_`node` field query plan._

If we zoom into the JSON representation of our query plan, we can see in detail the branches of our `ResolveNode` in the query plan. Depending on the type in our encoded `ID`, one of the branches will be executed. If the encoded types have different names in the subgraphs, Fusion will reencode the ID for the particular subgraph.

![Banana Cake Pop - Query Plan Viewer](bcp-7.png)
_JSON representation of our query plan_

# Going Further

While the subgraph inference of the schema composition is quite powerful, there are a lot of cases where we can go further by declaring the semantics of a GraphQL schema. We do not need to integrate such annotations into our subgraph schema directly but can pass additional GraphQL documents into the schema composition that hold type extensions with additional directive annotations.

Let's say the batching field we introduced did not follow the conventions of the other fields in our GraphQL schema.

```graphql
extend type Query {
  users(ids: [ID!]!): [User!]
}
```

In this case, the schema composition cannot just guess what `ids` is. `ids` could be identities for whatever. This is where we can use the fusion subgraph directives to bring meaning to the schema.

```graphql
extend type Query {
  users(ids: [ID!]! @is(field: "id")): [User!]
}
```

The `@is` directive allows us to specify that the argument on our field `users` is semantically identical to the output field `id` on their returning `User` type. Since `ids` is a list that returns a list of users, we can now infer that this field allows us to batch-fetch users by user ids.

# Requirements

Where subgraph directives really become necessary is with requirements. Data requirements let us integrate two or more subgraphs with each other without bleeding internal data requirements into the public schema.

Let's say we have the following schema:

```graphql
type Product {
  sku: String!
  name: String!
  dimension: ProductDimension
}
```

Also, let's say we have a subgraph that can calculate a delivery estimate for a product.

```graphql
type Product {
  deliveryEstimate(zip: String!, width: Float!, height: Float!): Int!
}
```

We need the ZIP code and the product's width and height to calculate the delivery estimate in our shipping subgraph. The product's dimension (width and height) is actually available in the product catalog service, which holds all the information about the product itself.

In this case, we want to create a public API for our consumer where we only have to pass in the ZIP code to the `deliveryEstimate` field on the `Product` type on our Fusion graph.

```graphql
type Product {
  sku: String!
  name: String!
  dimension: ProductDimension
  deliveryEstimate(zip: String!): Int!
}
```

We can express this by using the `@require` directive and referring to the required information relative to the `Product` type.

```graphql
type Product {
  deliveryEstimate(
    zip: String!
    width: Float! @require(field: "dimension { width }")
    height: Float! @require(field: "dimension { height }")
  ): Int!
}
```

We could also design that slightly differently and introduce an input to our subgraph representing the required data we need.

```graphql
input ProductDimensionInput {
  width: Float!
  height: Float!
}

type Product {
  deliveryEstimate(
    zip: String!
    dimension: ProductDimensionInput! @require(field: "dimension")
  ): Int!
}
```

The outcome will stay the same, and we will get this nice API for our users. The query planner will resolve the required data under the hood.

![Banana Cake Pop - Query Plan Viewer](bcp-2.png)

Again, this brings clarity to your subgraph as the field is very clear about what it needs and becomes easily testable in the process.

# Reshaping things

When we rethink a bit the shipping subgraph we actually should realize that the `deliveryEstimate` does not really need to be on the `Product` type as the argument has clear requirements which are expressed by its field arguments. Instead of having the field `deliveryEstimate` on the `Product` type itself, it could very well be exposed through the `Query` type, at least in the context of our subgraph.

```graphql
type Query {
  estimateShipping(zip: String!, width: Float!, height: Float!): Int!
}
```

In the case the subgraph is isolated and does not fully integrate with our intended public model, we can also reshape the subgraph to make it fit.

All the annotations can be put into separate graphql documents providing the extending metadata. This allows us to keep our actual subgraph schema clean. It also helps when you do not fully own the schema that you integrate, like, for instance, the GitHub schema. Just create a `schema.extensions.graphql` and put your annotations and extension in that file, and you're good to go.

First, let's make the whole query type private; we do not want to include anything by default from this subgraph.

```graphql
extend type Query @private
```

Next, we introduce some product metadata.

```graphql
extend type Product {
  estimateShipping(
    zip: String!
    width: Float! @require(field: "dimension { width }")
    height: Float! @require(field: "dimension { height }")
  ): Int!
}

extend type Query @private
```

Last, we want to declare how estimate wires up to our internal `Query` type.

```graphql
extend type Product {
  estimateShipping(
    zip: String!
    width: Float! @require(field: "dimension { width }")
    height: Float! @require(field: "dimension { height }")
  ): Int! @resolve
}

extend type Query @private
```

Since the field and arguments 100% match between the `Query` type and the `Product` type extension, we only need to put the `@resolve` directive on the field without specifying any mapping of arguments. But let's imagine we call it `calculateDelivery` on the product type. In this case, we need to become more explicit.

```graphql
extend type Product {
  calculateDelivery(
    zip: String!
    width: Float! @require(field: "dimension { width }")
    height: Float! @require(field: "dimension { height }")
  ): Int! @resolve(select: "estimateShipping")
}

extend type Query @private
```

Again, arguments match, so we do not need to map them, but we could. Each argument would become an implicit variable in this case.

```graphql
extend type Product {
  calculateShipping(
    zip: String!
    width: Float! @require(field: "dimension { width }")
    height: Float! @require(field: "dimension { height }")
  ): Int! @resolve(select: "estimateShipping(zip: $zip)")
}

extend type Query @private
```

Arguments that you do not map are again inferred, allowing you always just to specify the minimum. Since Fusion compiles the Fusion Graph at build time, this is fine, as the schema composition will always tell you what is missing and precisely in which file you have to specify more information for the composition and query planner to work.

Let's move on from the requirements case and dig deeper into the type reshaping capabilities. Often when we build our data silos, we also do not have all the stub types in there. It would sometimes be tedious to always have them around. Think of the review service.

```graphql
type Review {
  id: ID!
  body: String!
  product: Product!
  author: User!
}
```

This `Product` type is essentially just the `sku` field of the public `Product` type. In many cases, people are more tempted to create something like the following in the subgraph schema since it's just less cluttered.

```graphql
type Review {
  id: ID!
  body: String!
  productSKU: String!
  author: User!
}
```

With Fusion, you can provide us with some metadata in the schema extension file, and we will ensure that the references are introduced on our publicly exposed gateway schema.

```graphql
extend type Review {
  productSKU: String! @is(coordinate: "Product.sku") @private
  product: Product! @resolve
}
```

By declaring the semantics of the field `productSKU`, we can infer a way to resolve a product using one existing way to fetch a `Product` entity. Again, if there is no way to resolve it, we will give you a composition error telling you which subgraphs you could or should introduce `Query` fields to, to resolve the `Product` entity.

In many cases, we want to connect our types from both sides.

```graphql
extend type Product {
  reviews: [Review!] @resolve
}

extend type Review {
  productSKU: String! @is(coordinate: "Product.sku") @private
  product: Product! @resolve
}
```

For this to work, we would need to introduce a `reviewsBySKU` to our reviews subgraph. But in any case, we will be told by our schema composition if it is missing on our subgraph.

Like with our case for estimate delivery, we can be more or less explicit with our `@resolve` directive.

```graphql
extend type Product {
  reviews: [Review!] @resolve(select: "reviewsBySku(sku: $sku)")
}
```

Since `sku` is available on the product, it is automatically a variable available to inject. But because of collisions with field arguments or if the actual `sku` is not directly on the `Product` type, we could also explicitly declare the variable and state what we mean.

```graphql
extend type Product {
  reviews: [Review!]
    @declare(variable: "sku", select: "someOtherField { sku }")
    @resolve(select: "reviewsBySku(sku: $sku)")
}
```

> The `select` argument represents a field selection or selection set syntax and also allows for more complex query constructs that refer to GraphQL query files using fragments and other query constructs. For this introduction to Fusion as a concept, we keep it simple.

When I said at the beginning that Fusion lends concepts from both schema stitching and federation approaches, then its this kind of flexibility that I mean, you can build your graph in a federated structure, and you will, in most cases, not need to declare anything to the composition as everything can be inferred, but you can become very explicit with hints or even with the more precise `@resolve` directive.

# Open Telemetry for Federated Tracing

This brings me to another aspect of Fusion: telemetry. While the GraphQL-Fusion spec isn't primarily concerned with tracing itself, we've decided to leverage OpenTelemetry for the Hot Chocolate Fusion Gateway implementation. We're working to establish a more precise semantic convention for GraphQL in collaboration with the OpenTelemetry community. This effort aims to enable standard GraphQL servers to use OpenTelemetry to expose the intricate processes that occur when a GraphQL server handles a request. These traces, correlated from the gateway to the subgraph, allow any vendor to digest tracing events and provide profound insights into where performance bottlenecks exist in your distributed system.

Combined with the GraphQL subgraphs, which use instead of a generic `_entities` field actual semantic fields like `reviewsBySKU` in Fusion to retrieve data from subgraphs, the traces become very clear to read and expose optimization potential to the developers. The best part? There's no need for specialized approaches — it's as straightforward as crafting a conventional resolver. With the release of [Banana Cake Pop](https://eat.bananacakepop.com) version 9, we're introducing our revamped query plan viewer. This tool signifies our initial step towards integrating telemetry data from GraphQL-Fusion, aiming to provide comprehensive insights into the operations of your distributed GraphQL setup. However, thanks to the open nature of the GraphQL-Fusion spec and the OpenTelemetry definitions, you're not confined to our tools—alternatives like [The Guild's Hive](https://the-guild.dev/graphql/hive), [WunderGraph's Cosmo](https://wundergraph.com/cosmo), or even a plain Elastic Cloud integration are also available.

# CI/CD integrations from the start

We considered CI/CD from the start when conceptualizing Fusion and structured it so that you can easily integrate your solution. Right out of the gate, you can start with [Banana Cake Pop](https://eat.bananacakepop.com), which provides a schema registry, easy rollbacks of changes introduced by your subgraphs, and deployment pipeline synchronization.

![Banana Cake Pop - Stages](bcp-3.png)

But the core principle is that this is open and built into the GraphQL-Fusion spec. To provide tooling a single file containing all the information needed for gateway configuration and even space for gateway-specific features, we've adopted the [Open Packaging Convention](https://en.wikipedia.org/wiki/Open_Packaging_Conventions) as a container for the GraphQL-Fusion Configuration (.fgp).

The [Open Packaging Convention](https://en.wikipedia.org/wiki/Open_Packaging_Conventions) is an open standard provided by [Microsoft](https://microsoft.com), used for everything from Word Documents (.docx) to VSCode extension packages (.vsix). Simply put, think of it as a ZIP container with metadata and relations between its artifacts. The GraphQL-Fusion convention contains the mandatory Fusion Graph document. This document is all that's needed to run and configure a Gateway implementing the core specification.

Additionally, it contains all subgraph schema documents, the publicly exposed Gateway schema, and composition settings the user has opted into. Having all these artifacts in one place gives us a single artifact that we can pass on from the schema composition in a CI/CD pipeline to the schema registry and from there to the actual gateway. We have customers already using this with their custom solutions for distributing the configuration from their deployment pipeline to their gateway or by using our Cloud Services ([Banana Cake Pop](https://eat.bananacakepop.com)). Besides these standard artifacts included in the package, it also allows Gateway implementers to store custom configurations to specify GraphQL WAF settings and more.

![Simple Deployment Pipeline](pipeline-1.png)

# Apollo Federation

We recognize that some of you may have opted into Apollo Federation as a solution, and that is why we designed the Fusion schema composition so that it can compose any Apollo Federation subgraph into a Fusion subgraph. This allows you to seamlessly migrate from an Apollo Federation setup to a GraphQL-Fusion setup without the need to rewrite anything.

# Conclusion

We are still working on GraphQL-Fusion, but you can try an early version already today with the Hot Chocolate Fusion Gateway. We plan to release the GraphQL-Fusion spec as it matures later this year as **MIT license**. While the current iterations are primarily concerned with GraphQL, as mentioned before The Guild, in collaboration with IBM and StepZen, has begun specifying the Open API to GraphQL transformation they've developed in Mesh, and we'll integrate this as it becomes available. Hasura is working on GraphQL Compliant Data APIs spec and WunderGraph wants to contribute a spec for gRPC and Kafka (AsyncApi) to take federated GraphQL to a whole new level.

There's much more from the query plan engine to the schema composition we're eager to showcase in detail. Today I wanted to start talking about GraphQL-Fusion as a concept. We are also working on step-by-step YouTube tutorials for later this year that shows you how to create a GraphQL-Fusion setup from scratch or how to migrate from an Apollo Federation setup without skipping a beat to a GraphQL-Fusion setup.

The one crucial thing behind this effort is creating a truly open spec, which leans heavily on the GraphQL spec and describes the algorithms behind the schema composition and the query planning. No single company will own the spec as the GraphQL Foundation will take ownership of it. This ensures that we have a level playing field where companies can provide services, tooling, or gateways. It gives a better choice to developers building distributed systems with GraphQL as they can easily connect tools from different vendors.

You can join me at [GraphQL conf in San Francisco](https://graphql.org/conf/schedule/4a4e842d1cd0c06083f484d31225abd1/?name=GraphQL%20Fusion:%20Rethinking%20Distributed%20GraphQL%20-%20Michael%20Staib,%20ChilliCream%20Inc) as I will be giving a talk about GraphQL-Fusion with the latest bits.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Let’s Boost Your Productivity With APIs]]></title>
        <id>https://chillicream.com/blog/2023/03/15/banana-cake-pop-graphql-apis</id>
        <link href="https://chillicream.com/blog/2023/03/15/banana-cake-pop-graphql-apis"/>
        <updated>2023-03-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Together, we'll explore the new API feature coming with Banana Cake Pop 5 very soon.]]></summary>
        <content type="html"><![CDATA[
In version 5, the biggest change that will arrive soon is _APIs_, which will introduce a way to reorganize your documents completely. Let’s find out how this will change your life when working with _GraphQL_ _APIs_ in **Banana Cake Pop**. Go to [bananacakepop.com](https://bananacakepop.com) and check out the latest _Insider_ app or web version to get a taste of _APIs_. Watch the video to get more info about what APIs are and how they work.

# Subscribe

To stay up to date, subscribe to our [ChilliCream YouTube Channel](https://www.youtube.com/c/ChilliCream) to get notified whenever we publish new videos.

I'm Rafael Staib, and as soon as **Banana Cake Pop 5** is released, I'll be right here to tell you what's new in **Banana Cake Pop**!
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[What's new for Hot Chocolate 13]]></title>
        <id>https://chillicream.com/blog/2023/02/08/new-in-hot-chocolate-13</id>
        <link href="https://chillicream.com/blog/2023/02/08/new-in-hot-chocolate-13"/>
        <updated>2023-02-08T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
The last major release of Hot Chocolate was on the 27th of September, and since then, I have stopped writing blogs and focused more attention on YouTube. But for this occasion, it feels right to write and would have anyway resulted in a video that is too long.

# What is Version 13 about?

When we started on Hot Chocolate 13, the release focused on our Gateway, aka schema stitching. As we worked on schema stitching, it became apparent to us that we wanted to change and make it much easier than the current solutions that are out there. Distributed graphs should work with GraphQL and not force you to build them in a certain way but still yield best-in-class performance. At some point, our work branched off the original stitching project, and we created a new component called Hot Chocolate Fusion. As we were working on Hot Chocolate Fusion, we saw the time pass by and estimated that it would take considerable time more to get it done in the quality it should be. At this point, we already had so many great features and bugfixes merged into version 13 that we decided to focus development on delivering a Hot Chocolate 13 core with many improvements and ship Fusion as a dot release of 13 when it's ready.

If you asked me what the focus is of version 13, then I would say developer experience and more :)

# GraphQL over Internet

One major focus we put on Hot Chocolate 13 is transport. With Hot Chocolate 13, we are one of two servers (GraphQL-yoga and Hot Chocolate) fully supporting the new GraphQL over HTTP spec draft. The transport spec defines when to use which HTTP status code and introduces a new response content-type, `application/graphql-response+json`. The new transport spec makes proper use of the HTTP accept headers, meaning your client can now define what response content-types it understands and can handle. If your client, for instance, can only deal with `application/json` as a response content-type, then you can define that now in your request.

```curl
curl 'https://api-crypto-workshop.chillicream.com/graphql' \
  -H 'authority: api-crypto-workshop.chillicream.com' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  --data-raw '{"query":"{ __typename }\n","variables":{}}' \
  --compressed
```

[GraphQL over HTTP Spec](https://github.com/graphql/graphql-over-http)

If you do not want to use the new GraphQL over HTTP spec draft, then you can opt into our legacy mode, which uses `application/json` and 200 HTTP status codes.

```csharp
using HotChocolate.AspNetCore;
using HotChocolate.AspNetCore.Serialization;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddHttpResponseFormatter(
        new HttpResponseFormatterOptions
        {
            HttpTransportVersion = HttpTransportVersion.Legacy
        });

builder.Services
    .AddGraphQLServer()
    .AddTypes();

var app = builder.Build();
app.MapGraphQL();
app.Run();
```

> Note: After 2025-01-01T00:00:00Z, GraphQL servers are no longer required to support the legacy transport mode.

Apart from GraphQL over HTTP, we also focused on supporting even more GraphQL transport protocols. So, with Hot Chocolate 13, we now implement the GraphQL-SSE protocol, which allows you to use server-sent events for subscriptions or even queries that use defer. GraphQL-SSE, for me, has become the go-to solution for subscriptions.

But we also brought the WebSocket transport up to speed with GraphQL-WS. We now support the legacy Apollo subscription protocol and the new GraphQL-WS protocol.

![Banana Cake Pop - Subscription Protocol Selection Dialog](bcp-1.png)

[GraphQL-SSE Protocol](https://github.com/enisdenjo/graphql-sse) /
[GraphQL-WS Protocol](https://github.com/enisdenjo/graphql-ws)

## Cache-Control

We now have implemented the GraphQL cache-control feature, which allows you to specify cache-control headers for GraphQL query responses based on the entities you query.

To enable Cache-Control, you will need to install the package `HotChocolate.Caching`.

```bash
dotnet add package HotChocolate.Caching
```

Next, we will need to add the following to your GraphQL configuration. by default.

```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddGraphQLServer()
    .AddTypes()
    .AddCacheControl()
    .UseQueryCachePipeline();

var app = builder.Build();
app.MapGraphQL();
app.Run();
```

Hot Chocolate will apply defaults to your fields which you can override on a by-field basis.

```csharp
[QueryType]
public static class Query
{
    [CacheControl(maxAge: 10_000)]
    public static Book GetBook()
        => new Book("C# in depth.", new Author("Jon Skeet"));
}
```

The GraphQL cache-control header will collect the allowed amount of time the response is cacheable and exposes this as a cache-control header which consequently can be used by CDNs or browsers to cache the result.

## Null Values

Another smaller optimization option we have introduced to Hot Chocolate is the null value erasure.

```csharp
using HotChocolate.AspNetCore.Serialization;
using HotChocolate.Execution.Serialization;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddHttpResponseFormatter(
        new HttpResponseFormatterOptions
        {
            Json = new JsonResultFormatterOptions
            {
                NullIgnoreCondition = JsonNullIgnoreCondition.Fields
            }
        });

builder.Services
    .AddGraphQLServer()
    .AddTypes();

var app = builder.Build();
app.MapGraphQL();
app.Run();
```

Writing now a query where we fetch a field that is null ...

```graphql
{
  book {
    title
    descriptionIsNull
  }
}
```

... will yield the following result.

```json
{
  "data": {
    "book": {
      "title": "C# in depth."
    }
  }
}
```

So, by opting into this formatter feature, we will no longer serialize null fields. Relay now supports this, and you can opt for the same thing when using it.

# Developer Experience

We developers generally like to write less code, or more precisely, to write less repetitive code. The more we can focus on building awesome APIs, the happier we are. This is one of our guiding principles when looking at features. This is why I like source generators so much: we can offload the tedious bits and let someone else write those. The other plus side is that we can still get best-in-class performance since things analyzed and generated with source generators at build time are already computed, with no overhead and unpredictability at runtime.

## Type Auto Registration

With Hot Chocolate 13, we are embracing more features driven by source generators. Let me give you an example here. The following code shows you the GraphQL configuration of a smaller project with five entities without our source generators.

```csharp
builder.Services
    .AddGraphQLServer()
    .AddQueryType()
    .AddMutationType()
    .AddSubscriptionType()
    .AddTypeExtension<AttendeeQueries>()
    .AddTypeExtension<AttendeeMutations>()
    .AddTypeExtension<AttendeeSubscriptions>()
    .AddTypeExtension<AttendeeNode>()
    .AddDataLoader<AttendeeByIdDataLoader>()
    .AddTypeExtension<SessionQueries>()
    .AddTypeExtension<SessionMutations>()
    .AddTypeExtension<SessionSubscriptions>()
    .AddTypeExtension<SessionNode>()
    .AddDataLoader<SessionByIdDataLoader>()
    .AddDataLoader<SessionBySpeakerIdDataLoader>()
    .AddTypeExtension<SpeakerQueries>()
    .AddTypeExtension<SpeakerMutations>()
    .AddTypeExtension<SpeakerNode>()
    .AddDataLoader<SpeakerByIdDataLoader>()
    .AddDataLoader<SessionBySpeakerIdDataLoader>()
    .AddTypeExtension<TrackQueries>()
    .AddTypeExtension<TrackMutations>()
    .AddTypeExtension<TrackNode>()
    .AddDataLoader<TrackByIdDataLoader>()
    .AddUploadType()
    .AddFiltering()
    .AddSorting()
    .AddGlobalObjectIdentification()
    .AddInMemorySubscriptions()
    .AddFileSystemQueryStorage("./persisted_queries")
    .UsePersistedQueryPipeline();
```

And now, let's have a look at the same project with Hot Chocolate 13 and source generators.

```csharp
builder.Services
    .AddGraphQLServer()
    .AddTypes()
    .AddUploadType()
    .AddFiltering()
    .AddSorting()
    .AddGlobalObjectIdentification()
    .AddInMemorySubscriptions()
    .AddFileSystemQueryStorage("./persisted_queries")
    .UsePersistedQueryPipeline();
```

This is amazing! You focus on your code, and the Hot Chocolate source generator will write all those registrations for you. In our example which we migrated from Hot Chocolate 11 to 13, we reduced the configuration code from 32 lines to 10 lines of code. The best thing here is you will never again forget to register a type or DataLoader.

<Video videoId="s1rXR46h86o" />

## DataLoader

But this is not where this ends. One of the most dreaded pieces of code in a GraphQL project is the class DataLoader. DataLoader are amazing as they help you write APIs that take advantage of batched fetches to data sources and ensure that your graph is consistent. But they are just so much fricking code.

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ConferencePlanner.GraphQL.Data;
using GreenDonut;

namespace ConferencePlanner.GraphQL.DataLoader
{
    public class TrackByIdDataLoader : BatchDataLoader<int, Track>
    {
        private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;

        public TrackByIdDataLoader(
            IDbContextFactory<ApplicationDbContext> dbContextFactory,
            IBatchScheduler batchScheduler,
            DataLoaderOptions options)
            : base(batchScheduler, options)
        {
            _dbContextFactory = dbContextFactory ??
                throw new ArgumentNullException(nameof(dbContextFactory));
        }

        protected override async Task<IReadOnlyDictionary<int, Track>> LoadBatchAsync(
            IReadOnlyList<int> keys,
            CancellationToken cancellationToken)
        {
            await using ApplicationDbContext dbContext =
                _dbContextFactory.CreateDbContext();

            return await dbContext.Tracks
                .Where(s => keys.Contains(s.Id))
                .ToDictionaryAsync(t => t.Id, cancellationToken);
        }
    }
}
```

With Hot Chocolate 13, we are making DataLoader seamless and reducing them to the fetch function. Moreover, you can now co-locate them with the GraphQL-specific code you have for your entities.

```csharp
[DataLoader]
internal static async Task<IReadOnlyDictionary<int, Track>> GetTrackByIdAsync(
    IReadOnlyList<int> ids,
    ApplicationDbContext context,
    CancellationToken cancellationToken)
    => await dbContext.Tracks
        .Where(s => ids.Contains(s.Id))
        .ToDictionaryAsync(t => t.Id, cancellationToken);
```

The source generator will take the above code and generate the actual DataLoader for us, which you can consequently use in your resolvers, just as if you wrote all of this on your own. This works even with things like entity framework, where we could not execute with multiple threads on the same context. In the past, this would have made you write a ton of additional code to create scope or handle DBContextFactory. With Hot Chocolate 13, it's just one additional switch on the `DataLoaderAttribute`.

```csharp
[DataLoader(ServiceScope = DataLoaderServiceScope.DataLoaderScope)]
```

<Video videoId="72WVRPwzwLk" />

## Resolver Compiler

While we love source generators, we also use runtime code generation to remove clutter further. When we register a DBContext globally, we actually register an `IParameterExpressionBuilder` that will analyze resolver code and generate and compile expressions at runtimes so that you get the best-optimized resolver possible with the least amount of code. We simplified how you can now write your own expression builder to handle global states or other things you want to simplify.

```csharp
builder.Services
    .AddGraphQLServer()
    ...
    .AddParameterExpressionBuilder(
        ctx => ctx.GetGlobalStateOrDefault<ServiceState>(nameof(ServiceState)))
```

For a deep dive into resolver compilers, you can watch the following YouTube episode:

<Video videoId="c2hymm0FLio" />

## Directives

Directives are one of the last APIs we had that were Code-First and Schema-First only but could not be created with the annotation-based approach. With Hot Chocolate 13, we have revamped directives, and they are now super sleek.

```csharp
[DirectiveType(DirectiveLocation.Field)]
public class MyQueryDirective
{
    public MyQueryDirective(string myArg)
    {
        MyArg = myArg;
    }

    public string MyArg { get; }
}
```

The above translates to the following directive.

```SDL
directive @myQuery(myArg: String!) on FIELD
```

We can use this directive now right in our query.

```graphql
{
  book {
    title @myQuery(myArg: "abc")
  }
}
```

If you want to learn more about the improvements we have made for GraphQL directives in Hot Chocolate 13, you can head over into the following video:

<Video videoId="egyO7rZOoMI" />

## JSON Scalar

For some time, we had a scalar called Any, which allowed us to have some untyped data in our graph. But it was ugly how it was constructed with dictionary structures in our resolvers. Further, many of you just wanted to use clean JSON to specify the data. With Hot Chocolate 13, we are now introducing a clean JSON scalar that uses JsonElement as its runtime type.

```csharp
[ExtendObjectType<Book>]
public class BookResolvers
{
    public JsonElement Variant1
        => JsonDocument.Parse(
            """
            {
                "a": 123
            }
            """)
            .RootElement;

    [GraphQLType<JsonType>]
    public string Variant2
        =>
        """
        {
            "a": 123
        }
        """;
}
```

We called it JSON and did not rework Any to keep your existing code working. You can, however, register the JSON scalar as any type if you want to use it in place of the Any scalar.

```csharp
builder.Services
    .AddGraphQLServer()
    .AddTypes()
    .AddType(new JsonType("Any", BindingBehavior.Implicit));
```

<Video videoId="wODiVDT8ECI" />

## Generic Attributes

With Hot Chocolate 13 we are taking advantage of generic attributes in .NET 7. Instead of writing an ugly attribute like the following:

```csharp
[ExtendObjectType(typeof(Foo))]
public static class FooResolvers
```

You can no use it's generic version.

```csharp
[ExtendObjectType<Foo>]
public static class FooResolvers
```

The same goes for many other projects.

## Entity Framework

In the past, we have optimized Hot Chocolate to use the pooled factory approach when using Entity Framework. This did not sit well with many developers since it forced them to rewrite their long-established code patterns with scoped repositories. Hot Chocolate 13 will help you here and reduce the code and complexity of using Entity Framework to almost nothing.

First, when you register a DBContext as a global service with the GraphQL schema, we will handle it as a resolver-scoped service. This means that the executor will create a service scope at the resolver level and retrieve this service from there. All other services that you might use in the resolver are still retrieved from the request service provider. This is important, especially as things like DataLoader enter the scene.

The DBContext, in this case, can still be coming from a pool, but instead of using the factory configuration, you can now use the standard `AddDbContext` or the `AddDbContextPool`. Whatever makes you happy.

```csharp
builder.Services.AddDbContextPool<AssetContext>(o => o.UseSqlite("Data Source=assets.db"));
```

On our schema, we just register the `AssetContext` as a DBContext.

```csharp
builder.Services
    .AddGraphQLServer()
    .AddTypes()
    .RegisterDbContext<AssetContext>();
```

With this registration, we essentially tell our resolver compiler about this well-known service and how to handle it. We now can just use it in our resolver, no attributes, no special code, nothing, just use it.

```csharp
public static IQueryable<Asset> GetAssets(AssetContext context) => context.Assets;
```

But I talked about repositories, and this again is about the DBContext. The DBContext is just a specialized well-known service to the GraphQL engine. You can do the same with any repository or service object registered with the DI.

```csharp
builder.Services
    .AddGraphQLServer()
    .AddTypes()
    .RegisterService<AssetRepository>(ServiceKind.Resolver);
```

Just in the case of `RegisterService`, you have to explicitly opt into the resolver scoping since we default here to the request scope. But again, it's now one line of code in the GraphQL configuration, and you can use it everywhere without any clutter, as the resolver compiler will generate the code to keep the state.

```csharp
public static async Task<IReadOnlyList<Asset>> GetAssets(AssetRepository repository) => await repository.GetAssetsAsync();
```

# Authorization

Using the built-in authorization directives in Hot Chocolate was a pain. They only worked on fields and were executed for each field they were annotated to. So, basically, like with MVC, and this does not really fit into our graph world.

<Video videoId="0nRoP1_u4SE" />

Let me give you an example, given then the following schema:

```graphql
type Query {
  me: User
  userById(id: ID!): User
}

type User {
  name: String!
  friends: [User!]
}
```

To secure our user object, we would need to annotate three fields.

```graphql
type Query {
  me: User @authorize
  userById(id: ID!): User @authorize
}

type User {
  name: String!
  friends: [User!] @authorize
}
```

But if we now work on our schema and introduce new ways to get a user, we will need to continue ensuring it does not leak. This is tedious, and if we throw in unions and interfaces becomes very hard to manage.

This is where our new authorization approach comes in. You can still annotate fields, but annotating object types will ensure that all fields they are retrievable through are secured with the specified authorization rules.
This change alone makes it much easier to ensure your data is secure.

```graphql
type Query {
  me: User #secured because user is authorized
  userById(id: ID!): User #secured because user is authorized
}

type User @authorize {
  name: String!
  friends: [User!] #secured because user is authorized
}
```

But we also wanted to improve the performance of authorization checks and move them, when possible, out of the execution phase. In Hot Chocolate 13, by default, authorization checks are done before the execution by analyzing the query document. If the document has authorization directives that cannot be fulfilled, it will not even execute.

But, sometimes, we need our authorization logic to run in the resolver, either to get the data and authorize by using the actual data it protects or to use the context in the resolver to authorize. This can be easily done by specifying when an `@authorize` directive shall be applied.

```graphql
type Query {
  me: User #secured because user is authorized
  userById(id: ID!): User #secured because user is authorized
}

type User @authorize @authorize(policy: "READ_USER", apply: AFTER_RESOLVER) {
  name: String!
  friends: [User!] #secured because user is authorized
}
```

| Phase           | Description                                                                                                                                                                                       |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| VALIDATION      | The authorization directives are collected and applied in a batch during the validation phase of the document.                                                                                    |
| BEFORE_RESOLVER | The authorization directives are merged into the resolver pipeline and executed before the resolver. The authorize policies have access to the `IMiddlewareContext` but not to the resolved data. |
| AFTER_RESOLVER  | The authorization directives are merged into the resolver pipeline and executed after the resolver. The authorize policies have access to the `IMiddlewareContext` and the resolved data.         |

## Open Policy Agent

With Hot Chocolate 13, we have abstracted our authorization API and can now support multiple authorization solutions. You can even create your own if you want to. All you have to do is to implement the `IAuthorizationHandler` interface.

```csharp
public interface IAuthorizationHandler
{
    ValueTask<AuthorizeResult> AuthorizeAsync(
        IMiddlewareContext context,
        AuthorizeDirective directive,
        CancellationToken cancellationToken = default);

    ValueTask<AuthorizeResult> AuthorizeAsync(
        AuthorizationContext context,
        IReadOnlyList<AuthorizeDirective> directives,
        CancellationToken cancellationToken = default);
}
```

See [IAuthorizationHandler.cs](https://github.com/ChilliCream/graphql-platform/blob/main/src/HotChocolate/Core/src/Authorization/IAuthorizationHandler.cs) for more details.

Out of the box, we support Microsoft's authorization policies that come with ASP.NET Core and OPA (Open Policy Agent). OPA is getting increasingly popular and can be applied to things from Kubernetes to your database, and it is now just one package away from your favorite GraphQL server.

```bash
dotnet install HotChocolate.AspNetCore.Authorization.Opa
```

If you want to learn more about Open Policy agent, you can find more information [here](https://www.openpolicyagent.org/).

# Subscriptions

Subscription is another area where we put a lot of effort into. With Hot Chocolate 12, we had support for Redis as a backing pub-sub, and if you ran a single instance of your service, you could have used our in-memory implementation.

Now with Hot Chocolate 13, we have added support for NATS by using the [AlterNATS C# library](https://github.com/Cysharp/AlterNats).
We also added support for RabbitMQ, a popular solution many of you asked us to support for subscriptions.

Implementing a new subscription provider now also has become so much easier. If you want to support another system, look at the [NATS implementation](https://github.com/ChilliCream/graphql-platform/tree/main/src/HotChocolate/Core/src/Subscriptions.Nats).

# Data

As with almost every release, we have added more integrations to HotChocolate.Data. With Hot Chocolate 13, we are happy to announce built-in support for RavenDB and Marten.

Here is an example of how easy it is now to integrate RavenDB with Hot Chocolate 13.

1. Install the RavenDB provider to your project.

```bash
dotnet install HotChocolate.Data.Raven
```

2. Register your document store.

```csharp
builder.Services.AddSingleton<IDocumentStore>(
    _ => new DocumentStore { Urls = new[] { "http://localhost:8080" }, Database = "Test" }.Initialize());
```

3. Register, Filtering, Sorting, and Paging providers for RavenDB.

```csharp
builder.Services
    .AddGraphQLServer()
    .AddTypes()
    .AddRavenFiltering()
    .AddRavenProjections()
    .AddRavenSorting()
    .AddRavenPagingProviders();
```

4. Next, we can introduce some resolvers, and we are done.

```csharp
[QueryType]
public class Query
{
    [UsePaging]
    [UseProjection]
    [UseFiltering]
    [UseSorting]
    public IRavenQueryable<Person> GetPersons(IAsyncDocumentSession session)
        => session.Query<Person>();

    [UseFirstOrDefault]
    [UseFiltering]
    public IExecutable<Person> GetPerson(IAsyncDocumentSession session)
        => session.Query<Person>().AsExecutable();
}
```

The Marten integration works very similarly. The main difference here is that you have to install a different package.

```bash
dotnet install HotChocolate.Data.Marten
```

# Azure Functions

With version 12, we introduced the Azure Functions integration but only targeted in-process Azure Functions. Now, with Hot Chocolate 13, we have doubled down on Azure Functions and provided the ability to now run in the isolated process model, along with templates for both.

1. Install the HotChocolate Templates.

   ```bash
   dotnet new install HotChocolate.templates
   ```

2. Chose your template to install or take a spin with both.

   ```bash
   dotnet new graphql-azf --output .\hc-graphql-azf
   dotnet new graphql-azf-ip --output .\hc-graphql-azf-ip
   ```

   Or use Visual Studio.
   ![HotChocolate Azure Functions Project Templates](az-func-templates-vs.png)

# Performance

Performance is, in every release, a core concern that we have. For this release, we have looked at the memory consumption of the execution engine and were able to reduce consumption by 78% while at the same time improving execution performance by 24%.

| Method                                                 |       Mean |    Gen0 |   Gen1 | Allocated |
| ------------------------------------------------------ | ---------: | ------: | -----: | --------: |
| Hot Chocolate 12.17.0 / Introspection Query            |   221.2 us | 13.6719 | 0.2441 |  84.13 KB |
| Hot Chocolate 13.0.2 / Introspection Query             |   167.9 us |  2.9297 | 0.4883 |  18.73 KB |
| Hot Chocolate 12.17.0 / 5 parallel Introspection Query | 1,030.2 us | 68.3594 |      - | 420.63 KB |
| Hot Chocolate 13.0.2 / 5 parallel Introspection Query  |   835.8 us | 14.6484 | 2.9297 |  93.63 KB |

As always, we micro-optimize Hot Chocolate to make more room for your own application logic. What these optimizations mean in your use case might be very different.

# Strawberry Shake

While we did not have a strong focus on Strawberry Shake for this release, we wanted to address some user pain points. The first one was that it was too complex to set up and configure since you needed to fill in configuration and match it with the right packages. With Strawberry Shake 13, we wanted to improve the developer experience and simplify things. We now have three application profiles which translate to three meta-packages, Blazor, Maui, and Server.

| Package                | Description                                                                                                                                                                           |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| StrawberryShake.Blazor | For Blazor projects, use this package in your project, and we pre-configured it to generate Razor components automatically and use a client-side store for reactive web applications. |
| StrawberryShake.Maui   | For Maui projects, use this package in your project, and we pre-configured it to generate and use a client-side store for reactive mobile applications.                               |
| StrawberryShake.Server | For consoles or backend-to-backend communication, we have the service profile, which does not have a client store but gives you a strongly typed client.                              |

Here is a basic flow to initialize a project with a Strawberry Shake client.

1. Create your project.

   ```bash
   dotnet new blazorwasm
   ```

2. Add client tooling to manage the GraphQL schema.

   ```bash
   dotnet new tool-manifest
   dotnet tool install StrawberryShake.Tools
   ```

3. Register GraphQL service with your application.

   ```bash
   dotnet add package StrawberryShake.Blazor
   dotnet graphql init https://api-crypto-workshop.chillicream.com/graphql -n CryptoClient
   ```

With these three steps, you are good to go and can start creating clients for your project.

<Video videoId="-oq7YEciouM" />

We also made it simpler to opt-in to features like persisted queries. Configuration options are now neatly integrated into the project file. To export queries on deployment as persisted queries, you add one property, `GraphQLPersistedQueryOutput`, to your project file, and you are done.

```xml
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <GraphQLPersistedQueryOutput Condition="'$(Configuration)' == 'Release'">../output</GraphQLPersistedQueryOutput>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.0" PrivateAssets="all" />
    <PackageReference Include="StrawberryShake.Blazor" Version="13.0.2" />
  </ItemGroup>

</Project>
```

If you need a deep dive into the setup of persisted queries with Strawberry Shake, you can have a look at the following YouTube episode.

<Video videoId="CYpBafzytB0" />

# Banana Cake Pop

With version 13, we are also releasing Banana Cake Pop 4, which packs many new features. You can read all about this [here](https://chillicream.com/blog/2023/02/07/new-in-banana-cake-pop-4).

# Outlook

There are many more features and fixes in Hot Chocolate 13; too many to go into each of them. Instead, let me give you a couple of numbers around this release. We had 81 contributors, including the core team working on Hot Chocolate 13, and more than 400 PRs went into this release. Not all of them were code; some were bits and pieces of documentation, unit tests, code fixes, or even complete features. The Marten database provider, for instance, was contributed to us by a single member of the community. When I saw this, I remembered the time it was just me. I remember when my brother Rafi and I started the slack channel, and there was this single other person in there asking me questions about Hot Chocolate. Now we are over 4400 on slack.chillicream.com.

Since we were so many people working on this release, I do not want to mention one or two specific names here. It was all of us together who pushed this forward. You can have a look at the GitHub release for all the people who got their commits into main.

[Release Version 13.0.0](https://github.com/ChilliCream/graphql-platform/releases/tag/13.0.0)

The team will focus on tooling and Hot Chocolate Fusion for the next couple of months. We want to make distributed graphs much simpler and help you with great tooling to build and manage graphs at a massive scale. Further down the road, we will focus on AOT without compromise to enable much faster startup times. Also on our list is an overhaul of HotChocolate.Data, we want to make aggregations easier and also simplify creating custom providers. Let's take the next step and get even more people into our community.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[New in Banana Cake Pop 4]]></title>
        <id>https://chillicream.com/blog/2023/02/07/new-in-banana-cake-pop-4</id>
        <link href="https://chillicream.com/blog/2023/02/07/new-in-banana-cake-pop-4"/>
        <updated>2023-02-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[New document on paste cURL or fetch, schema reload enhancements, new ways of closing tabs, menu enhancements/standardization, and UI polishing.]]></summary>
        <content type="html"><![CDATA[
In version 4, we mainly focused on polishing and fixing UI glitches to improve the overall user experience, but that doesn't mean there isn't any new feature. To download **Banana Cake Pop 4**, go to [bananacakepop.com](https://bananacakepop.com). Let me walk you through the most important things we did in Version 4.

## Paste cURL and Fetch

Almost any IDE or Tool nowadays allows copying HTTP requests as cURL or fetch. So why not make use of it? Yeah, that's what we thought too. With version 4, we support pasting `cURL` and `fetch` GraphQL requests into **Banana Cake Pop**.

When pasting such a GraphQL request, a new document will be created with all its HTTP headers, GraphQL variables, GraphQL operation, and the GraphQL endpoint.

This is very helpful in various scenarios, especially when working with the Chrome Developer Tools to identify GraphQL request issues. Just go to the Network tab, right-click on any HTTP request, and then _copy as cURL_. As long as the copied HTTP request is a GraphQL request, **Banana Cake Pop** will create a new document on paste.

There are two ways of creating a new document for a copied `cURL` or `fetch` GraphQL request. First, use the shortcut. `CMD + OPT + V` on macOS and `CTRL + ALT + V` on windows. Second, click the three dots icon next to the save button for tabs, and then click _New document from clipboard_. Ta-da, that's it!

## Schema Reload

Sometimes, reloading a schema takes just a couple of milliseconds, which makes it rather impossible to see the loading indicator spinning. In general, feedback is critical when clicking a button, so we know whether we clicked it. The same goes for the schema reload button. Without knowing whether we clicked it, we’ll click it again and again. In the end, we come to the conclusion that the schema reload does not work. In fact, this isn't true, but how should we know?

Of course, we solved this issue by adding a decent pulse effect to the schema reload button, which keeps going for a couple of seconds.

Additionally, we merged the schema reload button with the schema fetch status to keep things clear and compact.

Furthermore, we improved the schema fetch status, including its tooltip in the status bar, which makes things more explicit.

## Close Multiple Document Tabs

Finally, after quite some time, we've added a bunch of ways to close multiple document tabs simultaneously. Right-click on a document tab and choose between _close others_, _close to the right_, and _close all_. Enjoy!

## Menu Enhancements

We've standardized and enhanced the menu component. We've fixed positioning issues and glitches. Also, we introduce navigation by key (arrow up and down).

## Schema Reference Default Values

Default values for fields in the schema reference column and type view are now available.

## Become An Insider

Hey you, we're looking for you to become an _Insider_ to help us shape the future of **Banana Cake Pop**. We're constantly pushing new _Insider_ builds, sometimes even daily. Get early access to new features, or help us find that last-minute show-stopper issue. Go to [bananacakepop.com](https://bananacakepop.com) to get the latest version of the _Insider_ app or check out the online web version on [insider.bananacakepop.com](https://insider.bananacakepop.com) instead.

## Subscribe

To stay up to date, subscribe to our [ChilliCream YouTube Channel](https://www.youtube.com/c/ChilliCream) to get notified whenever we publish new videos.

I'm Rafael Staib, and as soon as **Banana Cake Pop 5** is released, I'll be right here to tell you what's new in **Banana Cake Pop**!
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[New in Banana Cake Pop 3]]></title>
        <id>https://chillicream.com/blog/2023/01/08/new-in-banana-cake-pop-3</id>
        <link href="https://chillicream.com/blog/2023/01/08/new-in-banana-cake-pop-3"/>
        <updated>2023-01-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Team Workspaces, Express Middleware, Progressive Web Application (PWA) Support, Enterprise Single Sign-On (SSO), and many more features.]]></summary>
        <content type="html"><![CDATA[
Version 3 comes with a couple of neat features, e.g. Team Workspaces, Express Middleware, PWA Support, Enterprise SSO, and more. If you would like to download **Banana Cake Pop 3**, go to [bananacakepop.com](https://bananacakepop.com). Now lets see what’s new in detail.

## Team Workspaces

In **Banana Cake Pop 1**, we've introduced _Personal Workspaces_ for individuals to keep documents safe across devices. _Personal Workspaces_ is a free tier feature and will stay forever free. However, this time we are introducing a new feature called _Team Workspaces_.

_Team Workspaces_, as the name implies, allow teams to work together and share documents. To create _Team Workspaces_ an _Organization_ is required and can be created by anyone. _Organization_ is in preview and becomes a paid feature when the preview phase ends. We'll inform you as soon as the preview phase ends so that you can decide whether to use it.

## Express Middleware

We launched our first NodeJS middleware on [NPM](https://www.npmjs.com/package/@chillicream/bananacakepop-express-middleware).

You can plug **Banana Cake Pop** to your own GraphQL server with just 2 lines of code. Also, you can define per configuration whether to use our _cdn_ hosted version of the app or your own _self_ hosted version, and much more.

Check out our [recipes](https://www.npmjs.com/package/@chillicream/bananacakepop-express-middleware#recipes) for [graphql-http](https://github.com/graphql/graphql-http), [graphql-yoga](https://the-guild.dev/graphql/yoga-server), and [express-graphql](https://github.com/graphql/express-graphql)!

## Progressive Web App (PWA)

With version 3, **Banana Cake Pop** meets the PWA requirements, which allows the web version to be installed as an app. In Chrome on macOS, it looks like this.

![Banana Cake Pop PWA](banana-cake-pop-pwa.png)

## Enterprise Single Sign-On (SSO)

We've added Enterprise Single Sign-On (SSO) to **Banana Cake Pop**, which lets companies bring their own identity service, so that their employees can use their company logins. Please reach out to us if you're interested.

## Enterprise Services

For companies, we’re introducing **Banana Cake Pop** enterprise services, which can be deployed under their own Azure subscription. This gives companies control over their own data. Please reach out to us if you're interested.

## Insider Web Version

We brought the _Insider_ version to the web. Get early access to new features, or even help us find that last-minute show stopper issue.

Check it out here: [insider.bananacakepop.com](https://insider.bananacakepop.com).

## Subscribe

To stay up to date, subscribe to our [ChilliCream YouTube Channel](https://www.youtube.com/c/ChilliCream) to get notified whenever we publish new videos.

I'm Rafael Staib, and as soon as **Banana Cake Pop 4** is released, I'll be right here to tell you what's new in **Banana Cake Pop**!
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[New in Banana Cake Pop 2]]></title>
        <id>https://chillicream.com/blog/2022/10/05/new-in-banana-cake-pop-2</id>
        <link href="https://chillicream.com/blog/2022/10/05/new-in-banana-cake-pop-2"/>
        <updated>2022-10-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Drag & drop support for documents, GraphQL defer/stream support, GraphQL operation extraction, and many further improvements.]]></summary>
        <content type="html"><![CDATA[
## Getting started

Everything you need to get started with **Banana Cake Pop** you'll find on [bananacakepop.com](https://bananacakepop.com)

## Drag & Drop

We've added _Drag & Drop_ support to the document explorer. That makes moving documents, files and folders around so much easier. Moreover, we've added support for dropping files for _File Upload_ from outside. Just drag one or multiple files (e.g. a photo) from your computer and drop it on the document explorer root or a specific folder.

## Defer/Stream Spec

We've updated to the latest Defer/Stream spec draft version, but with backward-compatibility in mind. It still works with previous versions of Hot Chocolate or other servers that implemented the prior spec version.

## Operation Extraction

We've optimized how GraphQL operations are sent over the wire. Before we send an operation, we remove all the superfluous operations and fragments. For instance, if we have two queries in a GraphQL document, query `A` and `B`, we send only the query and its fragments we execute. Such a document could look like the following.

```graphql
query A {
  me {
    ...UserFragment
  }
}

query B {
  me {
    ...UserFragment
    friends {
      ...FriendFragment
    }
  }
}

fragment UserFragment on User {
  name
  image
}

fragment FriendFragment on User {
  ...User
  age
}
```

If we execute query `A`, for example, the request would look like the following.

```graphql
query A {
  me {
    ...UserFragment
  }
}

fragment UserFragment on User {
  name
  image
}
```

With this technique, we didn't only reduce the request overhead but were also able to send query `A` even though query `B` is not valid.

## Horizontal Scrolling for Tabs

We've added horizontal scrolling on tabs for mice with a scroll wheel. Instead of scrolling up/down, we switched to scrolling left/right. Simply hover over tabs that contain partly visible tabs and use the scroll wheel of the mouse to move hidden tabs into the visible area.

## Insider Version

We start now with insider versions for the Electron app, which will run side-by-side with the released app version. Follow this link [bananacakepop.com](https://bananacakepop.com) to download the first insider build.

## Further Improvements

A few more, worth mentioning, improvements are listed below.

1. Increased efficiency of workspace synchronization
1. Reduced Electron app size
1. Removed app leave warning prompt
1. Increased editor performance

## Subscribe

To stay up to date, subscribe to our [ChilliCream YouTube Channel](https://www.youtube.com/c/ChilliCream) to get notified whenever we publish new videos.

I'm Rafael Staib, and as soon as **Banana Cake Pop 3** is released, I'll be right here to tell you what's new in **Banana Cake Pop**!
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[New in Banana Cake Pop 1]]></title>
        <id>https://chillicream.com/blog/2022/09/01/new-in-banana-cake-pop-1</id>
        <link href="https://chillicream.com/blog/2022/09/01/new-in-banana-cake-pop-1"/>
        <updated>2022-09-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Subscription protocol auto-detection, Workspace auto synchronization, a Status Bar, and many further improvements.]]></summary>
        <content type="html"><![CDATA[
## Getting started

Everything you need to get started with **Banana Cake Pop** you'll find on [bananacakepop.com](https://bananacakepop.com)

## Subscription protocol auto-detection

Auto-detection can save you from a headache when it comes to the following questions:

- _Which subscription protocol is supported by server XYZ?_
- _Which subscription protocol prefers server XYZ?_

The new auto-detection is enabled by default. If you prefer a particular subscription protocol, you can change it in the **Connection Settings** dialog.

![Subscription protocol](subscription-protocol-auto-detection-1.png)

**Banana Cake Pop** supports the following subscription protocols.

![Supported subscription protocols](subscription-protocol-auto-detection-2.png)

## Workspace auto synchronization

Your local and remote workspace changes will be synchronized every 60 seconds automatically. No need for you to click the synchronize button anymore. The new synchronize button is now located in the status bar and is also an indicator, showing you whether a workspace is synchronizing.

![Workspace auto synchronization](workspace-auto-synchronization-1.png)

## Status bar

The new decent status bar shows you a couple of information. For instance, is my browser connected to a network, or with what account am I signed in?

![Network status and username](status-bar-1.png)

The status bar can also contain context-related information. For instance, is the schema of my current document up to date?

![Schema status](status-bar-2.png)

Furthermore, we introduced a new button in the right corner that shows the current version of **Banana Cake Pop** when clicking it.

![Version info](status-bar-3.png)

## Hidden Tabs

We introduced a new button that appears when a tab is at least partly hidden. This button, when clicked, will show a menu with partly hidden and completely hidden tabs.

![Version info](hidden-tabs-1.png)

## Subscribe

To stay up to date, subscribe to our [ChilliCream YouTube Channel](https://www.youtube.com/c/ChilliCream) to get notified whenever we publish new videos.

I'm Rafael Staib, and as soon as **Banana Cake Pop 2** is released, I'll be right here to tell you what's new in **Banana Cake Pop**!
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Pushing ahead with Hot Chocolate 12.5]]></title>
        <id>https://chillicream.com/blog/2022/01/13/hot-chocolate-12-5</id>
        <link href="https://chillicream.com/blog/2022/01/13/hot-chocolate-12-5"/>
        <updated>2022-01-13T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we have released Hot Chocolate 12.5, and this release is packed with new features. We put a focus on adding some early spec proposals into this release. We also have completely overhauled our GraphQL IDE Banana Cake Pop to include feedback from our community. Lastly, we picked up an issue created by Simon to support OpenTelemetry.

# Banana Cake Pop

Let us start with the most visible change to Hot Chocolate. With Hot Chocolate 12.5, we have integrated Banana Cake Pop iteration 22, which introduces themes support. One of the top requests for BCP by users was a Dark mode. With the new version, you can now switch between our light and our dark theme. We will add more themes with one of the subsequent iterations.

![Banana Cake Pop Themes](bcp1.png)

We put another focus on discoverability. Many people getting into BCP had difficulty finding the schema explorer or other details regarding their operation document. With the new version, the IDE is much more organized and exposes clearly areas you can dig into.

![Banana Cake Pop Tabs](bcp2.png)

The new Banana Cake Pop version is now available online at <https://eat.bananacakepop.com>, as an application that you can download at <https://bananacakepop.com> or as a middleware in the new Hot Chocolate 12.5.

# Open Telemetry

Hot Chocolate for a long time provides instrumentation events that can be used to add your logging solution. By doing this, we did not bind Hot Chocolate to a specific logging/tracing solution or a specific use-case.

But it also meant that almost everyone had to come up with their own solution to instrument Hot Chocolate. With Hot Chocolate 12.5, we have added the `HotChocolate.Diagnostics` package, which uses the new `ActivitySource` API.

To add OpenTelemetry to your GraphQL server, first add the activity instrumentation to your schema.

```csharp
builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddInstrumentation();
```

Next, we need to configure OpenTelemetry for our service. To quickly inspect our traces, we will use a Jaeger exported.

```csharp
builder.Services.AddOpenTelemetryTracing(
    b =>
    {
        b.AddHttpClientInstrumentation();
        b.AddAspNetCoreInstrumentation();
        b.AddHotChocolateInstrumentation();
        b.AddJaegerExporter();
    });

builder.Logging.AddOpenTelemetry(
    b =>
    {
        b.IncludeFormattedMessage = true;
        b.IncludeScopes = true;
        b.ParseStateValues = true;
    });
```

With all this in place, we can execute requests against our demo server and inspect the traces with the Jaeger UI.

![Banana Cake Pop Themes](jaeger.png)

The complete example can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/OpenTelemetry).

Docs can be found [here](https://chillicream.com/docs/hotchocolate/v12/server/instrumentation/#opentelemetry).

# `OneOf` Input Objects

One of the most asked-for features in GraphQL is input unions. The GraphQL working group has been discussing this feature for a long time, and we have explored multiple roads to achieve this. The most likely candidate has become the _`OneOf` Input Object_ representing a structural union. A structural union means that _`OneOf` Input Object_ is a special kind of input object where each field represents one choice. The _`OneOf` Input Object_ will only allow one field to be set, and the value can not be null. The type system enforces the rules for `OneOf` Input Objects\_.

We support _`OneOf` Input Objects_ in all three schema-building approaches (annotation-based, code-first, and schema-first.

In order to make an input object a _`OneOf` Input Object_ you simply need to annotate it with the `@oneOf` directive.

**schema-first**

```sdl
input PetInput @oneOf {
  cat: CatInput
  dog: DogInput
}
```

**code-first**

```csharp
public class PetInputType : InputObjectType<PetInput>
{
    protected override void Configure(
        IInputObjectTypeDescriptor<PetInput> descriptor)
    {
        descriptor.OneOf();
    }
}

public class PetInput
{
    public Dog? Dog { get; set; }

    public Cat? Cat { get; set; }
}
```

**annotation-based**

```csharp
[OneOf]
public class PetInput
{
    public Dog? Dog { get; set; }

    public Cat? Cat { get; set; }
}
```

Next, you need to enable the RFC feature on the schema.

```csharp
builder.Services
    .AddGraphQLServer()
    ...
    .ModifyOptions(o => o.EnableOneOf = true);
```

The complete example can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/OneOf).

Docs can be found [here](https://chillicream.com/docs/hotchocolate/v12/defining-a-schema/input-object-types/#oneof-input-objects).

The current GraphQL spec RFC can be found [here](https://github.com/graphql/graphql-spec/pull/825).

# Client-Controlled Nullability

Client-Controlled nullability gives more power to the consumer of a GraphQL API. It allows us to specify error boundaries in GraphQL by defining if a field shall be nullable or required in our GraphQL request. To give this power to the user, the RFC introduces new query syntax to let the user override type nullability on fields and specify where error boundaries are in the GraphQL request.

Let us, for instance, say we have a schema like the following:

```graphql
type Query {
  me: User
}

type User {
  name: String!
  bio: String!
  friends: [User!]
}
```

We have a user object with a name, a bio, and friends in our schema. Let's now consider we have a simple query where we fetch the currently signed-in user and that user's friends.

```graphql
{
  me {
    name
    bio
    friends {
      name
      bio
    }
  }
}
```

In our schema, the field `bio` is a non-null field, and whenever this field would become null due to a processing error or invalid data, the GraphQL non-null propagation rule would erase all friends.

```json
{
  "me": {
    "name": "Michael Staib",
    "bio": "Author of Hot Chocolate ...",
    "friends": null
  }
}
```

With client-controlled nullability, the API consumer can now change this behavior by overriding the field type nullability.

```graphql
{
  me {
    name
    bio
    friends {
      name
      bio?
    }
  }
}
```

We can tell the execution engine that we do not mind if this field becomes `null` by adding a question mark.

But we could also approach this differently and say if the field `bio` does not deliver any data, I do not want a partial result where `friends` becomes `null`. I instead want to have no data at all and fail the complete request.

```graphql
{
  me! {
    name
    bio
    friends! {
      name
      bio
    }
  }
}
```

So, in this case, I added the bang operator to the field `me` and the field `friends`. In GraphQL, a non-null violation will bubble up until it reaches a nullable field or until the complete result is deleted. Since we made the root non-null, the complete result, in this case, is deleted. Meaning either I get all the data I demanded or none.

We could also produce null entries in our `friends` list for users that do not provide a value for the field `bio` with the new list nullability modifier `[?]`.

```graphql
{
  me! {
    name
    bio
    friends[?] {
      name
      bio
    }
  }
}
```

At the moment, Banana Cake Pop is not updated for the new syntax yet. We will do that in the coming days. But you can write and execute the new syntax already since BCP will allow you to execute even with syntax errors. We hope to introduce an updated language server with the next iteration.

The current GraphQL spec RFC can be found [here](https://github.com/graphql/graphql-spec/pull/895).

# Conclusion

We have implemented a ton of other smaller additions and bug fixes. Hot Chocolate 12.5 pushes further ahead and allows you to opt into the newest GraphQL spec proposals and drafts. At the GraphQL working group, we are currently discussing great new additions to the GraphQL spec like fragment modularity and object identity. Together, stream/defer, OneOf, fragment modularity, object identity, and client-controlled nullability could make GraphQL so much better and help us solve fundamental problems in interacting with our data graphs. We have invested in these new features early and are iterating on these as the spec text matures.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[A Holly Jolly Christmas with Hot Chocolate 12.4]]></title>
        <id>https://chillicream.com/blog/2021/12/14/hot-chocolate-12-4</id>
        <link href="https://chillicream.com/blog/2021/12/14/hot-chocolate-12-4"/>
        <updated>2021-12-14T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Christmas is almost here! With the beginning of the festivities, more and more people are taking off from work. But at ChilliCream, we are still all hands down working on many new things.

Today, we are releasing Hot Chocolate 12.4, which brings a lot of great new productivity features to the table. Let me give you a little tour of what's new.

# Mutation Conventions

The main feature we worked on for this release was definitely the mutation conventions. The new convention will help minimize the effort to create well-defined mutations.

**What do I mean with well-defined mutations?**

In GraphQL, we have developed specific patterns around mutations. One foundational pattern is about the structure of mutations. It was initially developed by Facebook and belonged to the [Relay server specification](https://relay.dev/docs/v9.1.0/graphql-server-specification/#mutations).

> By convention, mutations are named as verbs, their inputs are the name with "Input" appended at the end, and they return an object that is the name with "Payload" appended.

```sdl
type Mutation {
  renameUser(input: RenameUserInput!): RenameUserPayload!
}

input RenameUserInput {
  userId: ID!
  username: String!
}

type RenameUserPayload {
  user: User
}
```

Essentially, each mutation consists of three parts:

- The mutation resolver.
- The mutation payload.
- The mutation input.

Each mutation has its own mutation payload and its own mutation input. This is done to keep a mutation evolvable over time. If we instead share inputs or payloads with other mutations, we would quickly get stuck with our mutation design since changing one mutation will often break the other mutation. By giving each mutation its own set of input and payload, we can evolve each mutation without breaking the other.

There are other reasons for this particular design. We, for instance, have a single input so that clients do not need to deconstruct their objects, and mutations do not end up with hundreds of arguments. The mutation clearly exposes what is required to execute it by having a single input. Further, it makes it very simple for client applications to craft the input object and pass it as a variable.

A separate payload object allows us to expose all affected objects by the mutation. So that the client can fetch all the affected data, it is interested in. Moreover, the payload allows us to expose user errors through just another field to the client on our payload.

```sdl
type Mutation {
  renameUser(input: RenameUserInput!): RenameUserPayload!
}

input RenameUserInput {
  userId: ID!
  username: String!
}

type RenameUserPayload {
  user: User
  errors: [RenameUserError!]
}

union RenameUserError = UserNameTakenError | InvalidUserNameError
```

We can see that having this particular design of mutation is very beneficial for our schema over time and for the usage by our consumers.

What was not so nice is that we needed so many types in C# to create a simple mutation.

```csharp
public class Mutation
{
    public async Task<RenameUserPayload> RenameUserAsync(
        RenameUserInput input,
        IUserService userService,
        CancellationToken cancellationToken)
    {
          try
          {
              User updateUser = await userService.RenameUserAsync(input.UserId, input.Username, cancellationToken);
              return new RenameUserPayload(updatedUser);
          }
          catch (UserNameTakenException ex)
          {
              return new RenameUserPayload(new UserNameTakenError(ex));
          }
          catch (ArgumentException ex)
          {
              return new RenameUserPayload(new InvalidUserNameError(ex));
          }
    }
}

public record RenameUserInput([property: ID(nameof(User)))] Guid UserId, string Username);

public class RenameUserPayload
{
   // code omitted for brevity
}

public class UserNameTakenError
{
   // code omitted for brevity
}

public class InvalidUserNameError
{
   // code omitted for brevity
}
```

That is where the core team tinkered for almost a year until the end to make it very simple to expose mutations. We wanted to eliminate repetitive C# code and let the user focus on the mutation itself. Mutation conventions let you opt-in very quickly by essentially just flipping the switch.

```csharp
services
    .AddGraphQLServer()
    .AddMutationConventions() // < -- this line enable the new conventions.
    ...
```

Once activated, the convention will transform mutations that do not yet apply to the mutation pattern. This works with code-first, schema-first, and annotation-based. Meaning, no matter what approach you take to build your schema, these new conventions will make your life easier.

**Annotation-Base**:

```csharp
public class Mutation
{
    public Task<User> RenameUserAsync(
        [ID(nameof(User))] Guid userId,
        string username,
        IUserService userService,
        CancellationToken cancellationToken)
        => userService.RenameUserAsync(userId, username, cancellationToken);
}
```

**Code-First**:

```csharp
public class MutationType : ObjectType<Mutation>
{
    protected override void Configure(IObjectTypeDescriptor<Mutation> descriptor)
    {
        descriptor
            .Field(f => f.RenameUserAsync(default, default, default, default))
            .Argument("userId", a => a.ID(nameof(User)));
    }
}

public class Mutation
{
    public Task<User> RenameUserAsync(
        Guid userId,
        string username,
        IUserService userService,
        CancellationToken cancellationToken)
        => userService.RenameUserAsync(userId, username, cancellationToken);
}
```

OR without runtime-type:

```csharp
public class MutationType : ObjectType
{
    protected override void Configure(IObjectTypeDescriptor descriptor)
    {
        descriptor
            .Field("renameUser")
            .Argument("userId", a => a.ID(nameof(User)))
            .Argument("username", a => a.Type<NonNullType<StringType>>())
            .Resolve(async ctx =>
            {
                var userService = ctx.Service<IUserService>();
                var userId = ctx.ArgumentValue<Guid>("userId");
                var username = ctx.ArgumentValue<string>("username");

                return userService.RenameUserAsync(userId, username, cancellationToken);
            });
    }
}
```

**Schema-First**:

```sdl
type Mutation {
  renameUser(userId: ID!, username: String!): User
}
```

```csharp
services
    .AddGraphQLServer()
    .AddMutationConventions()
    .AddDocumentFromString(@"
        type Mutation {
          renameUser(userId: ID!, username: String!): User
        }")
    .BindRuntimeType<Mutation>();

public class Mutation
{
    public Task<User> RenameUserAsync(
        Guid userId,
        string username,
        IUserService userService,
        CancellationToken cancellationToken)
        => userService.RenameUserAsync(userId, username, cancellationToken);
}
```

The conventions also let you onboard more slowly by opting-in on a per mutation basis.

```csharp
services
    .AddGraphQLServer()
    .AddMutationConventions(
        new MutationConventionOptions
        {
            ApplyToAllMutations = false
        })
    ...

public class Mutation
{
    [UseMutationConvention]
    public Task<User> RenameUserAsync(
        [ID(nameof(User))] Guid userId,
        string username,
        IUserService userService,
        CancellationToken cancellationToken)
        => userService.RenameUserAsync(userId, username, cancellationToken);
}
```

Further, you can customize the naming patterns for creating the payload/input/error type names.

```csharp
services
    .AddGraphQL()
    .AddMutationConventions(
        new MutationConventionOptions
        {
            InputArgumentName = "input",
            InputTypeNamePattern = "{MutationName}Input",
            PayloadTypeNamePattern = "{MutationName}Payload",
            PayloadErrorTypeNamePattern = "{MutationName}Error",
            PayloadErrorsFieldName = "errors",
            ApplyToAllMutations = true
        })
```

> Note: You can also partially opt-out of the convention by for instance crafting your own input type but letting the convention produce the payload.

## Errors

The second part of this new mutation convention involves user errors. We did a lot of work investigating how we should enable errors or even what pattern we should follow.

Marc-Andre Giroux wrote a great [blog post](https://xuorig.medium.com/a-guide-to-graphql-errors-bb9ba9f15f85) on the various error patterns in GraphQL and analyzed their pro and cons regarding evolvability and usability.

The error stage 6a has all the pros we want:

- Expressive and Discoverable Schema
- Support for Multiple Errors
- Easier Mutation Evolution

But at the same time, it wasn't easy to implement since it came with many moving parts. This meant that we had to write repetitive code again to fulfill this error pattern.

```sdl
type Mutation {
  renameUser(input: RenameUserInput!): RenameUserPayload!
}

input RenameUserInput {
  userId: ID!
  username: String!
}

type RenameUserPayload {
  user: User
  errors: [RenameUserError!]
}

union RenameUserError = UserNameTakenError | InvalidUserNameError

type UserNameTakenError implements Error {
  message: String!
  code: string!
  username: string!
  suggestedAlternatives: [String!]
}

type InvalidUserNameError implements Error {
  message: String!
  code: string!
  username: string!
  invalidCharacters: [String!]!
}

interface Error {
  message: String!
  code: string!
}
```

We looked at how people traditionally solve their errors, and in most cases, people still write custom exceptions. We now allow for annotating these custom exceptions on the resolver and exposing them as user errors on the mutation payload.

```csharp
public class Mutation
{
    [Error<UserNameTakenException>]
    [Error<ArgumentException>]
    public Task<User> RenameUserAsync(
        [ID(nameof(User))] Guid userId,
        string username,
        IUserService userService,
        CancellationToken cancellationToken)
        => userService.RenameUserAsync(userId, username, cancellationToken);
}
```

The above code will translate to the following schema:

```sdl
type Mutation {
  renameUser(input: RenameUserInput!): RenameUserPayload!
}

input RenameUserInput {
  userId: ID!
  username: String!
}

type RenameUserPayload {
  user: User
  errors: [RenameUserError!]
}

union RenameUserError = UserNameTakenError | ArgumentError

type UserNameTakenError implements Error {
  message: String!
  username: string!
  suggestedAlternatives: [String!]
}

type ArgumentError implements Error {
  message: String!
  paramName: string!
}

interface Error {
  message: String!
}
```

Again, we know that we do not always want to expose our errors one to one with exceptions or we even want to have more robust control of which information is exposed to the outside world. This is where we allow for error objects to substitute exceptions that are thrown.

```csharp
public class Mutation
{
    [Error<UserNameTakenException>]
    [Error<InvalidUserNameError>]
    public Task<User> RenameUserAsync(
        [ID(nameof(User))] Guid userId,
        string username,
        IUserService userService,
        CancellationToken cancellationToken)
        => userService.RenameUserAsync(userId, username, cancellationToken);
}

public class InvalidUserNameError
{
    public InvalidUserNameError(ArgumentException ex)
    {
        Message = ex.Message;
    }

    public string Message { get; }

    public string[] InvalidCharacters => new [] { "=", "^" }:
}
```

The error object shape defines the error type shape on our schema and ensures that even if the exception is refactored to have more or less information, we do not accidentally expose information that we do not want to expose.

You can read more about all of this in our [documentation](https://chillicream.com/docs/hotchocolate/v12/defining-a-schema/mutations/#conventions). The documentation also outlines more variants to create user errors.

One last aspect before we move on to the next topic. We also thought about result objects where a service we use does not use exceptions but already has error objects. Or F# code where we might have a union representing a result and its errors. We do not yet support these kinds of things but will further iterate on the current conventions to include these approaches towards results and errors in the future.

# Dependency Injection Improvements

Users that build large schemas with Hot Chocolate from time to time have asked us to help them reduce the DI code they have to write for resolvers.

```csharp
public async Task<ScheduleSessionPayload> ScheduleSessionAsync(
    ScheduleSessionInput input,
    [Service] ISessionService sessionService,
    [Service] ITopicEventSender eventSender)
{
    // code omitted for brevity
}
```

The above resolver gets injected a service we want to interact with within our resolver. We use this service in many resolvers throughout our solution, and having to repeatedly to annotate our service with the attributes `[FromService]`, `[Service]` or `[ScopedService]` bloats our code.

With our new version, you can now register this service as a well-known service on the schema. Wherever the resolver compiler finds this service type, it will generate a dependency injection code resolving it from the DI.

**Registration:**

```csharp
services
    .AddGraphQLServer()
    .RegisterService<ISessionService>()
    .RegisterService<ITopicEventReceiver>()
    .RegisterService<ITopicEventSender>()
    ...
```

**Resolver:**

```csharp
public async Task<ScheduleSessionPayload> ScheduleSessionAsync(
    ScheduleSessionInput input,
    ISessionService sessionService,
    ITopicEventSender eventSender)
{
    // code omitted for brevity
}
```

But this is not where this feature stops. We also wanted to simplify handling services of different kinds. For instance, some services are not thread-safe and can only be accessed by a single resolver in a specific request at once. With the new well-known services feature, we can tell the execution engine about this fact and produce a query plan that will accommodate this.

```csharp
services
    .AddGraphQLServer()
    .RegisterService<ISessionService>(ServiceKind.Synchronized)
    .RegisterService<ITopicEventReceiver>()
    .RegisterService<ITopicEventSender>()
    ...
```

We also might be dealing with pooled services or objects. These can now also be registered as a service.

```csharp
services
    .AddGraphQLServer()
    .RegisterService<ISessionService>(ServiceKind.Synchronized)
    .RegisterService<HeavyObject>(ServiceKind.Pooled)
    .RegisterService<ITopicEventReceiver>()
    .RegisterService<ITopicEventSender>()
    ...
```

We will, in this case, retrieve an `ObjectPool<TService>` from the DI, rent out the specified service or object from the pool and return it when the resolver is finished. The code you had to write to handle such complex cases is now reduced to a single registration line.

Last but not least, we also support now resolver level scoping, meaning you can register a service that shall be scoped to a resolver. In this case, we will create for these services in your resolver an `IServiceScope` from which we retrieve resolver-level services. After the resolver is completed, the scope is disposed of and with it the scoped services you have used.

We also wanted to clean up the attributes around services and allow for the same capabilities through the service attribute. That is why we introduced the `ServiceKind` also on the attribute.

```csharp
public async Task<ScheduleSessionPayload> ScheduleSessionAsync(
    ScheduleSessionInput input,
    [Service(ServiceKind.Synchronized)] ISessionService sessionService,
    [Service] ITopicEventSender eventSender)
{
    // code omitted for brevity
}
```

Whether you are using well-known services registered at the schema level or services declared with the attribute, you have the same capabilities and a new streamlined experience.

# Entity Framework Improvements

When redoing the services, we also looked at EF Core. The DBContext is a unique service that needs to be treated differently depending on how you registered it with your DI.

By default, if you just use `services.AddDbContext<MyDbContext>()`, your context will be registered in the DI as a scoped service. This means a single DBContext will be used for all resolvers of the request. Since a DBContext is not thread-safe, we need to ensure that only one resolver at a time can access this scoped service.

Like with the well-known services feature, we can now register a well-known DBContext on the schema level and tell the execution engine how this service shall be used. Since a scoped DBContext is the most common thing, we have decided to use it as the default whenever you register a well-known DBContext.

```csharp
builder.Services
    .AddDbContext<BookContext>(
        (s, o) => o
            .UseSqlite("Data Source=books.db")
            .UseLoggerFactory(s.GetRequiredService<ILoggerFactory>()))
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .RegisterDbContext<BookContext>();
```

The DBContext can be registered as a well-known DBContext with three different behaviors.

The first and the default is `DbContextKind.Synchronized` which will ensure that all resolvers that access such a DBContext synchronize their access through the query execution plan.

You also can use a pooled DBContext with the `DbContextKind.Pooled`. In this case, we will wrap a middleware around your resolver that will retrieve the DBContext through the DBContextFactory, inject the DBContext in your resolver and dispose of it once the resolver pipeline is finished executing.

```csharp
builder.Services
    .AddPooledDbContextFactory<BookContext>(
        (s, o) => o
            .UseSqlite("Data Source=books.db")
            .UseLoggerFactory(s.GetRequiredService<ILoggerFactory>()))
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .RegisterDbContext<BookContext>(kind: DbContextKind.Pooled);
```

The last way to use a well-known DBContext is as a resolver-level DBContext. In this case, we will treat it as a resolver-level service that is retrieved from a resolver service scope. With this, you essentially get a new DBContext per resolver without configuring anything special.

With the well-known DBContext, you now can switch the behavior of how resolvers interact with your DBContext with one line of code. With this, you essentially can start easy, and as traffic starts to grow and you get more pressure on your API, you can switch to DBContext pooling.

In combination with well-known services, you can also much easier handle DI behavior when your DBContext is walled off behind your business layer since we can scope and control your service objects.

We will further refine these features to integrate more use-cases and reduce the complexity even further.

# DateOnly and TimeOnly

One small note, we now support `DateOnly` and `TimeOnly`. They will now work with the current set of scalars and also with HotChocolate.Data.

We are still working on adding support NodaTime to HotChocolate.Data so that you can write filters that use NodaTime object beneath.

# Outlook

Work on 12.5 already is underway, and there are four notable things we are working on for this next iteration:

- Client Controlled Nullability (<https://github.com/graphql/graphql-spec/pull/895>)
- `OneOf` inputs and `OneOf` fields (<https://github.com/graphql/graphql-spec/pull/825>)
- OpenTelemetry and Elastic APM support
- Banana Cake Pop Themes

You can have a look at the milestone here:
<https://github.com/ChilliCream/graphql-platform/milestone/72>

We will also be working on the new stitching engine over Christmas and hope to have the first previews ready at the end of January.

Things are moving together and becoming more and more connected.

We hope you all enjoy this new version of Hot Chocolate and have some great holidays.

Join us on <https://slack.chillicream.com> and chime into the discussion around GraphQL on .NET!

> If you like our project help us by [starring it on GitHub](https://github.com/ChilliCream/graphql-platform/stargazers). A GitHub star is the easiest contribution you can give to an OSS project. Star the open source projects you use or love!
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Banana Cake Pop is in da Cloud!]]></title>
        <id>https://chillicream.com/blog/2021/11/22/banana-cake-pop-cloud</id>
        <link href="https://chillicream.com/blog/2021/11/22/banana-cake-pop-cloud"/>
        <updated>2021-11-22T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we’re introducing a new version of Banana Cake Pop packed with cool features like Personal Workspace, Authorization Flows, the ChilliCream Tunnel, and many more. Moreover, we’re excited to announce that we brought Banana Cake Pop into the cloud. So you don’t even need to install the app anymore if you’re, for example, on a device that does not belong to you.

# Personal Workspace

Synchronize your GraphQL documents with any of your devices, whether you’re using the cloud, app, or the HotChocolate middleware version of Banana Cake Pop. Your GraphQL documents stay with you where ever you are :-) And the best part, Personal Workspace is free! You just need to sign in.

![Personal Workspace](personal-workspace.png)

# Authorization Flows

We brought three commonly used authorization flows to Banana Cake Pop:

- OAuth 2
- Bearer
- Basic

More authorization flows are expected to be added soon.

![Personal Workspace](authorization-flows.png)

# ChilliCream Tunnel

When working with various GraphQL APIs, we’ve often been confronted with CORS issues. Those issues belong now to the past thanks to the latest and greatest Banana Cake Pop. With the brand new ChilliCream Tunnel, you can bypass CORS issues by enabling it on a per-document basis. The ChilliCream Tunnel will then relay all your graphql traffic through a proxy.

![Personal Workspace](chillicream-tunnel.png)

# No Login Required

Would you like to test a GraphQL operation or explore a GraphQL schema? That’s cool! You can do that without the need to create an account. Just go to [https://eat.bananacakepop.com](https://eat.bananacakepop.com) and do whatever you need to do. But if you sign up, we offer you even more features like document synchronization between your devices or the ChilliCream Tunnel, which helps you bypass CORS issues. You decide how far you wanna go ;-)

![Personal Workspace](no-login-required.png)

# Apple Silicon

As of preview 18, we’re introducing Apple Silicon (M1) support for Banana Cake Pop. You can download the newest version [here](https://bananacakepop.com).

# Next Steps

In the upcoming versions, we’re mainly focusing on reducing paper cuts to improve the overall experience in Banana Cake Pop. Furthermore, we will introduce more features to Banana Cake Pop. To name just a few:

- Operation Builder
- Team Workspaces
- Environments
- Different views for the Schema Reference
- Support for the new graphql-ws protocol
- GraphQL File Upload

# Let us know what you think

Help us make Banana Cake Pop the best GraphQL IDE ever by sharing your thought with us. The best way of sharing your valuable feedback with us is on [Slack](http://slack.chillicream.com/), where we have a dedicated channel for Banana Cake Pop: **#banana-cake-pop**. We’re always happy to have a chat with you.
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Say hello to Hot Chocolate 12!]]></title>
        <id>https://chillicream.com/blog/2021/09/27/hot-chocolate-12</id>
        <link href="https://chillicream.com/blog/2021/09/27/hot-chocolate-12"/>
        <updated>2021-09-27T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we are releasing Hot Chocolate 12, which brings many new features and refinements to the platform. The main focus for this release was to put a new execution engine in place that will allow us to build a more efficient schema federation with the next version. We are constantly iterating on the execution engine to make it more efficient and allow for new use-cases. Many implementations for GraphQL federation/stitching build a specific execution engine to handle federated schemas. With Hot Chocolate, we always wanted to keep this integrated and allow for stitching part of a graph while at the same time extending types in that very same schema. This also allows us to use improvements made for schema federation in other areas like Hot Chocolate Data, which will boost features and reliability with the next release.

# Execution Engine

The execution engine is changing with every release of Hot Chocolate. With version 11, we, for instance, introduced operation compilation, which takes the executed operation out of a document and pre-compiles it so that most of the GraphQL execution algorithm can be skipped in consecutive calls.

```mermaid
sequenceDiagram
    Validation->>Compile Operation: Document! and IsValid
    Compile Operation->>Coerce Variables: IPreparedOperation
    Coerce Variables->>Execute Operation: IVariableCollection

    Execute Operation-->>Coerce Variables: IExecutionResult
    Coerce Variables-->>Compile Operation: IExecutionResult
    Compile Operation-->>Validation: IExecutionResult
```

> Note, that there are actually more components involved in the actual execution pipeline. For brevity I have shortened the pipeline to the significant parts for this post.

With Hot Chocolate 12, we now take this further by introducing a query plan; essentially, the execution engine traverses a compiled operation tree to create a query plan from it. The query plan can take into account how a resolver is executed. For instance, if a resolver uses services that can only be used by a single thread and thus need synchronization.

```mermaid
sequenceDiagram
    Validation->>Compile Operation: Document! and IsValid
    Compile Operation->>Build Query Plan: IPreparedOperation
    Build Query Plan->>Coerce Variables: QueryPlan
    Coerce Variables->>Execute Operation: IVariableCollection

    Execute Operation-->>Coerce Variables: IExecutionResult
    Coerce Variables-->>Build Query Plan: IExecutionResult
    Build Query Plan-->>Compile Operation: IExecutionResult
    Compile Operation-->>Validation: IExecutionResult
```

Moreover, the execution engine can now inspect if it can pull up data fetching logic and inject a completed result into a resolver pipeline and, by doing this, optimize data fetching. Doing this sounds kind of like DataLoader since we are tackling batching with this in some way. But actually, it makes these implications visible to the executor. Query plans allow the executor to inspect these things before running a query, thus improving execution behavior.

Further, the execution engine now differentiates between pure and async resolvers. Pure resolvers are synchronous and only need what is available in their parent resolver context. Such resolvers can now be inlined by the execution, allowing us to skip a lot of logic we usually would need to execute.

## Performance

We had this simple throughput test for Hot Chocolate 11, which essentially executes a simple query to fetch books and authors. Hot Chocolate 11 achieved 19983 requests a second on our test hardware. With the new execution engine, we clock in 33702 requests a second, which are an additional 13719 requests per second with the same hardware on a test that does not even really take advantage of all the new optimizations.

Hot Chocolate 12 executes much faster but also saves on the memory. In many cases, the execution now needs only 1/3 of the memory Hot Chocolate 11 needed.

| Method                                            |      Median |     Gen 0 |    Gen 1 | Gen 2 | Allocated |
| ------------------------------------------------- | ----------: | --------: | -------: | ----: | --------: |
| Introspection 11                                  |    922.4 μs |   26.3672 |   0.9766 |     - |    275 KB |
| Introspection 12                                  |    333.6 μs |    7.8125 |        - |     - |     85 KB |
| Introspection 5 parallel requests 11              |  4,839.8 μs |  132.8125 |   7.8125 |     - |   1377 KB |
| Introspection 5 parallel requests 12              |  1,658.6 μs |   41.0156 |        - |     - |    423 KB |
| Large query with data fetch 11                    | 19,322.2 μs |  312.5000 | 156.2500 |     - |   3245 KB |
| Large query with data fetch 12                    | 15,461.0 μs |  187.5000 |  93.7500 |     - |   1923 KB |
| Large query with data fetch 5 parallel request 11 | 38,035.6 μs | 1571.4286 | 785.7143 |     - |  16395 KB |
| Large query with data fetch 5 parallel request 12 | 26,187.5 μs |  937.5000 | 468.7500 |     - |   9613 KB |

We are also, as always, comparing against GraphQL .NET, and we have to say they gained a lot of performance. Well done! When we looked the last time at GraphQL .NET, they were performing quite poorly. We, for instance, had this benchmark that executed a very small request of three fields which took GraphQL .NET 31 kb of memory to process. We did the same tests again and with GraphQL.Server.Core 5.0.2 they were now just a little bit slower than Hot Chocolate 11.

But Hot Chocolate 12, at the same time, also gained a lot more performance.

| Method                                        |     Median | Allocated |
| --------------------------------------------- | ---------: | --------: |
| Hot Chocolate 11 Three Fields                 |   11.94 μs |      7 KB |
| Hot Chocolate 12 Three Fields                 |    9.94 μs |      3 KB |
| GraphQL .NET 4.3.1 Three Fields               |   46.36 μs |     31 KB |
| GraphQL .NET 5.0.2 Three Fields               |   22.28 μs |      8 KB |
| Hot Chocolate 11 Small Query with Fragments   |   43.32 μs |     14 KB |
| Hot Chocolate 12 Small Query with Fragments   |   21.68 μs |      7 KB |
| GraphQL .NET 4.3.1 Small Query with Fragments |  138.56 μs |    135 KB |
| GraphQL .NET 5.0.2 Small Query with Fragments |   65.83 μs |     19 KB |
| Hot Chocolate 11 Introspection                |  750.51 μs |    392 KB |
| Hot Chocolate 12 Introspection                |  262.51 μs |     67 KB |
| GraphQL .NET 4.3.1 Introspection              | 2277.24 μs |   2267 KB |
| GraphQL .NET 5.0.2 Introspection              |  676.72 μs |    169 KB |

For the introspection, which produces a large result, GraphQL .NET needs 2.5 times more memory than Hot Chocolate 12. Even if we look at the small query benchmark with just three fields, GraphQL .NET needs 2.6 times more memory. The same goes for execution speed. The new execution engine is 2.2 times faster than GraphQL .NET in the test to query three fields while finishing 2.6 times faster when running an introspection query.

But to be honest, we did not use all the nice new query plan features that we have built-in with Hot Chocolate 12 in these tests. That is why we have started on a more comprehensive set of tests that use an actual database and allow Hot Chocolate to use projections or even query plan batching.

From Hot Chocolate 13 on, we will use our new performance test base we are working on. This new test base will show more aspects of usage. We also will start including even more GraphQL frameworks like juniper, async-graphql, or graphql-java.

Let's have a look at the throughput tests which we run to see the GraphQL engine overhead. The benchmark executes a simple book/author GraphQL query against in-memory data. We fire those requests as HTTP Post requests against the GraphQL servers in our test suite. We start with five users for 20 seconds, then ten users for 20 seconds, and up to 30 users for 20 seconds. We do this in a couple of rounds and let each of these benchmarks run on a freshly rebooted system. We are looking at automating this with k6s, and my colleague Jose will help us with that.

| Method                                     | Requests per Sec. |
| ------------------------------------------ | ----------------: |
| Hot Chocolate 12                           |             33702 |
| Hot Chocolate 11                           |             19983 |
| benzene-http (graphyne)                    |             17691 |
| mercurius+graphql-jit                      |             15185 |
| apollo-server-koa+graphql-jit+type-graphql |              4197 |
| express-graphql                            |              3455 |
| apollo-schema+async                        |              3403 |
| go-graphql                                 |              2041 |

With Hot Chocolate 13, our goal is to hit 40000 requests per second on the throughput tests, and we are hopeful that we can achieve this with some refinements in the execution engine. As we advance, we will start investing in other areas like startup performance as well.

# Entity Framework

I talked about many improvements in the execution engine that we will only unlock with Hot Chocolate 13. Still, we also have some practical use for the new execution engine features with Hot Chocolate 12. Specifically for APIs that use Entity Framework. In general, I always recommend letting the execution engine roam free and parallelize as needed. With Entity Framework, this can be achieved with DBContext pooling. But in some cases, this is not what people want or need for their specific use-case.

With Hot Chocolate 12, you can now mark a resolver as serial and, by doing this, tell the execution engine that it needs to synchronize a resolver. This is required when using a single DBContext instance per request so that it is ensured that only one thread accesses a given DBContext at the same time.

You can mark a single resolver as serial or mark all async resolvers as serial by default.

In the annotation-based approach, we need to annotate our resolver with the `SerialAttribute` to ensure that the execution engine is not executing these resolvers in parallel.

```csharp
[Serial]
public async Task<Person> GetPersonByIdAsync([Service] MyDbContext context)
{
    // omitted for brevity
}
```

Moreover, as mentioned, we can mark all async resolvers as serial by default.

```csharp
services
    .AddGraphQLServer()
    .ModifyOptions(o => o.DefaultResolverStrategy = ExecutionStrategy.Serial)
```

In this case, we still can opt out of the serial execution strategy by using the `ParallelAttribute` on our resolvers.

Serial executable resolvers will be put into a sequence shape of the query plan, which guarantees that they are executed one after the other. You can inspect the query plan by providing the `graphql-query-plan` header with a value of `1`.

We will get the following execution plan if we head over to <https://workshop.chillicream.com> and run the following query with the query plan header.

```graphql
{
  a: sessions {
    nodes {
      title
    }
  }

  b: sessions {
    nodes {
      title
    }
  }
}
```

```json
{
  "extensions": {
    "queryPlan": {
      "flow": {
        "type": "Operation",
        "root": {
          "type": "Resolver",
          "strategy": "Parallel",
          "selections": [
            {
              "id": 0,
              "field": "Query.sessions",
              "responseName": "a"
            },
            {
              "id": 1,
              "field": "Query.sessions",
              "responseName": "b"
            }
          ]
        }
      },
      "selections": "{\n  ... on Query {\n    a: sessions @__execute(id: 0, kind: DEFAULT, type: COMPOSITE) {\n      ... on SessionsConnection {\n        nodes @__execute(id: 4, kind: PURE, type: COMPOSITE_LIST) {\n          ... on Session {\n            title @__execute(id: 5, kind: PURE, type: LEAF)\n          }\n        }\n      }\n    }\n    b: sessions @__execute(id: 1, kind: DEFAULT, type: COMPOSITE) {\n      ... on SessionsConnection {\n        nodes @__execute(id: 2, kind: PURE, type: COMPOSITE_LIST) {\n          ... on Session {\n            title @__execute(id: 3, kind: PURE, type: LEAF)\n          }\n        }\n      }\n    }\n  }\n}"
    }
  }
}
```

Adding this header to your request will add a property to the response with the query plan and the internally compiled operation. We can see that the query plan only has two fields in it; these are the async fields that fetch data, all the other fields are folded into their parent threads. We also can see that these two resolvers can be executed in parallel. Depending on how many components are involved, these query plans can be much bigger end expose the dependencies between the data fetching components.

If we did the same for serial resolvers, we would get a sequence shape that would execute resolver tasks one after the other.

BTW, allowing such serial execution flows in Hot Chocolate 12 was one of the most requested features, and the team is quite happy to provide this now to our community.

# Resolver Compiler

One of the things many people love about Hot Chocolate is how we infer the GraphQL schema from your C# types and how you can inject various things into your resolver.

```csharp
public async Task<Person> GetPersonByIdAsync([Service] MyDbContext context)
{
    // omitted for brevity
}
```

For instance, let's take the above; we are injecting a service `MyDbContext` into our resolver. The resolver compiler knows what to do with this parameter because of the service attribute. These attributes can become quite tedious to annotate if you have a lot of resolvers. Further, people might want to extend the parameter injection or introduce their own parameter injection logic. With Hot Chocolate 12, we open up the resolver compiler and allow you to configure it straightforwardly.

Let's start with a basic example of `MyDbContext` as a well-known service that no longer needs an attribute.

Essentially we want to be able to write the following code without any attributes:

```csharp
public async Task<Person> GetPersonByIdAsync(MyDbContext context)
{
    // omitted for brevity
}
```

To tell the resolver compiler that we have a well-known service, we need to do the following:

```csharp
.AddGraphQLServer()
    .AddQueryType<Query>()
    .ConfigureResolverCompiler(r =>
    {
        r.AddService<Service>();
    });
```

Specifically for the service case, we simplified things with the `AddService` extension method. With this simple configuration, we can make our resolver code cleaner and better to read.

But what if we wanted to inject a specific thing from the request state. Essentially we want to grab something from the `ContextData` map and make it nicely accessible through parameter injection.

```csharp
public async Task<Person> GetPersonByIdAsync(MyDbContext context, CustomState state)
{
    // omitted for brevity
}
```

For the above resolver, we want to pull `CustomState` from the request state.

```csharp
.AddGraphQLServer()
    .AddQueryType<Query>()
    .ConfigureResolverCompiler(r =>
    {
        r.AddService<Service>();
        r.AddParameter<CustomState>(resolverContext => (CustomState)resolverContext.ContextData["myCustomState"]!);
    });
```

I know the expression I wrote up there is not safe; it is just an example of how you can access nearly anything from the resolver context and make it injectable into your resolver. The expression will be compiled into the resolver.

We could go further and write a selector for your resolver compiler extension that inspects the parameter. These inspections are only run at startup, which ensures that there is no reflection overhead at runtime.

```csharp
.AddGraphQLServer()
    .AddQueryType<Query>()
    .ConfigureResolverCompiler(r =>
    {
        r.AddService<Service>();
        r.AddParameter<CustomState>(
            resolverContext => (CustomState)resolverContext.ContextData["myCustomState"]!,
            p => p.Name == "state");
    });
```

However, we are not done with this yet. We are already thinking about giving you even more freedom to extend the resolver compiler by injecting proper logic that runs in the resolver pipeline. We essentially want to support a kind of conditional middleware, where we will append middleware depending on what you inject into your resolver. We have not fully solved all the issues around this yet and have moved this to Hot Chocolate 13.

# Dynamic Schemas

While static schemas created with C# or GraphQL SDL are very simple to build with Hot Chocolate, it was pretty challenging to build dynamic schemas based on JSON files or database tables. It was achievable, like in the case of schema stitching, but it was pretty tricky, and you needed to know quite a lot about the internals of the type system. With Hot Chocolate 12, we are opening up the type system quite a lot to allow you to create types in an unsafe way.

With unsafe, I mean that we allow you to create the types by bypassing validation logic intended for the standard users of Hot Chocolate and using the type system definition objects to create types and type extensions.

I will do a follow-up post that goes deeper into the type system and explains the inner workings. For this post, let me show you a simple example of how you can now create dynamic types. First, let me introduce a new component here called type module.

```csharp
public interface ITypeModule
{
    event EventHandler<EventArgs> TypesChanged;

    ValueTask<IReadOnlyCollection<ITypeSystemMember>> CreateTypesAsync(
        IDescriptorContext context,
        CancellationToken cancellationToken);
}
```

Type modules provide types for specific components or data sources; for instance, the new schema stitching engine will use type modules to provide types to the schema.

A type module consists of an event `TypesChanged` and a method `CreateTypesAsync`. `CreateTypesAsync` is called by the schema building process to create types for a new schema instance. Whenever something changes for a type module, like the underlying database structure, the `TypesChanged` event can be triggered to tell Hot Chocolate that it needs to phase out the old schema and phase in a new schema with the changed types of this module. The Hot Chocolate server will ensure that running requests are still completed against the old schema while new requests are routed to the new schema instance that contains the updated types.

Essentially, `ITypeModule` will remove the complexity of providing a dynamic schema with hot-reload functionality.

But we not only introduced this new interface to provide types, but we also opened up our lower-level configuration API, which now lets you create types straightforwardly from a Json file or what have you.

```csharp
public async ValueTask<IReadOnlyCollection<ITypeSystemMember>> CreateTypesAsync(
    IDescriptorContext context,
    CancellationToken cancellationToken)
{
    var types = new List<ITypeSystemMember>();

    await using var file = File.OpenRead(_file);
    using var json = await JsonDocument.ParseAsync(file, cancellationToken: cancellationToken);

    foreach (var type in json.RootElement.EnumerateArray())
    {
        var typeDefinition = new ObjectTypeDefinition(type.GetProperty("name").GetString()!);

        foreach (var field in type.GetProperty("fields").EnumerateArray())
        {
            typeDefinition.Fields.Add(
                new ObjectFieldDefinition(
                    field.GetString()!,
                    type: TypeReference.Parse("String!"),
                    pureResolver: ctx => "foo"));
        }

        types.Add(
            type.GetProperty("extension").GetBoolean()
                ? ObjectTypeExtension.CreateUnsafe(typeDefinition)
                : ObjectType.CreateUnsafe(typeDefinition));
    }

    return types;
}
```

A complete example of a dynamic schema with hot-reload can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/TypeModules), and I will also follow up this post with a detailed blog post on dynamic schemas that goes more into the details.

## Type Interceptors

We also added further improvements to the type initialization to allow type interceptors to register new types. Also, on this end, you can now hook into the type initialization to analyze the types registered by a user and then create further types based on the initial schema. Where type modules generate types based on an external component or data source, type interceptors allow you to generate types based on types. This can be useful if you, for instance, create a filter API that is based on the output types provided by a user.

# Schema-First

Another area where we have invested for Hot Chocolate 12 was schema-first. At its very beginning, Hot Chocolate was a schema-first library that developed more and more into a code-first / annotation-based library. If we look back at Hot Chocolate 11, then it almost looked like schema-first was an afterthought. With Hot Chocolate 12, we are bringing schema-first up to par with code-first and the annotation-based approach. This means that we also did some API refactoring and kicked out the old binding APIs. We did these breaking changes to align APIs of the various approaches.

If we now create a schema-first server, it looks very similar to code-first or annotation-based servers from a configuration standpoint.

```csharp
using Demo.Data;
using Demo.Resolvers;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddSingleton<PersonRepository>()
    .AddGraphQLServer()
    .AddDocumentFromFile("./Schema.graphql")
    .AddResolver<Query>();

var app = builder.Build();

app.MapGraphQL();

app.Run();
```

There are now two things in schema first to distinguish, resolver types and runtime types. Runtime types are the representation of a GraphQL type in .NET.

```sdl
type Person {
  name: String!
}
```

```csharp
public record Person(int Id, string Name);
```

The .NET representation, in this case, is a record, but it could also be a map, a JSON structure, or something else. In most cases, we automatically infer the correct binding between runtime type and GraphQL type, but we can now use the same API as with the other approaches if you need to bind the type explicitly.

```csharp
builder.Services
    .AddSingleton<PersonRepository>()
    .AddGraphQLServer()
    .AddDocumentFromFile("./Schema.graphql")
    .AddResolver<Query>()
    .BindRuntimeType<Person>();
```

Or, if the name does not match the .NET type name, you can pass that in as well.

```csharp
builder.Services
    .AddSingleton<PersonRepository>()
    .AddGraphQLServer()
    .AddDocumentFromFile("./Schema.graphql")
    .AddResolver<Query>()
    .BindRuntimeType<Person>("Person");
```

Resolver types are .NET classes that provide resolvers methods, so essentially we give a class that has a couple of methods handling data fetching for our GraphQL types. In this instance, we have a type `Query` that provides a method to fetch persons.

```csharp
public class Query
{
    public IEnumerable<Person> GetPersons([Service] PersonRepository repository)
        => repository.GetPersons();
}
```

In our example, the resolver type name matches the GraphQL type, so bindings are automatically inferred. If you have multiple resolver classes per GraphQL type, you can use an overload that passes in the GraphQL type name.

```csharp
.AddResolver<QueryResolvers>("Query")
```

Naturally, we still have the delegate variants of the `AddResolver` configuration methods to bind a delegate to a GraphQL field.

```csharp
.AddResolver("Query", "sayHello", ctx => "hello")
```

## Middleware and Attributes

One more thing we did was fully integrate our attributes like `UsePaging` with schema first resolvers.

Meaning you can write the following schema now:

```sdl
type Query {
  persons: [Person!]
}

type Person {
  name: String!
}
```

Then on your `Query` resolver for `persons`, annotate it with the `UsePaging` attribute. This will cause the schema initialization to rewrite the schema.

```csharp
public class Query
{
    [UsePaging]
    public IEnumerable<Person> GetPersons([Service] PersonRepository repository)
        => repository.GetPersons();
}
```

The output schema on the server would now look like the following:

```sdl
type Query {
  persons(
    """
    Returns the first _n_ elements from the list.
    """
    first: Int

    """
    Returns the elements in the list that come after the specified cursor.
    """
    after: String

    """
    Returns the last _n_ elements from the list.
    """
    last: Int

    """
    Returns the elements in the list that come before the specified cursor.
    """
    before: String
  ): PersonsConnection
}

type Person {
  name: String!
}

"""
A connection to a list of items.
"""
type PersonsConnection {
  """
  Information to aid in pagination.
  """
  pageInfo: PageInfo!

  """
  A list of edges.
  """
  edges: [PersonsEdge!]

  """
  A flattened list of the nodes.
  """
  nodes: [Person!]
}

"""
Information about pagination in a connection.
"""
type PageInfo {
  """
  Indicates whether more edges exist following the set defined by the client's arguments.
  """
  hasNextPage: Boolean!

  """
  Indicates whether more edges exist prior to the set defined by the client's arguments.
  """
  hasPreviousPage: Boolean!

  """
  When paginating backwards, the cursor to continue.
  """
  startCursor: String

  """
  When paginating forwards, the cursor to continue.
  """
  endCursor: String
}

"""
An edge in a connection.
"""
type PersonsEdge {
  """
  A cursor for use in pagination.
  """
  cursor: String!

  """
  The item at the end of the edge.
  """
  node: Person!
}
```

The paging attribute rewrote the schema and wrapped a middleware around the field resolver to support pagination. Rest assured, you can still fully control your schema and specify all of those types by yourself, but you also can let Hot Chocolate generate all those tedious types like connection types, edge types or filters types, etc.

In the future, we are also thinking of letting descriptor attributes become directives that would allow you to annotate directly in the schema file like the following:

```sdl
type Query {
  persons: [Person!] @paging
}

type Person {
  name: String!
}
```

But for the time being, schema-first got a big update with this release, and we will continue to make it better with every new release.

The schema-first demo can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/SchemaFirst).

# DataLoader

Another component that got a massive overhaul is DataLoader. It was also one reason the release candidate phase stretched so far since we had lots of issues with the changes in user projects. First, as we already said we would do, we moved all the DataLoader classes into the `GreenDonut` library, meaning that the various DataLoader no longer reside in `HotChocolate.Types`. Apart from that, we have refactored a lot to allow DataLoader to pool more of its objects and use a unified cache for entities. This unified cache allows better control of how much memory can be allocated by a single request and lets us do cross DataLoader updates. Essentially, one DataLoader can now fill the cache for another DataLoader. Cross DataLoader updates often happen when you have entities that can be looked up by multiple keys, like a user that can be fetched by its name or by its id.

To take advantage of the new cache, pass down the DataLoader options to inject them from the DI.

```csharp
public class CustomBatchDataLoader : BatchDataLoader<string, string>
{
    public CustomBatchDataLoader(IBatchScheduler batchScheduler, DataLoaderOptions options)
        : base(batchScheduler, options)
    {
    }

    protected override Task<IReadOnlyDictionary<string, string>> LoadBatchAsync(
        IReadOnlyList<string> keys,
        CancellationToken cancellationToken)
}
```

With DataLoader now, always pass down the options and the batch scheduler so the DI can inject the new unified cache. If you do not pass down the options object, the DataLoader will use a cache per instance like before.

The DataLoader caches with Hot Chocolate 12 are also pooled, meaning that the cache object is cleaned, preserved, and reused, which will save memory. Further, we have now introduced `DataLoaderDiagnosticEventListener`, which allows you to monitor DataLoader execution.

All diagnostic listeners cannot be registered with the schema.

```csharp
services.AddGraphQLServer()
    .AddDiagnosticEventListener<MyDataLoaderEventListener>()
    ...
```

# Stream and Defer

With Hot Chocolate 11, we introduced the `@defer` directive, which allows you to defer parts of your query to get the most important data first, and de-prioritize the execution of more expensive parts of your query.

With Hot Chocolate 12, we are now introducing the `@stream` directive, which allows you to take advantage of async enumerators and define how much data of a stream you want to get immediately and what shall be deferred to a later point in time.

```graphql
{
  persons @stream(initialCount: 2) {
    name
  }
}
```

`@stream` works with any list in Hot Chocolate, but it is only efficient and gives you all the benefits of using stream if your resolver returns an `IAsyncEnumerable<T>`. Our internal paging middleware at the moment does not work with `IAsyncEnumerable<T>`, which means you can stream the results. However, you still will have the full execution impact on the initial piece of the query. We will rework pagination to use `IAsyncEnumerable<T>` when slicing the data and executing the query with Hot Chocolate 13.

Stream and defer both work with Banana Cake Pop if your browser is chrome based. We already have an update in the works to make it work with Safari. We will issue this BCP update with Hot Chocolate 12.1.

# ASP.NET Core improvements

Hot Chocolate neatly integrates with ASP.NET core, and with a simple `MapGraphQL`, you get a GraphQL over HTTP spec-compliant endpoint. This simple `MapGraphQL` is great when you get started with Hot Chocolate but limiting when you go to production and have different authorization requirements for various aspects of the GraphQL transport layer.

Hot Chocolate 12 still keeps its `MapGraphQL` around but now also provides a specific transport method.

| Method              | Description.                                                                                                              |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| MapGraphQL          | MapGraphQL is our default way of adding GraphQL transport and adds just everything on one route.                          |
| MapGraphQLHttp      | MapGraphQLHttp will add support for GraphQL HTTP Post, GraphQL HTTP GET, and support for MultiPart and batching requests. |
| MapGraphQLWebSocket | MapGraphQLWebSocket will add support for GraphQL over web-sockets.                                                        |
| MapGraphQLSchema    | MapGraphQLSchema will add an endpoint to fetch the GraphQL SDL.                                                           |
| MapBananaCakePop    | MapBananaCakePop will add the Banana Cake Pop GraphQL IDE middleware.                                                     |

These new map methods will allow you to pass in a configuration as you can with `MapGraphQL`.

# Banana Cake Pop

After Hot Chocolate 11, we started reworking Banana Cake Pop and rethinking what we wanted to enable with our GraphQL IDE. Hot Chocolate 12 now incorporates preview 14 of the new Banana Cake Pop, and we will deliver the final version of the new Banana Cake Pop IDE with Hot Chocolate 12.1 at the end of October.

Banana Cake Pop is now again available as middleware and application for Windows, macOS, and Linux. The team is working hard to get major new features like authentication flows, document synchronization, and schema reference into BCP.

![Banana Cake Pop](bcp.png)

[Download](https://bananacakepop.com) the new BCP preview today and help us make this the best GraphQL IDE out there. We still have lots to do to get to that point, but people following us on slack can see the progress. We will soon have the next preview available, which will make a significant jump in functionality.

# The little things that will make your life easier

Apart from our big-ticket items, we also have invested in smaller things that will help make Hot Chocolate easier to learn and better to use.

## Cursor Paging

### Boundaries

We introduced more options for cursor paging that allow you to require paging boundaries like GitHub is doing with their public API.

```csharp
public class Query
{
    [UsePaging(RequirePagingBoundaries = true)] // will create MyNameConnection
    public IEnumerable<Person> GetPersons([Service] PersonRepository repository)
        => repository.GetPersons();
}
```

### Connections

Further, we reworked how the connection name is inferred and allow you to override defaults locally. With Hot Chocolate 12, we infer the connection name from the field instead of the element type. Since this change will break all existing schemas built with Hot Chocolate so far, we allow you to switch to the old way of inferring the connection name with the paging options.

```csharp
services.AddGraphServerQL()
    .AddQueryType<QueryType>()
    .SetPagingOptions(new PagingOptions { InferConnectionNameFromField = false });
```

The connection name, by default, is inferred from the field name; this means if you have a field `friends`, then the connection will be called `FriendsConnection` instead of the old behavior where we used the element type.

You also can override the default connection name.

```csharp
public class Query
{
    [UsePaging(ConnectionName = "MyName")] // will create MyNameConnection
    public IEnumerable<Person> GetPersons([Service] PersonRepository repository)
        => repository.GetPersons();
}
```

### Paging Provider

We also made it now easier to control which paging provider is used. For one, you can now configure the default paging provided. If you do not specify anything, we will set the queryable paging provider as the default provider.

```csharp
services.AddGraphServerQL()
    .AddQueryType<QueryType>()
    .AddCursorPagingProvider<MyCustomProvider>(defaultProvider = true);
```

Also, you can now name a provider, which gives you an easy way to point to the specific paging provider.

**Register Provider:**

```csharp
services.AddGraphServerQL()
    .AddQueryType<QueryType>()
    .AddCursorPagingProvider<MyCustomProvider>("Custom");
```

**Use Provider:**

```csharp
public class Query
{
    [UsePaging(ProviderName = "Custom")]
    public IEnumerable<Person> GetPersons([Service] PersonRepository repository)
        => repository.GetPersons();
}
```

> Since we now can easily interact with multiple providers, we removed the `UseMongoPagingAttribute`. Please have a look at our documentation regarding MongoDB.

### Control

Sometimes, you want to have everything in your own hands and just use Hot Chocolate to take the tedious work of generating types of your hands. In this case, you can implement the paging algorithm in your business logic or the resolver and return a connection instance, and we will know what to do with it.

```csharp
public class Query
{
    [UsePaging]
    public Task<Connection<Person>> GetPersons([Service] PersonRepository repository, int? first, string? after, int? last, string? before)
        => repository.GetPersonsPagedAsync(first, after, last, before);
}
```

If you are using the `HotChocolate.Data` package in combination with the connection type, you can even use our new data extensions to allow for more complex resolvers.

```csharp
public class Query
{
    [UsePaging]
    [UseProjection]
    [UseFiltering]
    [UseSorting]
    public Task<Connection<Person>> GetPersonsAsync(
        [Service] PersonRepository repository,
        IResolverContext context,
        CancellationToken cancellationToken)
        => repository.GetPersons()
              .Filter(Context)
              .Sort(context)
              .Project(context)
              .ApplyCursorPaginationAsync(context, cancellationToken);
}
```

## Relay

As always, we are investing a lot into removing complexity from creating relay schemas. Our new version adds the `nodes` field (a plural version of the `node` field), allowing clients to fetch multiple nodes in one go without rewriting the query since the `ids` can be passed in as a variable. While the `nodes` field is not part of the relay specification, it is a recommended extension.

```graphql
{
  nodes(ids: [ 1, 2 ]) {
    __typename
    ... Person {
      name
    }
    ... Cat {
      name
    }
  }
}
```

Apart from that, we have split the `EnableRelaySupport` configuration method to allow you to opt into partial concepts of the relay specification.

```csharp
services.AddGraphServerQL()
    .AddGlobalObjectIdentification()
    .AddQueryFieldToMutationPayloads();
```

The two new configuration methods are more precise, and you can now opt into the concepts you need and nothing more.

## Errors

Another area where users asked us to improve was with errors. When you want to produce a GraphQL error, you can use a `GraphQLException` or any other exception in combination with error filters.

People often choose the latter since errors may come from the business layer that already has a set of well-defined domain exceptions. The issue that many users had was that one exception could always only spawn one GraphQL error.

With HotChocolate 12, we have introduced the `AggregateError` class, which allows you to wrap multiple errors into one error object; this helps us to preserve the interface but at the same time enables you to transform a single exception or a single error into multiple errors.

**Error Filter**

```csharp
public class ErrorFilter : IErrorFilter
{
    public IError OnError(IError error)
    {
        if (error.Exception is AggregateException ex)
        {
            var errors = new List<IError>();

            foreach (Exception innerException in ex.InnerExceptions)
            {
                errors.Add(error.WithMessage(innerException.Message).WithException(innerException));
            }

            return new AggregateError(errors);
        }

        return error;
    }
}
```

**Registration**

```csharp
builder.Services
    .AddGraphQLServer()
    .AddErrorFilter<ErrorFilter>()
    ...
```

Speaking of errors, we have put a lot of effort into providing better errors. One of these efforts resulted in splitting the infamous error `HC0016` into multiple errors that now clearly outline the issue with invalid variable inputs. It's often these little things that save users from frustrations when searching for issues.

# Outlook

Hot Chocolate 12 is a release where we put a lot of work into the core of the server. In most cases, an upgrade from Hot Chocolate 11 to Hot Chocolate 12 should be just updating the package.

With Hot Chocolate 13, we will now focus on our stitching and schema federation engine as the main topic. Hot Chocolate 12 introduced many new concepts that allow us to completely rethink schema stitching, e.g., with type modules and query plans.

Beginning this week, we will start working on the new version, which we hope to finish at the end of November.

But there are also other topics Hot Chocolate 13 will tackle like support for AzureFunctions, more transport protocols like graphql-ws and Azure Web PubSub and many more things.

If you want to have a look at the high-level roadmap, you can check it out [here](https://github.com/ChilliCream/graphql-platform/projects/28).

There are also dot releases planned for Hot Chocolate 12, with 12.1 already scheduled for the end of October.

We have tons of updates in the pipeline, with the new Banana Cake Pop release waiting already around the corner.

So stay tuned :)
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Language Injection in Rider]]></title>
        <id>https://chillicream.com/blog/2021/07/20/rider-language-injection</id>
        <link href="https://chillicream.com/blog/2021/07/20/rider-language-injection"/>
        <updated>2021-07-20T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
This post will show you how JetBrains Rider can make your life a little easier when working with GraphQL queries in string literals.
![Syntax Highlighting in String Literals](./header.png)

## Testing is hard

When writing integration tests for HotChocolate, you find yourself often writing GraphQL queries in string literals. The
most challenging part of writing an integration test is to write the query correctly. You quickly forget a bracket, the
name of a field or a required input field and you end up with an invalid query.

If you use JetBrains Rider, you can easily solve this problem and write integration tests with ease. Rider supports
language injection in string literals.

## Getting Started

Rider has no support for the GraphQL language out of the box. You need to install the extension JS GraphQL
from [Jim Kydne Meyer](https://github.com/jimkyndemeyer). You can install the extension from the marketplace or download
it here [JS GraphQL](https://plugins.jetbrains.com/plugin/8097-js-graphql).

The extension needs to know your schema, but in exchange, you get syntax highlighting, linting and IntelliSense.

## Creating a schema file

When you use the annotation-based or the code-first approach of HotChocolate, a change on a domain model often results
in a change in the schema. Even though this is in most cases wanted, it also happens that you change the schema by
accident. It's recommended to have at least one snapshot test of your GraphQL schema to avoid accidental changes.

A snapshot test captures the schema, stores it in the project folder and from then on compares the stored schema against
the schema from your server. In the HotChocolate code base, we make heavy use of snapshot testing. We can recommend the
package [Snapshooter](https://swisslife-oss.github.io/snapshooter/docs/get-started). With Snapshooter you can create snapshot tests for any object.

```csharp
[Fact]
public void ExampleUseOfSnapshooter()
{
   // arrange
   var serviceToTest = new ServiceToTest();

   // act
   List<string> result = serviceToTest.GetSomeStrings();

   // assert
   result.MatchSnapshot();
}
```

A HotChocolate schema, can be printed into a string and this string can then be used in a snapshot test. This schema
snapshot can also be used as the source for the GraphQL extension. The JS GraphQL extension requires a schema file with
the name `schema.graphql`. You can configure the extension in a `.graphqlconfig` file

The snapshot test to capture the schema could look like this:

_/test/ExampleProject.Tests/SchemaTests.cs_

```csharp
public class SchemaTests
{
    [Fact]
    public async Task SchemaShouldNotChange()
    {
        // arrange
        SnapshotFullName fullName = new XunitSnapshotFullNameReader().ReadSnapshotFullName();
        IServiceCollection services = ConfigureTestServices();
        IRequestExecutor executor = await services
            .AddGraphQLServer()
            .BuildRequestExecutorAsync();

        // act
        string schema = executor.Schema.Print();

        // assert
        schema.MatchSnapshot(new SnapshotFullName("schema.graphql", fullName.FolderPath));
    }
}
```

The example from above creates a snapshot of the schema in `/test/ExampleProject.Tests/__snapshots__/schema.graphql`. You now
have to make the GraphQL extension aware of this schema by creating a `.graphqlconfig`

`_/test/ExampleProject.TestsYourProject.Tests/.graphqlconfig_`

```json
{
  "name": "example-project",
  "schemaPath": "./__snapshots__/schema.graphql"
}
```

Now all `.gql` and `.graphql` files in your project will have proper syntax highlighting, IntelliSense and linting.

## Inject GraphQL into strings

If you write integration tests for your GraphQL server, your tests probably look similar to this:

```csharp
public class PersonsIntegrationTests
{
    [Fact]
    public async Task GetPersons_Should_ReturnPagesPersons()
    {
        // arrange
        IServiceCollection services = ConfigureTestServices();
        IRequestExecutor executor = await services
            .AddGraphQLServer()
            .BuildRequestExecutorAsync();

        string query =
            @"query getPersons {
            persons {
                nodes {
                    name
                }
            }
        }";

        IReadOnlyQueryRequest request =
            QueryRequestBuilder.New().SetQuery(query).Create();

        // act
        IExecutionResult result = await executor.ExecuteAsync(request);

        // assert
        result.ToJson().MatchSnapshot();
    }
}
```

The GraphQL extension now knows the schema, but Rider does not understand that the string contains a GraphQL query.
To make Rider aware of string literals that contain GraphQL queries, you have to add a new language injection provider.

1. Go To 'Preferences' and search for 'Language Injection'
   ![Rider Preferences Window](./preferences.png)
2. Add a new 'Generic Csharp' Language Injection
3. Select GraphQL in the Dropdown ID
4. Add the following pattern

```text
- csharpLiteralExpression().withText(string().matchesBrics("@?[\"'] *((query|mutation|subscription) .*) .*[\"']?"))
```

![Rider language injection-settings](./language-injection-settings.png)

Now every string in C# that starts with either `query`, `mutation`, or `subscription` will be interpreted by Rider as a GraphQL Query.

![Rider Look and Feel with the working extensions](./lookandfeel.png)

You can find an example project here [rider-language-injection-example](https://github.com/PascalSenn/rider-language-injection-example)

In case you have questions, [Join our Slack Channel](http://slack.chillicream.com/). We have a very welcoming and helpful community that is waiting for you.

If you like what we are doing at ChilliCream, head over to the [HotChocolate repository and **give us a star**](https://github.com/ChilliCream/graphql-platform).
It helps us to gain visibility and grow our already awesome community!

Thank you!
]]></content>
        <author>
            <name>Pascal Senn</name>
            <uri>https://github.com/pascal_senn</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[ChilliCream Platform Update 11.1]]></title>
        <id>https://chillicream.com/blog/2021/03/31/chillicream-platform-11-1</id>
        <link href="https://chillicream.com/blog/2021/03/31/chillicream-platform-11-1"/>
        <updated>2021-03-31T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we are releasing Hot Chocolate server and Strawberry Shake client 11.1. This release brings many things that we skipped for the initial release of Hot Chocolate server 11. The platform now contains four major components: Hot Chocolate server, Hot Chocolate gateway, Banana Cake Pop, and Strawberry Shake.

# Strawberry Shake

Let us start with the biggest new feature we built for 11.1, which is Strawberry Shake.

What the heck is Strawberry Shake, you ask?

Well, that has changed over the time of our development on it. When we started looking at GraphQL clients, in general, and how we can bring something to .NET, we began to try out many things and experimented with the experience.

The first internal StrawberryShake was a GraphQL client built on top of IQueryable. The experience felt awful since we had to create artificial C# syntax to describe a GraphQL query, and this never felt natural. We came away with the feeling that users would struggle guessing what selection syntax would translate into what GraphQL syntax. With directives and features like `@defer` it grew more and more awful. Ever since this first try, we were convinced to bring a better experience where GraphQL is front and center. We came away with the thought that it is best to do GraphQL with GraphQL. When we write a GraphQL query, we already have this beautiful and simple syntax that is strongly typed. The only thing we were missing is something that makes it a first citizen in the .NET IDEs and the .NET build process.

The first public preview of Strawberry Shake began to go down this path by compiling the GraphQL queries into C# code. Still, it essentially was a glorified HttpClient.

After our first tries with Strawberry Shake, we polled our community and looked at what people want to do with a GraphQL client in .NET. There are actually three different use-cases people want to tackle with Strawberry Shake.

- Build an application (frontend/UI) with GraphQL (Xamarin/Blazor)
- Do server-to-server communication
- Write unit tests against a GraphQL server

When we polled our users, we found that 1 and 2 have an almost equal share of people. Use-Case 2 is a bit bigger. The group that wants to write tests with Strawberry Shake is the smallest at around 10%.

When we restarted the development on Strawberry Shake, we thought building a GraphQL client for the first group would allow us to disrupt the ecosystem the most. Something like Relay or Apollo client is completely missing in the .NET ecosystem. If we look at patterns and how UIs are built in .NET, we see that it is over complicated to achieve these reactive UIs that work even when your application goes offline with things like optimistic mutations.

So, for version 11.1, we set the focus on .NET frontend developers.

When you ask me now what Strawberry Shake is, I would say it is a state management component.

## State and Entities

Strawberry Shake understands your schema and knows what your entities are. When you interact with your data through Strawberry Shake, you are really interacting against a store that holds this data. The data in this store is normalized into entities and can be local data or remote data.

```mermaid
sequenceDiagram
    participant Generated Client
    participant Operation Store
    participant Entity Store
    participant GraphQL Server
    Generated Client->>Operation Store: Queries local store
    Operation Store->>GraphQL Server: Queries GraphQL server
    Note over Entity Store: Normalize response into entities
    GraphQL Server->>Entity Store: Returns GraphQL response
    Note over Operation Store: Builds operation result from entities
    Entity Store->>Operation Store: Returns entities for operation
    Operation Store->>Generated Client: Returns operation result
```

When you write a GraphQL query, we will compile it into C# code. The generated client will know how to decompose the response of your queries into entities. Strawberry Shake knows which query holds the data of which entity.

![Data is normalized into entities.](normalize-entities.png)

## How it works

Let us have a look at how this all works and make some sense of this long introduction.

When we write a query like the following:

```graphql
query GetSessions {
  sessions(order: { title: ASC }) {
    nodes {
      title
    }
  }
}
```

We compile the GraphQL operation to a .NET client where each operation becomes a class that can be executed.

```csharp
public interface IConferenceClient
{
    IGetSessionsQuery GetSessions { get; }
}

public interface IGetSessionsQuery
{
    Task<IOperationResult<IGetSessionsResult>> ExecuteAsync(CancellationToken cancellationToken = default);

    IObservable<IOperationResult<IGetSessionsResult>> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null);
}
```

If we just want a simple fetch we can execute out query like the following and access the data:

```csharp
var result = await client.GetSessions.ExecuteAsync();

foreach(var session in result.Data.Sessions.Nodes)
{
    Console.WriteLine(session.Title);
}
```

This essentially is what we could do with the first public GraphQL client iteration of Strawberry Shake.

But I talked about state and how we understand data. Meaning we can also subscribe to our data.

```csharp
using var storeSubscription =
    client
        .GetSessions
        .Watch()
        .Where(result => result.IsSuccessResult())
        .SelectMany(result => result.Data.Sessions.Nodes)
        .Subscribe(session => Console.WriteLine(session.Title));
```

In this case, we are subscribing to our store and triggering an update to this store by fetching new data from the GraphQL server.

Whenever entities are changing that make up our operation response, the store will trigger our subscribe delegate, which in consequence will update our UI component.

Entities are changing whenever ANY request is made to the backend, whether it is a real-time request through subscriptions or just a mutation that is changing the data we are watching. For our application development, this means that we do NOT need to make unnecessary re-fetches or build complicated logic to update all the components where some data is displayed. We are just subscribing to the data, and whenever it changes, all components that display that particular piece of information are updated.

So, if we introduced a new mutation that changes a session that is in view in our `GetSessions` query than the store would trigger another update to our subscribe delegate.

```csharp
await client.UpdateSessionTitle.ExecuteAsync("U2Vzc2lvbgppMzU=", "Abc 123");
```

## Execution Strategies

Apart from our data's reactivity, we can also use the store to control when data is fetched. By default, Strawberry Shake will always first fetch from the network before it accepts updates to entities it is watching. It would often be more efficient if we first looked at our store and used the data that is already in our memory and at the same time started updating this data. This would lead to a more responsive UI component that has, in most cases, something to display right out of the gate.

We call this strategy `CacheAndNetwork`.

```csharp
using var storeSubscription =
    client
        .GetSessions
        .Watch(ExecutionStrategy.CacheAndNetwork) // <-- Define Network Strategy
        .Where(result => result.IsSuccessResult())
        .SelectMany(result => result.Data.Sessions.Nodes)
        .Subscribe(session => Console.WriteLine(session.Title));
```

Last but not least we have a third strategy to access data which is called `CacheFirst`. This strategy will look at the store first and use the data we already have. Only if the store has no data for the request we are executing will we go to the network to fetch new data.

## Persistence

The last aspect that I want to go into is store persistence. The store that we built into Strawberry Shake can also be persisted. We provide out-of-the-box a package to use SQLite to persist your data. Persisting your store can create true offline applications that fetch new data while online and preserve this data while offline. It also allows you to have faster startup times with your online applications since you can combine this with the `CacheAndNetwork` strategy, so whenever your mobile app starts, the user will immediately have data that will be updated in the background without you having to write all this complicated code.

Adding this capability to your application is now really two lines of code:

```csharp
serviceCollection
  .AddConferenceClient()
  .ConfigureInMemoryClient()
  .ConfigureHttpClient(client => client.BaseAddress = new Uri("..."))
  .AddSQLitePersistence("Data Source=mydb.db;"); // <-- add persistence
```

Second, we need to initialize the persistence at which point we load data from the database and track any change to the in-memory stores.

```csharp
await services.GetRequiredService<SQLitePersistence>().InitializeAsync();
```

## Outlook

This is the first real version of Strawberry Shake, and we have planned a lot more for it.

With 11.2, we are aiming at smoothening any rough edges around the tooling. Moreover, we bring a generator option to generate the client without the store for server-to-server use-cases.

For the next major release, we are looking to bring @stream, @defer, and the MultiPart request specification to StrawberryShake. All things we already support with the Hot Chocolate server. Further, we want to bring more protocols like subscriptions over SignalR and gRPC.

If you want to get started with strawberry shake or read more about its capabilities head over to our [documentation].

Strawberry Shake was mostly built by [Pascal], [Fred], [Rafael], and [me].

# Hot Chocolate

While we focused on Strawberry Shake for this release, we also invested further into our GraphQL server, Hot Chocolate.

## .NET Support

With version 11.1, we started compiling with the .NET 6 SDK, meaning that we target in our ASP.NET core components, .NET 6, .NET 5, and .NET Core 3.1. The GraphQL core and the parsers are still also compiled for .NET Standard 2.0. Further, all our client utilities are compiled for .NET Standard 2.0 as well to let you consume GraphQL in almost any .NET application.

## Performance

As with every release, we are putting a lot of energy into performance. With performance, we mean both execution time and memory usage. For this release, we looked at static memory usage. Essentially the memory footprint of Hot Chocolate when you just create the schema. When we started to work on this, Hot Chocolate used around 380.000 objects to create the GitHub schema. Now with version 11.1, we are only using around 80.000 objects to represent the same schema. We also reduced the schema memory usage by around 40%. We identified a lot more improvements that we can do in this area but where we would need to more substantially change how we build a schema. Beginning with version 12, we will use source generators in a lot of these areas in the server to achieve faster execution and a lower memory footprint.

## GraphQL MultiPart request specification

With version 11.1, we now support out-of-the-box the [GraphQL MultiPart request specification], which allows handling file streams in GraphQL requests.

When using the `HotChocolate.AspNetCore` package, your server out-of-the-box supports this new specification, no need to opt-in. In order to use the new capabilities, you need to register the `Upload` scalar.

```csharp
services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddType<UploadType>(); // <--- this registers the new scalar
```

To separate the `Upload` scalar from the ASP.NET core dependencies on all things multi-part, we have put the actual scalar into the [HotChocolate.Types.Scalars.Upload] package, which can be used in .NET Standard 2.0 and has only a dependency on [HotChocolate.Types].

When using the new type in our annotation-based approach, you only need to use the new interface `IFile`.

```csharp
public record CreateNewUserInput(string Username, IFile ProfilePicture);

public class Mutation
{
    public async Task<NewUserPayload> CreateNewUser(CreateNewUserInput input)
    {
        using Stream stream = input.ProfilePicture.OpenReadStream();
        // do your work with the streamed file here
    }
}
```

You can also use `IFile` directly as an argument or in lists.

For code-first, when you want to declare this explicitly, you can use the actual type `UploadType`,

```csharp
public class QueryType : ObjectType
{
    protected override void Configure(IObjectTypeDescriptor descriptor)
    {
        descriptor
            .Field("bar")
            .Argument("file", a => a.Type<UploadType>())...
    }
}
```

Finally, in schema-first, you can use the name of the scalar `Upload`.

```sdl
type mutation {
  uploadFile(file: Upload): Uri
}
```

Most of the work on this feature was done by [Tobias Tengler], who is one of our community members. He worked like most of us in his free time on this. Thank you, Tobias; we will put your code to good use.

## Scalars, Scalars, Scalars

We looked at the wider community and what problems many of you are facing. We often need to build for our specific use-cases new scalars that represent a specific domain need. We found by chance an excellent package of scalars build by [The Guild] for the JavaScript ecosystem. With version 11, we have started porting their scalars one by one over to Hot Chocolate. But fear not, we are not polluting the GraphQL core libraries with these new scalars. If you do not have any need for them, we will not bother you with this amazing set of scalars.

The new collection of scalars are published in the package [HotChocolate.Types.Scalars].

**New Scalars:**

| Type             | Description                                                                                                                                                                                                               |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| EmailAddress     | The `EmailAddress` scalar type represents an email address, represented as UTF-8 character sequences that follows the specification defined in RFC 5322.                                                                  |
| HexColor         | The `HexColor` scalar type represents a valid HEX color code.                                                                                                                                                             |
| Hsl              | The `Hsl` scalar type represents a valid a CSS HSL color as defined here <https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#hsl_colors>.                                                                       |
| Hsla             | The `Hsla` scalar type represents a valid a CSS HSLA color as defined here <https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#hsl_colors>.                                                                     |
| IPv4             | The `IPv4` scalar type represents a valid IPv4 address as defined here <https://en.wikipedia.org/wiki/IPv4>.                                                                                                              |
| IPv6             | The `IPv6` scalar type represents a valid IPv6 address as defined here [RFC8064](https://tools.ietf.org/html/rfc8064).                                                                                                    |
| Isbn             | The `ISBN` scalar type is an ISBN-10 or ISBN-13 number: https:\/\/en.wikipedia.org\/wiki\/International_Standard_Book_Number.                                                                                             |
| LocalDate        | The `LocalDate` scalar type represents an ISO date string, represented as UTF-8 character sequences yyyy-mm-dd. The scalar follows the specification defined in RFC3339.                                                  |
| LocalTime        | The `LocalTime` scalar type is a local time string (i.e., with no associated timezone) in 24-hr `HH:mm:ss]`.                                                                                                              |
| MacAddress       | The `MacAddress` scalar type represents an IEEE 802 48-bit Mac address, represented as UTF-8 character sequences. The scalar follows the specification defined in [RFC7042](https://tools.ietf.org/html/rfc7042#page-19). |
| NegativeFloat    | The `NegativeFloat` scalar type represents a double‐precision fractional value less than 0.                                                                                                                               |
| NegativeInt      | The `NegativeIntType` scalar type represents a signed 32-bit numeric non-fractional with a maximum of -1.                                                                                                                 |
| NonEmptyString   | The `NonNullString` scalar type represents non-empty textual data, represented as UTF‐8 character sequences with at least one character.                                                                                  |
| NonNegativeFloat | The `NonNegativeFloat` scalar type represents a double‐precision fractional value greater than or equal to 0.                                                                                                             |
| NonNegativeInt   | The `NonNegativeIntType` scalar type represents a unsigned 32-bit numeric non-fractional value greater than or equal to 0.                                                                                                |
| NonPositiveFloat | The `NonPositiveFloat` scalar type represents a double‐precision fractional value less than or equal to 0.                                                                                                                |
| NonPositiveInt   | The `NonPositiveInt` scalar type represents a signed 32-bit numeric non-fractional value less than or equal to 0.                                                                                                         |
| PhoneNumber      | The `PhoneNumber` scalar type represents a value that conforms to the standard E.164 format as specified in: <https://en.wikipedia.org/wiki/E.164>.                                                                       |
| PositiveInt      | The `PositiveInt` scalar type represents a signed 32‐bit numeric non‐fractional value of at least the value 1.                                                                                                            |
| PostalCode       | The `PostalCode` scalar type represents a valid postal code.                                                                                                                                                              |
| Port             | The `Port` scalar type represents a field whose value is a valid TCP port within the range of 0 to 65535.                                                                                                                 |
| Rgb              | The `RGB` scalar type represents a valid CSS RGB color as defined here [MDN](<https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb()_and_rgba()>).                                                            |
| Rgba             | The `RGBA` scalar type represents a valid CSS RGBA color as defined here [MDN](<https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb()_and_rgba()>).                                                          |
| UnsignedInt      | The `UnsignedInt` scalar type represents an unsigned 32‐bit numeric non‐fractional value greater than or equal to 0.                                                                                                      |
| UnsignedLong     | The `UnsignedLong` scalar type represents an unsigned 64‐bit numeric non‐fractional value greater than or equal to 0.                                                                                                     |
| UtcOffset        | The `UtcOffset` scalar type represents a value of format `±hh:mm`.                                                                                                                                                        |

Most of the work on this new library was done by [Gregory], who also put his free time into Hot Chocolate. We are happy to have you onboard, Gregory!

> More about this topic can be read [here](/docs/hotchocolate/v11/defining-a-schema/scalars).

## Type Extensions

For a long time, we have type extensions that essentially let you split up types into separate type definitions. Until now, they were bound by name and could just provide new fields to existing types. This is quite useful if you want to modularize your schema and have types from different modules extend each other.

When using the annotation-based approach, we so far could do something like the following:

```csharp
public class Session
{
    public int Id { get; set; }

    [Required]
    [StringLength(200)]
    public string? Title { get; set; }

    [StringLength(4000)]
    public string? Abstract { get; set; }

    public int? TrackId { get; set; }
}
```

Let's say `Session` is a domain entity. We do not want any GraphQL on it. But we do want to extend upon it. I know we could use code-first with our fluent API or schema-first and get this setup. But we also are able to create another type like the following:

```csharp
[ExtendObjectType(nameof(Session))]
public class SessionResolvers
{
    public async Task<Track> GetTrackAsync(
        [Parent] Session session,
        TrackByIdDataLoader trackById,
        CancellationToken cancellationToken) =>
        trackById.LoadAsync(session.TrackId, cancellationToken)
}
```

This essentially would then be merged by the schema builder into the following GraphQL type:

```sdl
type Session {
  id: Int!
  title: String!
  abstract: String
  trackId: Int
  track: Track
}
```

While this is nice, we actually do not want `trackId` and would like to replace `trackId` with `track`.

With version 11.1, we can now do that by binding the resolver to the field of the original type.

```csharp
[ExtendObjectType(nameof(Session))]
public class SessionResolvers
{
    [BindMember(nameof(Session.TrackId))]
    public async Task<Track> GetTrackAsync(
        [Parent] Session session,
        TrackByIdDataLoader trackById,
        CancellationToken cancellationToken) =>
        trackById.LoadAsync(session.TrackId, cancellationToken)
}
```

This now leads to our new GraphQL type:

```sdl
type Session {
  id: Int!
  title: String!
  abstract: String
  track: Track
}
```

We can also now globally ignore members from the original type without binding them to a new resolver on our extension type.

```csharp
[ExtendObjectType(
    nameof(Session),
    IgnoreProperties = new[] { nameof(Session.Abstract) })]
public class SessionResolvers
{
    [BindMember(nameof(Session.TrackId))]
    public async Task<Track> GetTrackAsync(
        [Parent] Session session,
        TrackByIdDataLoader trackById,
        CancellationToken cancellationToken) =>
        trackById.LoadAsync(session.TrackId, cancellationToken)
}
```

This leads to the following GraphQL type:

```sdl
type Session {
  id: Int!
  title: String!
  track: Track
}
```

We added one more thing to the new type extension API, and this also works in code-first with the fluent API.

We now can rewrite with type extensions multiple types at once by using base types or interfaces by doing the following:

```csharp
public class Session : IHasResourceKey
{
    public int Id { get; set; }

    public string? Key { get; set; }
}

public class Speaker : IHasResourceKey
{
    public int Id { get; set; }

    public string? Key { get; set; }
}

[ExtendObjectType(typeof(IHasResourceKey))]
public class HasResourceKeyResolvers
{
    [BindMember(nameof(Session.Key))]
    public async Task<string?> GetDescriptionAsync(...)
        // ... omitted for brevity
}
```

The GraphQL SDL representation would now look like the following:

```sdl
type Session {
  id: Int!
  description: String
}

type Speaker {
  id: Int!
  description: String
}
```

We can also use the new type extension API to extend all the entities in our schema with the node interface and add a custom node resolver.

```csharp
[Node]
[ExtendObjectType(typeof(IEntity))]
public class EntityExtension2
{
    // this is how the node field shall resolve this entity from the
    // database ...
    [NodeResolver]
    public static IEntity GetEntity(int id) => ...
}
```

We can also have a specific entity resolver for each specific entity:

```csharp
[Node]
[ExtendObjectType(typeof(IEntity))]
public class EntityExtension2
{
    [NodeResolver]
    public static Session GetSession(int id) => ...

    [NodeResolver]
    public static Speaker GetSpeaker(int id) => ...
}
```

As I initially said, a lot of these thing could already be achieved by using the fluent API or the more complex `TypeInterceptor`. With the new capabilities of the type extension API, we can now rewrite files very simply and with less boilerplate.

It also completes the annotation-based approach further and gives us more tools to create schemas with only C#.

> More about this topic can be read [here](/docs/hotchocolate/v11/defining-a-schema/extending-types).

## MongoDB integration

As with almost every release, we are further investing in our data integration layer. Version 11.1 is now embracing MongoDB even further with native query support. Until now, you could use MongoDB with filtering, sorting, and projections through their queryable provider. But the queryable provider has many shortcomings and does not support all the features of MongoDB. With the new integration, we are rewriting the GraphQL queries into native MongoDB queries. Meaning we are building up a BSON object representing the query.

A GraphQL query like the following,

```graphql
query GetPersons {
  persons(
    where: {
      name: { eq: "Yorker Shorton" }
      addresses: { some: { street: { eq: "04 Leroy Trail" } } }
    }
  ) {
    name
    addresses {
      street
      city
    }
  }
}
```

is rewritten into the Mongo query:

```json
{
  "find": "person",
  "filter": {
    "Name": { "$eq": "Yorker Shorton" },
    "Addresses": { "$elemMatch": { "Street": { "$eq": "04 Leroy Trail" } } }
  }
}
```

To use the new Mongo integration, you need to add the [HotChocolate.Data.MongoDb] package to your project.

You can build up queries with the native driver and then create an executable from them, representing a re-writable query to Hot Chocolate.

```csharp
[UsePaging]
[UseProjection]
[UseSorting]
[UseFiltering]
public IExecutable<Person> GetPersons([Service] IMongoCollection<Person> collection)
{
    return collection.AsExecutable();
}

[UseFirstOrDefault]
public IExecutable<Person> GetPersonById(
    [Service] IMongoCollection<Person> collection,
    Guid id)
{
    return collection.Find(x => x.Id == id).AsExecutable();
}
```

This feature was implemented by [Pascal], who is the third person who became a Chilli. Together [Pascal] and [I] are building most of the Hot Chocolate server and gateway.

> More about this topic can be read [here](/docs/hotchocolate/v11/integrations/mongodb).

## Mutation Transactions

Another area where we are making it easier for users is with our new mutation transactions. Mutation transactions are an opt-in feature, so you need to activate it to use it.

This is to make it easy to wrap transactions around the execution of mutation requests which is especially useful if you are executing multiple mutations at once. To have a `System.Transactions.TransactionScope` wrapped around your mutation request, you only need to add the following configuration to your GraphQL server configuration:

```csharp
services
    .AddGraphQLServer()
    ...
    .AddDefaultTransactionScopeHandler();
```

The default implementation looks like the following:

```csharp
/// <summary>
/// Represents the default mutation transaction scope handler implementation.
/// </summary>
public class DefaultTransactionScopeHandler : ITransactionScopeHandler
{
    /// <summary>
    /// Creates a new transaction scope for the current
    /// request represented by the <see cref="IRequestContext"/>.
    /// </summary>
    /// <param name="context">
    /// The GraphQL request context.
    /// </param>
    /// <returns>
    /// Returns a new <see cref="ITransactionScope"/>.
    /// </returns>
    public virtual ITransactionScope Create(IRequestContext context)
    {
        return new DefaultTransactionScope(
            context,
            new TransactionScope(
                TransactionScopeOption.Required,
                new TransactionOptions
                {
                    IsolationLevel = IsolationLevel.ReadCommitted
                }));
    }
}
```

You can also implement your very own transaction handler by implementing `ITransactionScopeHandler` on your own. Custom transaction scope handlers are registered like the following:

```csharp
services
    .AddGraphQLServer()
    ...
    .AddTransactionScopeHandler<CustomTransactionScopeHandler>();
```

> More about this topic can be read [here](/docs/hotchocolate/v11/defining-a-schema/mutations#transactions).

## Directive Introspection

We are always looking at new GraphQL features very early. But this time, we got in even earlier and picked up an experimental feature that could change entirely or might be dropped. We are following in this GraphQL-Java.

Essentially this represents an experiment to allow users to query directives through introspection.

In order to enable this feature, you need to opt into it by enabling this in the options.

In order to activate it do the following:

```csharp
services
    .AddGraphQL()
    .AddDocumentFromString(
        @"
            type Query {
                foo: String
                    @foo
                    @bar(baz: ""ABC"")
                    @bar(baz: null)
                    @bar(quox: { a: ""ABC"" })
                    @bar(quox: { })
                    @bar
            }

            input SomeInput {
                a: String!
            }

            directive @foo on FIELD_DEFINITION

            directive @bar(baz: String quox: SomeInput) repeatable on FIELD_DEFINITION
        ")
    .UseField(next => ...)
    .ModifyOptions(o => o.EnableDirectiveIntrospection = true);
```

This would now allow you to then query all directives on your type system like the following:

```graphql
{
  __schema {
    types {
      fields {
        appliedDirectives {
          name
          args {
            name
            value
          }
        }
      }
    }
  }
}
```

But often, we do not want to expose all of our directives. For instance, we might want to hide our internal `@authorize` directives, which refer to our security policies.

In this case, we can add another option to define the default visibility of directives.

```csharp
.ModifyOptions(o =>
{
    o.EnableDirectiveIntrospection = true;
    o.DefaultDirectiveVisibility = DirectiveVisibility.Internal;
});
```

With this setting in place, we no need to mark directives that we want to query publicly.

```csharp
private sealed class UpperDirectiveType : DirectiveType
{
    protected override void Configure(
        IDirectiveTypeDescriptor descriptor)
    {
        descriptor.Name("upper");
        descriptor.Public() // <-- marks the directive as publicly visible
        descriptor.Location(DirectiveLocation.Field);
        descriptor.Use(next => async context =>
        {
            await next.Invoke(context);

            if (context.Result is string s)
            {
                context.Result = s.ToUpperInvariant();
            }
        });
    }
}
```

You can even hide directives on runtime based on the user's permission. But as said before, all of this is experimental, and we will see how far this feature goes or how it will change over time.

# Summing up

Version 11.1 again is a significant update to the platform and has many more things packed that I did not have the time to list here.

Version 11.2 will mainly round out features of 11.1. The next major update is planned for the end of June 2021 and will focus on distributed schemas, Neo4J, and Banana Cake Pop. With the June update, we will finally bring a release version of Banana Cake Pop that will pack many new things.

We are doing as before a community gathering where we will walk you through all things new to version 11.1. You can join us by signing up for our [ChilliCream Platform 11.1 launch].

[chillicream platform 11.1 launch]: https://www.meetup.com/ChilliCream-User-Group/events/277223506/
[graphql multipart request specification]: https://github.com/jaydenseric/graphql-multipart-request-spec
[hotchocolate.types.scalars.upload]: https://www.nuget.org/packages/HotChocolate.Types.Scalars.Upload/
[hotchocolate.types]: https://www.nuget.org/packages/HotChocolate.Types/
[hotchocolate.types.scalars]: https://www.nuget.org/packages/HotChocolate.Types.Scalars/
[hotchocolate.data.mongodb]: https://www.nuget.org/packages/HotChocolate.Data.MongoDb/
[the guild]: https://the-guild.dev
[gregory]: https://twitter.com/wonbyte
[tobias tengler]: https://twitter.com/tobiastengler
[me]: https://twitter.com/michael_staib
[i]: https://twitter.com/michael_staib
[rafael]: https://twitter.com/rafaelstaib
[pascal]: https://twitter.com/Pascal_Senn
[fred]: https://github.com/fredericbirke
[documentation]: /products/strawberryshake

<!-- spell-checker:ignore lvbgpp, mydb, Shorton -->
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Log Your Queries While Building a GraphQL Server]]></title>
        <id>https://chillicream.com/blog/2021/01/10/hot-chocolate-logging</id>
        <link href="https://chillicream.com/blog/2021/01/10/hot-chocolate-logging"/>
        <updated>2021-01-10T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Whether you are a building your first Hot Chocolate GraphQL server, or you're on the core team who built it, having an easy way to see both
the query you've sent to the server immediately is very helpful and valuable. Small mistakes in syntax can be easily discovered, problems with
variable definitions can be tricky to uncover, and just in general, having those queries at your finger tips is a big benefit while developing or running your
Hot Chocolate GraphQL server.

# Just Show Me the Code

All the code from this article can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/blog/2021/2021-01-20-logging).

To start logging your GraphQL server requests this is all you need to do. First, you need to create a new class in your project that implements the listener `DiagnosticEventListener`.

```csharp
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using HotChocolate.Execution;
using HotChocolate.Execution.Instrumentation;
using Microsoft.Extensions.Logging;

namespace Logging
{
    public class ConsoleQueryLogger : DiagnosticEventListener
    {
        private static Stopwatch _queryTimer;
        private readonly ILogger<ConsoleQueryLogger> _logger;
        public ConsoleQueryLogger(ILogger<ConsoleQueryLogger> logger)
        {
            _logger = logger;
        }

        public override IActivityScope ExecuteRequest(IRequestContext context)
        {
            return new RequestScope(_logger, context);
        }

        private class RequestScope : IActivityScope
        {
            private readonly IRequestContext _context;
            private readonly ILogger<ConsoleQueryLogger> _logger;
            public RequestScope
                (ILogger<ConsoleQueryLogger> logger,
                     IRequestContext context)
            {
                _logger = logger;
                _context = context;
                _queryTimer = new Stopwatch();
                _queryTimer.Start();
            }

            public void Dispose()
            {
                if (_context.Document is not null)
                {
                    StringBuilder stringBuilder =
                        new(_context.Document.ToString(true));
                    stringBuilder.AppendLine();
                    if (_context.Variables != null)
                    {
                        var variablesConcrete =
                            _context.Variables!.ToList();
                        if (variablesConcrete.Count > 0)
                        {
                            stringBuilder.
                                AppendFormat($"Variables {Environment.NewLine}");
                            try
                            {
                                foreach (var variableValue in _context.Variables!)
                                {
                                    string PadRightHelper
                                        (string existingString, int lengthToPadTo)
                                    {
                                        if (string.IsNullOrEmpty(existingString))
                                            return "".PadRight(lengthToPadTo);
                                        if (existingString.Length > lengthToPadTo)
                                            return existingString.Substring(0, lengthToPadTo);
                                        return existingString + " ".PadRight(lengthToPadTo - existingString.Length);
                                    }
                                    stringBuilder.AppendFormat(
                                        $"  {PadRightHelper(variableValue.Name, 20)} :  {PadRightHelper(variableValue.Value.ToString(), 20)}: {variableValue.Type}");
                                    stringBuilder.AppendFormat($"{Environment.NewLine}");
                                }
                            }
                            catch
                            {
                                // all input type records will land here.
                                stringBuilder.Append("  Formatting Variables Error. Continuing...");
                                stringBuilder.AppendFormat($"{Environment.NewLine}");
                            }
                        }
                    }
                    _queryTimer.Stop();
                    stringBuilder.AppendFormat(
                        $"Elapsed time for query is {_queryTimer.Elapsed.TotalMilliseconds:0.#} milliseconds.");
                    _logger.LogInformation(stringBuilder.ToString());
                }
            }
        }
    }
}
```

Then, in your `startup.cs`, you need to subscribe to the the Hot Chocolate `DiagnosticEventListener`, which is what the above `ConsoleQueryLogger` class implements.

That's done in the `ConfigureServices` method in `startup.cs`.

```csharp
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddRouting()
            .AddGraphQLServer()
            .AddQueryType<Query>()
            .AddDiagnosticEventListener(sp =>
              new ConsoleQueryLogger(
                sp.GetApplicationService<ILogger<ConsoleQueryLogger>>()
              ));
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment()) app.UseDeveloperExceptionPage();

        app.UseRouting();

        app.UseEndpoints(endpoints => { endpoints.MapGraphQL(); });
    }
}
```

For this logger to have something to do, we need to have a `Query` in our project so let's make a very simple class and put it in a file `Query.cs`.

Let's assume you have in your `Query.cs` a resolver that takes a single parameter and returns a string based on a passed in parameter (like this for example).

```csharp
namespace logging
{
    public class Query
    {
        public Person GetPerson(bool upperCase = false)
        {
            return upperCase ?
                new Person("Luke Skywalker".ToUpper(), 101) :
                new Person("Luke Skywalker", 102);
        }
    }

    public class Person
    {
        public Person(string name,int id)
        {
            Name = name; Id = id;
        }
        public string Name { get; }
        public int Id { get; }
    }
}
```

When you execute the GraphQL query

```graphql
query person($upperCase: Boolean) {
  person(upperCase: $upperCase) {
    name
    id
  }
}
```

with the associated `Boolean` variable in your POST `upperCase`

```json
{
  "upperCase": true
}
```

You console output will show this

```bash
Executing endpoint 'Hot Chocolate GraphQL Pipeline'
info: logging.ConsoleQueryLogger[0]

query person($upperCase: Boolean) {
  person(upperCase: $upperCase) {
    name
    id
  }
}
Variables
upperCase    :true  :HotChocolate.Types.BooleanType
Elapsed time for query is 162 milliseconds.
```

Notice the execution time shows as 162 milliseconds. If you execute the query again, you'll see that drop to just 1 or 2 milliseconds as now, the query, along with it's resolvers are cached by Hot Chocolate.

Now, for a little more details on what's actually happening here, as well as how to log your queries using the very useful
<a href="https://miniprofiler.com/dotnet/AspDotNetCore" target="_blank">MiniProfiler for ASP.NET Core</a>.

# What is Really Going on Here

Adding console logging is really quite simple in what is going on. It's straight forward usage of both the ASP.NET Core <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection" target="_blank">Dependency Injection</a> and <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware" target="_blank">Middleware</a> implementations.

That middleware is added to our `startup.cs`.

```csharp
.AddDiagnosticEventListener(sp =>
  new ConsoleQueryLogger(
    sp.GetApplicationService<ILogger<ConsoleQueryLogger>>()
  ));
```

`AddDiagnosticEventListener` is adding to the Hot Chocolate GraphQL server a listener designed to listen for events that happen while the server is processing requests. Typically, these are diagnostic events that give us the ability to do things like capture GraphQL queries and variables while at the same time, doing something useful with them (like log them to the console).

Our `ConsoleQueryLogger` receives as an injected service, the logger itself, that uses the <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging" target="_blank">ASP.NET Core Logging API</a>, and the built in Console logging provider, `AddConsole`.

You will need to make sure that in your `program.cs` you've added `ConfigureLogging` to your `CreateHostBuilder` method. It should look similar to this.

```csharp
public static IHostBuilder
  CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(c => c.AddConsole())
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
```

Back to our `ConsoleQueryLogger` class. The entire purpose of this class is to hook into the Hot Chocolate GraphQL processing pipeline such that we can start a timer before the query starts processing. Then, at that processing completion, the query details, the variables associated with the query and the execution time are logged.

Because this method implements the Hot Chocolate `DiagnosticEventListener`, we can override the `ExecuteRequest` method which gives us a way to hook into the processing pipeline. That "hook in" is by way of Dependency Injection. By making the first parameter of that method an `IRequestContext`, we can get passed into this method, our GraphQL context for this request. That context contains all the details about the request including the query itself and its associated request variables.

From here, we create a new `RequestScope`, that will track our entire request from start to finish in the Hot Chocolate GraphQL server. We pass into that `RequestScope`, our console logger and our newly acquired GraphQL context.

Essentially, this new `RequestScope` tracks our GraphQL query from start to finish. We make use of `System.Diagnostics.Stopwatch` to time our request. We start the timer in the `RequestScope`'s constructor, and we stop it in its `Dispose` method. Because we have access to our request details, as well as the logger class, we can output our complete query to our logger on the completion of the request processing.

```csharp
public void Dispose()
{
    if (_context.Document is not null)
        _logger.LogInformation(_context.Document.ToString(true));
}
```

You don't really need to understand all these details to use the logger, and likely, in the future you would probably get this from another `nuget` package. For now, it's interesting to see how straight forward it is to hook directly into the processing of your GraphQL request.

# Logging Requests to MiniProfiler

Console logs are nice, but can get pretty cluttered and become unmanageable quickly. Luckily for us, there is very useful open source project that we can include for free in our apps called <a href="https://miniprofiler.com/dotnet/AspDotNetCore" target="_blank">MiniProfiler</a> and there is an implementation specifically written for <a href="https://docs.microsoft.com/en-us/aspnet/core" target="_blank">ASP.NET Core</a>.

The idea is that you get a URL route you can secure on your website that lists the queries you've run and how long each one took. Typically it's something like <u>http://localhost:5000/profiler/results-index</u>. Here is an example of us running the query we wrote earlier, multiple times.

![MiniProfiler Index Web Page](MiniProfiler-Index-640.png)

You can drill down on each one if these queries, and see the actual query as well as the passed in variables along with their associated input data.

![MiniProfiler Detail Web Page](MiniProfiler-Detail-640.png)

Just like for the `ConsoleQueryLogger` class, we need to create a similar class for our MiniProfiler to work. I've done that in our example repository and named the class `MiniProfilerQueryLogger`.

<https://github.com/pkellner/hot-chocolate-query-logging/blob/main/MiniProfilerQueryLogger.cs>

It also implements `DiagnosticEventListener` just like `ConsoleQueryLogger` did. It gets passed in the request context, but instead of logging to the console with the `ILogger` interface and the `ConsoleLoggerExtension`, it simply calls the MiniProfiler API directly.

I could have implemented it with the ILogger interface and that would have given a lot more flexibility to our logging, but that also would have added a lot more complexity, so for now, if you want to log to MiniProfiler, add this middleware to your GraphQL.

We do need to install the MiniProfiler package for ASP.NET Core so let's do that at the command line with `nuget`. That command is:

```bash
dotnet add package MiniProfiler.AspNetCore.Mvc
```

Then, to our `startup.cs`, we need to add several things. They are:

In `ConfigureServices`

1. Add MVC to our app by adding the service `AddControllersWithViews`
2. Add the `MiniProfilerQueryLogger` service
3. Add the `MiniProfiler` itself to the our services.

In `Configure`

1. Add to our app builder `useMiniProfiler`

Here is our final `startup.cs`.

```csharp
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace logging
{
    public class Startup
    {
        public void ConfigureServices
           (IServiceCollection services)
        {
            services.AddControllersWithViews();
            services
                .AddRouting()
                .AddGraphQLServer()
                .AddQueryType<Query>()
                .AddDiagnosticEventListener(sp =>
                    new ConsoleQueryLogger
                        (sp.GetApplicationService
                           <ILogger<ConsoleQueryLogger>>()))
                .AddDiagnosticEventListener(sp =>
                    new MiniProfilerQueryLogger());
            services.AddMiniProfiler(options =>
                { options.RouteBasePath = "/profiler"; });
        }

        public void Configure(IApplicationBuilder app,
            IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseMiniProfiler();
            app.UseEndpoints(endpoints =>
              { endpoints.MapGraphQL(); });
        }
    }
}
```

That's it! Now, when you run your app and do some GraphQL queries, you can browse to the URL <u>http://localhost:5000/profiler/index-results</u> and that will give you a list of all your GraphQL requests. You can drill down on any request and see both the query itself, as well as any variables passed in with the associated value and type.

Just a side note. You can run both the console logger and the MiniProfiler at the same time and both logs will work as adding listeners is additive.

# Possibilities For Logging SQL and Entity Framework

It's worth mentioning that <a href="https://miniprofiler.com" target="_blank">MiniProfiler</a> has been around for a long time and there are many configuring profiles available including ones for <a href="https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ado-net-overview" target="_blank">ADO.NET</a> as well as <a href="https://docs.microsoft.com/en-us/ef/" target="_blank">Entity Framework Core</a>.

If you've gotten everything working, it's trivial to add Entity Framework support so that inside your GraphQL requests, you can see the actual SQL sent to the server and the associated timing. Literally, all you have to do is install one `nuget` package

```bash
dotnet add package MiniProfiler.EntityFrameworkCore
```

And, in your `startup.cs`, change the line that adds MiniProfile as follows:

```csharp
services.AddMiniProfiler
   (options =>
      { options.RouteBasePath = "/profiler"; })
         .AddEntityFramework();
```

Then, when you execute a GraphQL query that uses Entity Framework Core, you'll get results like the following. Notice that not only do you get the GraphQL query with it's variables, but also, you get all the SQL generated by Entity Framework that's run on that Query's behalf. Also notice the timing, you can see the time for the GraphQL query as well as the time for just the SQL.

![MiniProfiler Detail Web Page](MiniProfiler-Detail-EF-640.png)

# Wrap

Once you have logging enabled in your Hot Chocolate GraphQL server, you'll wonder how you ever worked without it. It's easy to setup and does not get in the way at all while you're building your apps.

Stay Safe.
]]></content>
        <author>
            <name>Peter Kellner</name>
            <uri>https://peterkellner.net</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Welcome Hot Chocolate 11]]></title>
        <id>https://chillicream.com/blog/2020/11/23/hot-chocolate-11</id>
        <link href="https://chillicream.com/blog/2020/11/23/hot-chocolate-11"/>
        <updated>2020-11-23T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we are releasing Hot Chocolate server 11. We started work on this version about 1 1/2 years ago. We occasionally took a break from this project to create another 10.x version and deliver new features to the stable branch. From a user perspective, we have provided a new feature version every two months. For the core team, it was quite an intense time creating this new server and, at the same time, looking at the old version to keep it current.

With Hot Chocolate 11, we are now fully embracing .NET 5 while still supporting older .NET platforms. If you opt into .NET 5, you will get a much more refined experience to express a GraphQL schema in entirely different ways.

Records are now fully supported and let you create full GraphQL types with a single line of code. I personally like to use records for input types when using the pure code-first (annotation based) approach.

```csharp
public record AddSessionInput(string Title, string SpeakerId);
```

We reworked Hot Chocolate also to accept attributes on the parameters when using the short-hand syntax.

```csharp
public record AddSessionInput(string Title, [ID(nameof(Speaker))] string SpeakerId);
```

This allows you to write very slim input types and get rid of a lot of boilerplate code.

We have also started exploring how we can use source generators to make Hot Chocolate faster and reduce boilerplate even further. You will see this trickling in with the next dot releases.

# New Configuration API

While .NET 5 support is nice, the most significant change from an API perspective is the new configuration API, which now brings together all the different builders to set up a GraphQL server. This makes the server configuration now very accessible and straightforward to use.

```csharp
services
    .AddGraphQLServer()
    .AddQueryType<Query>();
```

The builder API lets you chain in new extension methods that can add new capabilities without the need to change the actual builder API. The builder interface is nothing more than a named access to the service collection, which lets you add named configurations to the DI that are consecutively used to create a GraphQL server.

```csharp
public interface IRequestExecutorBuilder
{
    /// <summary>
    /// Gets the name of the schema.
    /// </summary>
    NameString Name { get; }

    /// <summary>
    /// Gets the application services.
    /// </summary>
    IServiceCollection Services { get; }
}
```

Significant here is our switch to allow multiple named schemas that can be hot-reloaded during runtime. This allows us to improve a lot of workloads like schema stitching. But we will have more on that later.

With the new configuration API, you now can chain in various configurations without the need to remember where these things were hidden.

```csharp
services
    .AddGraphQLServer()
    .AddQueryType(d => d.Name("Query"))
        .AddType<AttendeeQueries>()
        .AddType<SessionQueries>()
        .AddType<SpeakerQueries>()
        .AddType<TrackQueries>()
    .AddMutationType(d => d.Name("Mutation"))
        .AddType<AttendeeMutations>()
        .AddType<SessionMutations>()
        .AddType<SpeakerMutations>()
        .AddType<TrackMutations>()
    .AddSubscriptionType(d => d.Name("Subscription"))
        .AddType<AttendeeSubscriptions>()
        .AddType<SessionSubscriptions>()
    .AddType<AttendeeType>()
    .AddType<SessionType>()
    .AddType<SpeakerType>()
    .AddType<TrackType>()
    .AddFiltering()
    .AddSorting()
    .AddProjections()
    .EnableRelaySupport()
    .AddDataLoader<AttendeeByIdDataLoader>()
    .AddDataLoader<SessionByIdDataLoader>()
    .AddDataLoader<SpeakerByIdDataLoader>()
    .AddDataLoader<TrackByIdDataLoader>()
    .EnsureDatabaseIsCreated()
    .AddInMemorySubscriptions()
    .AddFileSystemQueryStorage("./persisted_queries")
    .UsePersistedQueryPipeline();
```

With the new configuration API, we also reworked the ASP.NET Core integration to use the endpoints API. It now is effortless to apply the Hot Chocolate server to a routing configuration.

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseWebSockets();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGraphQL();
    });
}
```

With the new middleware, we dropped support for Playground and GraphiQL and have added our own GraphQL IDE Banana Cake Pop, which will be automatically added to a GraphQL route.

![Banana Cake Pop](banana-cake-pop.png)

To configure Banana Cake Pop or other middleware settings, you can chain in the server options with the GraphQLEndpointConventionBuilder.

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseWebSockets();
    app.UseRouting();

    app.UseEndpoints(
        e => e.MapGraphQL().WithOptions(
            new GraphQLServerOptions
            {
                Tool = { Enable = false }
            }));
}
```

# Execution Engine

While the new Configuration API is the first change, you will notice we changed a whole lot more underneath. One of the most significant investments we made was into our new execution engine. The new execution engine uses a new operation optimizer component to create execution plans and optimize executing requests. The first request now is a little slower since we need to essentially compile a query and then execute it. All consecutive requests can now simply execute and no longer need to interpret things like skip, include, defer, and other things.

With the new execution engine, we also introduced a new batching mechanism that is now much more efficient and abstracts the batching mechanism from DataLoader, meaning you can write your own batching functionality and integrate it. The stitching layer, for instance, does this to batch requests to the downstream services.

Apart from this, the new DataLoader API now follows the DataLoader spec version 2 and lets you inject the batch scheduler into the DataLoader. This makes it now easy to use Green Donut in your business logic. The beauty of this is that you do not need to expose any GraphQL libraries into your business layer and are able to layer your application nicely.

We also rewrote the validation layer for Hot Chocolate to make it much more correct and much faster on execution. To make the query validation more correct and ensure quality, we have ported all the `graphql-js` tests regarding validation to Hot Chocolate. While porting and integrating these tests, we found countless little issues with our implementation of field merging, for instance.

So, what do we mean with much faster execution? We put a lot of effort into reducing our memory footprint to execute more in parallel.

Let's have a look at how Hot Chocolate 11 compares to GraphQL .NET Server 4.3.1.

| Server           | Benchmark                  |    Time |  Allocated |
| ---------------- | -------------------------- | ------: | ---------: |
| Hot Chocolate 11 | Three Fields               |   11.94 |    7.49 KB |
| GraphQL .NET     | Three Fields               |   46.36 |   30.59 KB |
| Hot Chocolate 11 | Small Query with Fragments |   43.32 |   13.64 KB |
| GraphQL .NET     | Small Query with Fragments |  138.56 |  135.41 KB |
| Hot Chocolate 11 | Introspection              |  750.96 |  392.31 KB |
| GraphQL .NET     | Introspection              | 2277.24 | 2267.26 KB |

Hot Chocolate 11 uses a lot less memory and, on top of that, uses a lot less time to execute queries. But we also looked at other GraphQL servers and added Hot Chocolate to a variety of benchmarks.

For instance, we ran tests against the Apollo GraphQL server and other nodejs GraphQL servers.

| Server                     | Requests / second |
| -------------------------- | ----------------: |
| Hot Chocolate 11           |           19983.2 |
| graphyne                   |           17918.4 |
| express-gql                |            5931.4 |
| apollo-fastify-graphql-jit |            4046.2 |
| apollo                     |            2697.1 |

In our throughput tests, we can see that Hot Chocolate outperforms any node-based GraphQL server. Hot Chocolate is optimized for parallel requests meaning the more CPU cores your system has, the better Hot Chocolate server performs. This also means that if you have, for instance, only one CPU core graphyne will actually perform better. But even with less parallelization, Hot Chocolate turns up in the top three ahead of Express GraphQL and Apollo GraphQL.

This said, we are not done on performance and pulled the two biggest performance features on the execution side since we could not get them done in time for the 11 release. We already have seen huge potential in improving the overall performance of the server by using source generators. Source generators let us move a lot of the logic into the build process instead of executing resolver compilation at runtime. Also, we pulled a lot of our execution plan optimizers that would rewrite the execution tree to optimize data fetching. These performance improvements will trickle in with the next dot releases and should push Hot Chocolate further.

# Relay

We have invested a lot of time to make it even easier to create relay schemas. One of the things I often found cumbersome was to create entities that implemented the node interface. With Hot Chocolate 10.5, you could not do that with pure code-first (annotation based) and always needed to use code-first with the fluent API or schema-first. This now has changed, and it is much easier to write relay compliant schemas with any schema definition approach.

To write an entity that implements the node interface, you can now just put everything into one class.

```csharp
[Node]
public class Person
{
    public int Id { get; set; }

    public string Name { get; set; }

    public static async Task<Person> GetPersonAsync(MyDbContext context, int id)
    {
        // ...
    }
}
```

We often want to have the node resolver logic in a separate class that only deals with fetching the entity by ID. Or even have multiple node resolvers co-located in the same class. This can be done by specifying the node resolver type on the node attribute.

```csharp
[Node(NodeResolverType = typeof(IPersonResolver))]
public class Person
{
    public int Id { get; set; }

    public string Name { get; set; }
}
```

There are more variations and options possible to define a node type; the essence here is that it has become more natural.

# Draft Specification

As always, we try to implement draft specifications early, and we added a couple more draft spec features with Hot Chocolate 11.

## Allow interfaces to implement other interfaces

[GraphQL Spec PR 373](https://github.com/graphql/graphql-spec/pull/373)

One thing that users often requested is that interfaces could implement interfaces. With GraphQL until now, this was not possible. With the new GraphQL draft spec, we now have this capability, and we have optimized Hot Chocolate to make it very simple to apply.

The GraphQL spec states that you have to reimplement an interface on every level. This decision was made to optimize the GraphQL SDL for readability, and further show the impact of changes to an interface.

We will help you that this does not feel cumbersome and automatically add the missing re-implementations with code-first.

```csharp
public interface INode
{
    string Id { get; }
}

public interface IPerson : INode
{
    string Name { get; }
}

public class Person : IPerson
{
    public string Id { get; }

    public string Name { get; }
}

public class Query
{
    public IPerson GetPerson() => new Person();
}

services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddInterfaceType<INode>()
```

This schema will translate to the following GraphQL SDL.

```sdl
schema {
  query: Query
}

interface INode {
  id: String
}

interface IPerson implements INode {
  id: String
  name: String
}

type Person implements IPerson & INode {
  id: String
  name: String
}

type Query {
  person: IPerson
}
```

## Custom Scalar Specification URLs

[GraphQL Spec PR 649](https://github.com/graphql/graphql-spec/pull/649)

Another feature that we think will make tooling better over time is the ability to state the scalar specification. Andi Marek from graphql-java has created a new scalar specification website that, at the moment, only hosts one scalar specification for `DateTime`. Hopefully, this will grow over time. Scalars that have a specification can point to a URL of a human-readable spec. This will allow tooling to use the spec URLs as identifiers and apply then IntelliSense or other means of validation to a GraphQL IDE.

When you implement a scalar type, you can now pass on this `specifiedBy` URL.

```csharp
public class MyScalar : ScalarType
{
    public MyScalar()
        : base("MyScalar")
    {
        SpecifiedBy = new Uri("URL");
    }

    // ...
}
```

## Defer and Stream

[GraphQL Spec PR 742](https://github.com/graphql/graphql-spec/pull/742)

We also invested a lot of time in a very early feature called defer and stream. Defer, and stream allow you to de-prioritize parts of your request. This means that you essentially can tell the server to give you all the data in one go, but you mark the data that can arrive a little later.

```graphql
{
  sessions {
    nodes {
      title
      abstract
      startTime
      endTime
      ... @defer {
        speakers {
          name
        }
      }
    }
  }
}
```

Hot Chocolate Server 11 supports defer. This feature is experimental since the spec still changes, and we will keep it up to date. We have not yet included stream, which will follow with 11.1, probably at the end of January. You do not need to specify anything in your server to use defer; it will just work. You can try out defer with Banana Cake Pop, which will show you exactly how the patches come in.

![Banana Cake Pop](banana-cake-pop-defer.png)

# Data Integration

I know a lot of you love the data integration API, aka filtering. We completely reinvented this API and created a new package called `HotChocolate.Data`. This new package contains the base for automatic database mapping, filtering, sorting, and projections.

We actually started out in 11 to make the filtering introduced in version 10 better. But people soon chimed in and wanted to do more and wanted to **NOT** be dependant on `IQueryable`. So we create a new API that lets you fully control how filters, sorting, and projections are handled. You can integrate new providers like NeoJ4, MongoDB, or even spatial filter
support.

```csharp
public static class FilterConventionDescriptorMongoDbExtensions
{
    public static IFilterConventionDescriptor UseMongoDbProvider(
        this IFilterConventionDescriptor descriptor) =>
        descriptor.Provider(new MongoDbFilterProvider(x => x.AddDefaultMongoHandler()));

    public static IFilterProviderDescriptor<MongoDbFilterVisitorContext> AddDefaultMongoHandler(
        this IFilterProviderDescriptor<MongoDbFilterVisitorContext> descriptor)
    {
        descriptor.AddFieldHandler<MongoDbEqualsOperationHandler>();
        descriptor.AddFieldHandler<MongoDbNotEqualsOperationHandler>();

        descriptor.AddFieldHandler<MongoDbInOperationHandler>();
        descriptor.AddFieldHandler<MongoDbNotInOperationHandler>();

        // shortened for brevity

        return descriptor;
    }
}
```

What does this actually mean?

We have ported the old filtering to 11, so you can use that and essentially have no breaking change. We are no longer developing this any further and are also no longer investing in this component's bug fixing.

This means that you essentially will need to upgrade to the new `HotChocolate.Data` package. The issue with that is that your graph filter structure will change. Meaning a breaking change to your schema. You can, however, upgrade slowly and use both APIs side by side.

You can read more about the journey on our data integration API in Pascal's blog post [here](/blog/2020/11/18/new-filtering-api).

## Entity Framework

We know that many of you love Entity Framework and that it was quite painful to use Entity Framework with Hot Chocolate. We refined usage of Entity Framework with 10.5 but had to use internal APIs of EF to make it efficient. Hot Chocolate 11 introduces a new package `HotChocolate.Data.EntityFramework`, which integrates seamlessly with the data integration API.

We have a great example with Entity Framework right here:

[GraphQL Workshop](https://github.com/ChilliCream/graphql-workshop)

## Spatial Filtering

Apart from the refactoring of the data integration API, we introduced our new GeoJSON based spatial types. These spatial types are not just simple types but can also be used to add spatial filter capabilities to our data integration API.

```graphql
{
  pubs(
    where: {
      location: { within: { geometry: { type: Point, coordinates: [1, 1] } } }
    }
  ) {
    id
    name
    location
  }
}
```

Which translates to:

```sql
 SELECT c."Id", c."Name", c."Area"
 FROM "Counties" AS c
 WHERE ST_Within(c."Area", @__p_0)
```

The spatial filters use-case has driven us to reinvent the data integration API in the first place. This now very easily allows you to expose complex spatial filters to your GraphQL consumers.

Let me thank Steve and Pascal for all their work on this feature.

However, we are still developing spatial further, and this feature essentially is still experimental. Meaning, it might change in the next dot releases.

## Support for more providers

We are currently working on more providers for the data integration API like MongoDB native, Neo4J, and Elastic Search, which we will drop with the next dot releases.

The furthest along is our new MongoDB integration. Of course, MongoDB works already through `IQueryable`, but with `IQueryable` performance is sometimes an issue since the translation from `IQueryable` to the native Mongo query is not optimal in all cases. With the new Mongo provider, we use the BSON API to craft a native query that you can also intercept and further modify before it is sent to the database.

We expect to release the MongoDB provider with 11.1 in January.

# Schema Stitching

Schema got a nice upgrade for version 11, although a lot of features were moved to 11.1. We originally wanted to redo the whole stitching execution on top of the new execution engine. In the end, we essentially moved the old stitching engine on top of the new execution engine and integrated the old stitching engine into the new configuration API. This alone already will give you a big upgrade in functionality and usability.

The first thing to note with schema stitching is that it completely integrates with a standard schema. No more is there a separate stitching builder that makes it challenging to add customizations.

```graphql
services
    .AddGraphQLServer()
    .AddQueryType(d => d.Name("Query"))
    .AddRemoteSchema(Accounts)
    .AddRemoteSchema(Inventory)
    .AddRemoteSchema(Products)
    .AddRemoteSchema(Reviews);
```

Essentially now you just merge in types into your schema from anywhere, and you are still able to create local types that are merged with remote types. This gives a lot of control and flexibility to you. With that, any schema could also be a gateway.

```graphql
services
    .AddGraphQLServer()
    // adds a local query type
    .AddQueryType<Query>()
    // and merges that with the incoming schemas
    .AddRemoteSchema(Accounts)
    .AddRemoteSchema(Inventory)
    .AddRemoteSchema(Products)
    .AddRemoteSchema(Reviews);
```

## Federated Schemas

I mentioned in the beginning that we can now hot-reload schemas, which we designed specifically for schema stitching so that you could distribute the schema configuration and use a federated approach to schema stitching.

While there are various ways now to do federated schemas, we internally use one backed by Redis. Essentially, a downstream service can push to the gateway its local configuration, and the gateway will start phasing out the old schema and phasing in the new schema without any disruption every time a configuration changes.

The gateway will further store schema configurations on Redis so that even if there are downstream services offline, we can always create a schema, and only on execution might there be errors for affected parts of the schema. This really makes a federated schema more resilient.

```csharp
services
    .AddGraphQLServer()
    .AddQueryType(d => d.Name("Query"))
    .AddRemoteSchemasFromRedis("Demo", sp => sp.GetRequiredService<ConnectionMultiplexer>());
```

We have created some examples that show the various ways to set up schema stitching, which can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/Stitching).

But as I said in the beginning, there is a lot more coming with the next dot updates. Like GraphQL over gRPC to improve efficiency between the gateway and the downstream services. Moreover, we are bringing in subscription stitching and full integration with the new execution engine. Furthermore, we will introduce a new fetch directive that will bring much more flexibility to integrating GraphQL schemas and other data sources.

# Extensibility

With Hot Chocolate 11, we have invested in adding extensibility points, where our customers and partners who want to extend Hot Chocolate can do so easily and safely. When customizations are created, the creator can be assured that the integrity of Hot Chocolate will be maintained in the future and those extensions will continue to work as designed through minor and major releases of Hot Chocolate. Our existing extensions, `HotChocolate.Data` and `HotChocolate.Stitching` already take advantage of this new extensibility feature.

We essentially created a new interception API that can hook into the type initialization to completely rewrite an inferred schema. It can create new types when it finds an attribute or branch of types and essentially creates versions of the same graph. It gives you a powerful API that visits each type during its various initialization stages and lets you change the APIs.

Also, it allows you to modify the underlying type definitions rather than being constrained by the fluent API. These extension APIs are not meant for the standard developer creating a schema but for people who want to write powerful, reusable components like `HotChocolate.Data`. We also rewrote a lot of our core components to use this new API, like the introspection.

```csharp
server
    .AddGraphQLServer()
    ...
    .AddTypeInterceptor<IntrospectionTypeInterceptor>();

internal sealed class IntrospectionTypeInterceptor : TypeInterceptor
{
    public override void OnBeforeCompleteType(
        ITypeCompletionContext completionContext,
        DefinitionBase definition,
        IDictionary<string, object> contextData)
    {
        if (definition is ObjectTypeDefinition objectTypeDefinition)
        {
            var position = 0;
            IDescriptorContext context = completionContext.DescriptorContext;

            if (completionContext.IsQueryType ?? false)
            {
                objectTypeDefinition.Fields.Insert(position++, CreateSchemaField(context));
                objectTypeDefinition.Fields.Insert(position++, CreateTypeField(context));
            }

            objectTypeDefinition.Fields.Insert(position, CreateTypeNameField(context));
        }
    }
}
```

We will soon have a follow-up post on writing extensions for Hot Chocolate to drill into what you can do.

# Strawberry Shake

The one thing missing from this launch is Strawberry Shake, our GraphQL client. We decided in August to pause development for Strawberry Shake in order to focus on the server. Many features in Strawberry Shake depended on Hot Chocolate to bring in new features like defer that really will make Strawberry Shake shine. With this decision, we were able to focus on the server and make it great. We essentially broke the 11 development into two parts. We will start next week to put resources again behind Strawberry Shake and hope to get it done by the end of January.

# General Outlook

Where are we going from here? We now essentially are a team of four people, Rafael, Pascal, Fred, and myself. We plan to start focusing for the next three months on three components.

Strawberry Shake will become Fred's and my immediate focus, so expect our GraphQL client to get real attention and expect it to get the same attention for detail that made Hot Chocolate your beloved GraphQL server. We think that the client space at the moment does not exist in .NET, and we want to change that. There are a lot of opportunities to bring something unique. We have done a lot of research into things like Relay and Apollo client and think that we can reinvent how you interact with data in Xamarin and Blazor applications.

Apart from Strawberry Shake, we will start moving in the missing schema stitching features. The new stitching engine can not only do subscription stitching but also is able to merge the Hot Chocolate stitching approach with the Apollo Federation approach. You will be able to have Apollo Federation protocol downstream services as well as Hot Chocolate Stitching protocol downstream servers. The gateway can mix and match them, not forcing you to choose. As you have seen with the general execution engine, stitching will become very fast, and we will publish benchmarks soon.

In general, expect a lot more performance improvements to trickle in over the next dot releases.

These changes are more iterative, where we complete components and get better. We will also start on a new component that will become a big leap for the whole platform. Rafael and Pascal will focus on this new chapter of ChilliCream and we will start talking about this soon.

# Community

The great thing about Hot Chocolate is the people. Every day, I think the best thing we did was to create this slack channel where anybody could join. The slack channel has become the space where the community can congregate and help each other find a solution to a problem.

We internally talked about this great family and how to push this further and help this community grow. We will soon start with our ChilliCream user group, where users from the community can present solutions to their issues or present components that they have build around Hot Chocolate. But we think that we will even go beyond that and ask people from the greater GraphQL community to talk to us and give us fresh ideas and new takes on GraphQL.

Last but not least, let me invite you to our launch party on Wednesday and celebrate with us this amazing community and the next chapter of Hot Chocolate.

[Hot Chocolate 11 Launch Party](https://www.meetup.com/ChilliCream-User-Group/events/274656703/)
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[The new Filtering API]]></title>
        <id>https://chillicream.com/blog/2020/11/18/new-filtering-api</id>
        <link href="https://chillicream.com/blog/2020/11/18/new-filtering-api"/>
        <updated>2020-11-18T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
With version 11, we release a complete rewrite of filtering, sorting, and selections. With our initial release a few versions back, we decided to use a similar syntax as Prisma did. Initially, this looked like a very intuitive way of declaring filters. We already shipped some extensions in preview releases of version 11, like object filters, list filters, etc.

We started investigating into opening up the API for users who want to provide their filters or write their database providers for Hot Chocolate. Quickly we realized that the API was not good enough for a public release and, even worse, the underlying GraphQL syntax was not ideal to use.

This was a huge setback for us, but we still went back to the drawing board and made a complete redesign of it. We looked at many different implementations of similar features, and combined with the experience we made; we settled on a similar approach to Hasura or Postgraphile.

The main issue with the filters released with version 10 is the strict binding of field and operation. The discussion and a detailed description of the problem we faced can be followed in this [Issue on GitHub](https://github.com/ChilliCream/graphql-platform/issues/2044)

Here is a quick summary:

This approach works great with scalar filters.

```graphql
where: {
    foo_contains: “bar”
}
```

We bundled the field and the operation together into an easy to understand and straight forward GraphQL field.

Object filters would add another level of nesting:

```graphql
where: {
    foo: {
        bar_contains:”bar”
    }
}
```

For array filters, we came up with a mixture of nesting and bundling. With list filters, the problems already begin to start. It is already required to have helper (`el_XXX`) syntax to access the elements of a list:

```graphql
where: {
    foo_some: {
        el_gt:4
    }
}
```

As soon as we dived deeper into possible extensions, the problems became more severe, and the API became more inconsistent. A good example of this issue is when we want to filter by the length of a string. We could filter by `foo_length_gt:4` or `foo_length: { is_gt: 4}` or even `foo: { length: { is_gt:4 } }`. All of these approaches would follow the style guide. The first would be like we define filters for the field, the second similar to the list filters, and the last one would be like the object filters.

# The New Filtering

With the new filtering API, there is a fundamental change. Operations and fields are no longer bundled together into one GraphQL field.

Here is a quick overview of the examples listed above:

Scalar filters:

```graphql
where: {
    foo: {
        contains: “bar”
    }
}
```

Object filters:

```graphql
where: {
    foo: {
        bar {
            contains: “bar”
        }
    }
}
```

List filters:

```graphql
where: {
    foo: {
        some: {
            gt: 4
        }
    }
}
```

As the API now is based on nesting, every combination of field and operation feels a lot more natural. When you like to filter by the length of a string, the resulting API looks seamless:

```graphql
where: {
    foo: {
        length: {
            gt: 4
        }
    }
}
```

# THIS IS BREAKING MY API!

We know. We had a long discussion about this. We feel confident that this new approach is the right way to go, and it is designed to stay. The 10.X.X filters are still available in version 11. They will be deprecated, though, and will be removed in version 12.

# The Data Package

With version 11, we introduce a new package for Hot Chocolate. We created a new package called `HotChocolate.Data`. This package contains `HotChocolate.Data.Filtering`, `HotChocolate.Data.Sorting` and `HotChocolate.Data.Projections`.

# Migrating from 10 to 11

We could not avoid conflicts in type names between the old and the new filtering. You can use static imports or fully qualified type names to have the old and the new filtering API in the same file.

If you have full control over the front end, the easiest way to migrate is to replace the old filtering with the new one and make the necessary changes.

If this is not an option for you, you will have to declare new fields and deprecate the old ones once they are no longer used. You may even use the filters on the same fields, but you will end up with conflicting argument names.

# Getting started

You first need to add the new `HotChocolate.Data` package to the project.

It is also required to register filtering on the schema builder:

```csharp
public void ConfigureServices(IServiceCollection services) {
    services.AddGraphQLServer()
        .AddQueryType<Query>()
        .AddFiltering();
}
```

You are now all set and ready to use the filters. For a pure code first approach, you can use the attribute `[UseFiltering]`, and for code first, you can use the `UseFiltering()` extension method.

```csharp
// pure code first
public class Query {
    [UseFiltering]
    public IQueryable<Foo> Foos([Service]DbContext context) => context.Foos;
}

//code first
public class Query : ObjectType {
    protected override void Configure(IObjectTypeDescriptor descriptor) {
        descriptor
            .Field<Resolver>(x => x.Foos(default!))
            .UseFiltering();
    }

    public class Resolver {
        public IQueryable<Foo> Foos([Service]DbContext context) => context.Foos;
    }
}
```

# How does it work?

The old filtering was bundling a field and operation together. With the new filtering, this is now separated. The concept of field and operation still exists, though a little different. A field is always used for navigation. You can think of it as a selector. In code first, a field represents a property of a class. An operation is always an action in the context of a field. Semantically you can look at it as a function. This is often a compare operation, like equals or greater than, but it can also be more arbitrary. In spatial data, many functions can be translated to database queries, like `ConvexHull()` or `Distance(Geometry g)`. Filtering on spatial data is something we plan to support soon. Operations are identified by an integer, which is called the operation ID.

In most cases, a filter type either only contains fields or only operations, but it is in no way restricted to that. A filter type can contain both. This can be useful to provide the necessary metadata. Let's continue the example `Distance(Geometry g)` from above. This function has a parameter `g`. To calculate the distance between two points, the consumer needs to provide one point. The function then returns the distance between these two points. In GraphQL, this now can be combined into one input type:

```graphql
input HouseFilterInput {
    position: PointFilterInput
}

input PointFilterInput {
    distanceTo: DistanceToFilterInput;
}

input DistanceToFilterInput {
    """The other point where the distance is calculated to"""
    other: GeometryFilterInput!
    eq: Float
    neq: Float
    gt: Float
    ....
}
```

The new version of filtering does not only have a new look and feel at the API level but also comes with lots of changes to the Hot Chocolate core. The data package is now completely separated from the core, and no internal APIs are used. Like most of the things in Hot Chocolate, filtering can roughly be broken down into two parts. Schema building and execution. Something we focused on is the new conventions. The goal was to make it easier for users to extend the capabilities of filtering. It is now a lot easier to create custom filters and providers to add new functionality. Both schema building and execution are configurable with conventions.

# Schema Building

Filtering has dedicated input types. `FilterInputType` and `FilterInputType<T>` are extensions of the normal `InputObjectType`. Both filter input types have a similar interface to the normal input type. In addition to `Name`, `Description`, `Directive`, there are a couple of specific descriptors to describe filter capabilities. You can specify fields and operations. There is also `AllowOr` and `AllowAnd`. These two add the special fields needed for these operations. The `FilterInputType` uses the convention for naming and inference of properties. Like the scalar registration on the schema builder, operation types can be bound on the filter convention.

# Execution

To map an incoming GraphQL filter query to the database, Hot Chocolate needs to know how to handle fields and operations. We initially started by having a lookup table. The filter middleware would access this lookup table and search for a matching handler. Since we did a lot of unnecessary work on runtime, we redesigned this to do more of this work at configuration time. During schema initialization, we annotate the matching handler directly from the convention onto the field. For this, we use a new concept call type interceptors. This comes with a few benefits. Firstly, we know during schema creation if all required handlers are registered. In case we do not find a matching handler, we can now fail early and tell the developer what is missing. Secondly, we do not have to do runtime lookups. All handlers are now directly stored on the fields and are available on visitation. We introduced a new concept called type scoping to use more than one filter convention, e.g., MongoDB and SqlServer.

## Type Interceptor

Type interceptors are one of the new shiny features of version 11. To create an interceptor, you have to extend the class `TypeInterceptor` and register it on the schema builder. You can hook into the schema initialization process and make changes across all types or even introduce new once while rewriting the schema. Countless new possibilities come with these new type interceptors. As an example, use-case, we looked at feature flags. Feature flags can be useful in services that are tenant-based. You may want to hide parts of an API for a specific tenant.

The simplest example might be the following one:

> You have an API with two endpoints. One endpoint is for all users of the website (/graphql). The other endpoint is only accessible by administrators (/admin/graphql). The structure of the APIs is the same, the administrators just have access to more fields and mutations.

In previous versions, you would have to create two separate type hierarchies with different types. One for normal users and one for administrators. This would bloat the codebase a lot. With type interceptors and [the new schema creation api](/blog/2020/07/16/version-11#configuration-api) this is a lot cleaner.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddGraphQLServer()
            .AddQueryType<Query>()
            .AddTypeInterceptor<RemoveAdminFieldInterceptor>()
        .AddGraphQLServer("admin")
            .AddQueryType<Query>();
}
```

```csharp
public class RemoveAdminFieldInterceptor : TypeInterceptor
{
    public override void OnAfterInitialize(
        ITypeDiscoveryContext discoveryContext,
        DefinitionBase definition,
        IDictionary<string, object> contextData)
    {

        if (definition is ObjectTypeDefinition def)
        {
            var fields = (IList<ObjectFieldDefinition>)def.Fields;
            for (var i = fields.Count; i > 0; i--)
            {
                if (fields[i].ContextData.ContainsKey("admin"))
                {
                    fields.RemoveAt(i);
                }
            }
        }
    }
}

public static class ObjectFieldDescriptorExtensions
{
    public static IObjectFieldDescriptor IsAdmin(this IObjectFieldDescriptor descriptor)
    {
        descriptor.Directive("IsAdmin");
        return descriptor;
    }
}

public class ExampleObjectType : ObjectType<Foo> {
    protected override void Configure(IObjectTypeDescriptor<Foo> descriptor){
        descriptor.Field(x => x.AvailableForAll);
        descriptor.Field(x => x.OnlyForAdmins).IsAdmin();
    }
}
```

## Scoping

With this release, we introduce a concept called schema scoping. As we write handlers from the convention directly on to the fields, we would limit filtering to just one convention. In case we need two conventions we need two fields and therefore two different types. Schema scoping makes it possible to branch of a type hierarchy and create multiple types from the same definition and then later even join the two branches back together. This feature works on the type reference level. Type references now have a scope that can change the type reference identity.
Scoping only really makes sense in combination with a type interceptor. This interceptor picks up a scoped type and then scopes all its dependencies. The type interceptor also has to rename scoped types to avoid name collisions.
Filtering does the same. In case there is only one filter convention registered, you will not see a difference. As soon as you have multiple conventions registered the name of the convention is added to the type name.

## Conventions

Conventions will be the configuration interface for extensions on top of the Hot Chocolate core. In version 11 the convention API has been extended. We introduce the named conventions in this release. This way multiple conventions of the same type can be registered on the Schema.
You may have a filter convention for MongoDB and a filter convention for SqlServer.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddGraphQLServer()
            .AddQueryType<Query>()
            // this will be the default convention as no name is specified
            .AddConvention<IFilterConvention, MongoFilterConvention>()
            .AddConvention<IFilterConvention, FilterConvention>("SqlServer")
            .AddFiltering();
}
```

You can configure the convention when you declare filtering.

```csharp
// pure code first
public class Query {
    [UseFiltering("SqlServer")]
    public IQueryable<Foo> Foos([Service]DbContext context) => context.Foos;
}

//code first
public class Query : ObjectType {
    protected override void Configure(IObjectTypeDescriptor descriptor) {
        descriptor
            .Field<Resolver>(x => x.Foos(default!))
            .UseFiltering("SqlServer");
    }

    public class Resolver {
        public IQueryable<Foo> Foos([Service]DbContext context) => context.Foos;
    }
}
```

## What's next?

The data package is designed for extensibility. There are a few extensions that we will work on. e.g. filtering for spatial data and a MongoDB provider.
We will as well invest time into documentation and have examples on how to create your own extensions.
There are too many databases to create providers for all of them out of the box. We encourage you, the community, to contribute the extensions you need.
If you are interested, reach out to us in slack in the #contributors channel. We will help you along!
]]></content>
        <author>
            <name>Pascal Senn</name>
            <uri>https://github.com/pascal_senn</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[What is up with 11]]></title>
        <id>https://chillicream.com/blog/2020/07/16/version-11</id>
        <link href="https://chillicream.com/blog/2020/07/16/version-11"/>
        <updated>2020-07-16T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
When we at ChilliCream talked the other day, we reflected on the progress on version 11, where we are at this point, and how we got there. We are now working for almost one year on version 11 and will probably need a couple more months to polish it and get all the features in. When talked about this, we reflected that the actual version 11 was perhaps the 10.3 release when all the pure code-first goodness came.

With version 11, we are re-envisioning what we want Hot Chocolate to be. How we want the API to feel and how extensibility works. We have looked at the things that are difficult for users to understand and made these better accessible. We also looked at how we can take things to the next level with a new execution engine that will support execution plans.

## Developer Preview

Today we are releasing a first developer preview of version 11 with our new configuration API. We call this a developer preview to make it clear that this should not be used in production. This preview is missing a lot of components included in version 10.x like filtering, schema stitching, and many others. As we go forward, we will slowly integrate these missing components and refine the new APIs further.

In order to get started with the developer preview first create a new ASP.NET Core project.

```bash
dotnet new web -n Demo
```

Next, add the ASP.NET Core server package.

```bash
cd Demo
dotnet add package HotChocolate.AspNetCore --version 11.0.0-dev.1
```

[Hot Chocolate - 11.0.0-dev.1](https://www.nuget.org/packages/HotChocolate.AspNetCore/11.0.0-dev.1)

## Configuration API

OK, after all these disclaimers, let us get into some code and talk features.

The first feature that I want to walk you through is the one that everybody will have to use to set up their GraphQL server, and it is also the first breaking change compared to version 11. When setting up a GraphQL server, we start with an ASP.NET Core web project. Our main configuration is located in the `Startup.cs`.

Before we look at how we do it, version 11, let us see how we usually would start in version 10.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddGraphQL(sp =>
        SchemaBuilder.New()
            .AddQueryType<Query>());
}
```

The code looks nice and simple. Also, the schema builder is a great API that lets us chain configuration. The main issue that we found with this or where we saw that people had problems was when schema stitching came into play or when you wanted to configure request services or change the execution pipeline and so on. Whenever it got a little more complicated, and we had to add more services and integrate other things that were not available on the `SchemaBuilder`, it got complicated. The pity here is also that the `SchemaBuilder` is difficult to extend. This means that components like schema stitching cannot easily add an extension method that brings new configuration functionality to the `SchemaBuilder`.

After long nights we came up with a new approach that brings everything together into one API that is very easy to extend.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddGraphQLServer()
            .AddQueryType<Query>();
}
```

This little example does not look so much different, but the new API can do a lot more.

First, when in a server context like ASP.NET Core or Azure Functions, we now have this new `AddGraphQLServer()` method that sets up a new schema and executor with additional services the server needs. This API also does not allow just one schema but multiple.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddGraphQLServer()
            .AddQueryType<Query>()
        .AddGraphQLServer("internal")
            .AddQueryType<Query>()
            .AddTypeExtension<InternalQueryExtension>();
}
```

The above code sets up two schemas. One is our default schema and adds a `Query` type. The other schema is called `internal` and adds the same `Query` type, and extends the `Query` type with some internal queries.

I can put each of these schemas on a different route and for that, we also now support Microsoft`s new routing API.

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGraphQL();
        endpoints.MapGraphQL("/internal", schemaName: "internal");
    });
}
```

The new configuration API, in combination with Microsoft`s new routing, makes it easy to map various schemas to various routes and secure and limit them as one pleases.

But there is even more to that. Since we also have some new schema stitching features in mind that will use the unique capabilities of this API. The new configuration API allows to hot reload schema configurations. Meaning you can push schema configurations to a running server. We will have more on this with the next few previews.

Another part that I mentioned is that we can more seamlessly configure a schema. If we wanted, for instance, to add apollo tracing support to our internal schema but not the default schema we can do that now with one line of code.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddGraphQLServer()
            .AddQueryType<Query>()
        .AddGraphQLServer("internal")
            .AddQueryType<Query>()
            .AddTypeExtension<InternalQueryExtension>()
            .AddApolloTracing();
}
```

Having configuration bound to specific schemas also means that the performance impact from components like apollo tracing effects only the schema it is applied to. We could also add this globally by adding apollo tracing to the service collection instead of the request builder. In this case, apollo tracing would be applied to all schemas.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddApolloTracing()
        .AddGraphQLServer()
            .AddQueryType<Query>()
        .AddGraphQLServer("internal")
            .AddQueryType<Query>()
            .AddTypeExtension<InternalQueryExtension>();
}
```

We are still bringing more APIs over to the new configuration API, and it will take us some time to have everything in here.

## Subscriptions

Another area that is now super simple to set up is subscriptions. To use in-memory subscriptions, we configure our schema like the following.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddGraphQLServer()
            .AddQueryType<Query>()
            .AddMutationType<Mutation>()
            .AddSubscriptionType<Subscription>()
            .AddInMemorySubscriptions();
}
```

Again, I can have in-memory subscriptions on one schema and Redis subscriptions on another.

Next, we need to define our `Mutation` type to trigger subscriptions whenever something happens on our schema.

```csharp
public class Mutation
{
    public string SendMessage(
        string userId
        string message,
        [Service] ITopicEventSender eventSender)
    {
        eventSender.SendAsync(userId, message);
        return message;
    }
}
```

In our example, we have a mutation that can send a text message to a user represented by the user API. To send a message to our subscription bus, we use the `userId` argument as a topic and the `message` argument as the payload of our subscription event. We also injected `ITopicEventSender`, which allows us to send events to our internal event stream. Events are topic-based, and a subscription can subscribe to a topic.

From a GraphQL standpoint, we would like to subscribe to a specific user to receive the messages for that user.

```graphql
subscription onMessage {
  onMessage(userId: "123");
}
```

This subscription will then pass down to us the message text for user `123` whenever the mutation is invoked with the userId `123`.

Let us have a look at how we would create our subscription type for that.

```csharp
public class Subscription
{
    [Subscribe]
    public string OnMessage(
        [Topic] string userId,
        [EventMessage] string message) =>
        message;
}
```

If you look at the code above you, do not see any specific code that subscribes to the event system itself. We added an argument `userId` and annotated it to be our topic. The topic argument tells our system what events we would like to receive. Next, we added another argument `message`, which we annotated as our event message or payload. The `message` argument is where the system shall inject us the payload of the events whenever our subscription resolver is invoked.

There are many more variants with the new subscriptions, but I will cover that in a later blog post that only looks at subscriptions and what we can do with them.

## Extensibility

One of our most significant investments was making the type system even more flexible to allow more complex features. We want to allow for very complex features to become fully transparent. Meaning, features like relay support should not dictate how you build your types. You should not need to handle id serialization or things like that. The system should understand your types and rewrite them into what you want them to be.

To this, there is an even better example. With version 11, we want to bring schema-first or SDL-first up to par with code-first. In SDL-first integrating paging is quite tedious at the moment, since you have to write all the paging and connection types and so forth. But if we could have a feature that can rewrite a schema, we could let people specify a schema like the following.

```sdl
type Query {
  users: [User] @paging
}

type User {
  # removed for brevity
}
```

The configuration would take this initial schema and rewrite it to the following schema that includes all those types necessary for relay pagination.

```sdl
type Query {
  users(first: Int, last: Int, after: String, before: String): [UserConnection]
}

type UserConnection {
  pageInfo: PageInfo
  edges: [User]
}

type PageInfo {
  # removed for brevity
}

type User {
  # removed for brevity
}
```

To allow cross-cutting features like this, we are now allowing to intercept type configurations and rewrite them.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddGraphQLServer("hello")
            .AddQueryType(d => d
                .Name("Query")
                .Field("hello")
                .Resolver("world"))
            .OnBeforeCompleteType<ObjectTypeDefinition>(
                (context, definition, contextData) =>
                {
                    if(definition.Name.Equals("Query"))
                    {
                        ObjectTypeDescriptor.From(context.DescriptorContext, definition)
                            .Field("foo")
                            .Type<StringType>()
                            .Resolver(resolverContext => "say hello");
                    }
                });
}
```

In the above example, I am intercepting the configuration of the `Query` type and add a simple foo field to it. This feature allows for so much more since you can write very sophisticated interceptors that scope types and branch them into separate type trees. We will rewrite and decouple a lot of our current features with this.

## Execution Engine

With this first dev preview, we are bringing the first part of our new execution engine in. It does not yet contain the execution plan bits but has a lot of the memory optimizations built-in. The execution engine now also is much easier to extend with features. All of the execution configurations are as-well backed into our new configuration API.

If I, for instance, wanted to use the persisted queries execution flow, I could do so by using the following configuration.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddGraphQLServer("hello")
            .AddQueryType(d => d
                .Name("Query")
                .Field("hello")
                .Resolver("world"))
            .UsePersistedQueryPipeline();
}
```

## Summary

There are a ton more features in this preview, so many really that it is to much to go into every one of them. Also, we have just begun to bring our various bits together and hope to integrate those now more quickly. Over the next weeks, we will share with every new preview more new features with you and will drill down more specifically into those. This first post is meant to kick things off. Give us feedback on how you like the feel of the new configuration API.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Get started with Hot Chocolate and Entity Framework]]></title>
        <id>https://chillicream.com/blog/2020/03/18/entity-framework</id>
        <link href="https://chillicream.com/blog/2020/03/18/entity-framework"/>
        <updated>2020-03-18T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
In this post I will walk you through how to build a GraphQL Server using Hot Chocolate and _Entity Framework_.

_Entity Framework_ is an OR-mapper from Microsoft that implements the unit-of-work pattern. This basically means that with _Entity Framework_ we work against a `DbContext` and once in a while commit changes aggregated on that context to the database by invoking `SaveChanges`.

With _Entity Framework_ we can write database queries with _LINQ_ and do not have to deal with _SQL_ directly. This means that we can compile our database queries and can detect query errors before we run our code.

## Introduction

This blog post is based on the Contoso University example application used by Microsoft to demonstrate the usage of _Entity Framework_ with ASP.NET Core.

In this blog post we will take that example and build with it a simple GraphQL server for the university website. With it, we can query students, courses, and instructor information.

Before we get started let us setup our server project.

```bash
mkdir ContosoUniversity
dotnet new web
```

Next wee need to add _Entity Framework_ to our project.

```bash
dotnet add package Microsoft.EntityFrameworkCore
```

Last but not least we are adding the SQLLite _Entity Framework_ provided in order to have a lightweight database.

```bash
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
```

For our data we have three models representing the student, the enrollments and the courses.

The student entity has some basic data about the student like the first name, the last name or the date when the student first enrolled into the university.

The enrollment entity represents the enrollment of a student to a specific course. The enrollment entity not only represents the relationship between the student and the course but also holds the Grade that a student achieved in that course.

Last but not least we have the course to which many students are enrolled to. The course has a title and a property defining the credit that a student can achieve in that course.

Let’s copy our models into our project.

```csharp
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity
{
    public class Student
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }

        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }

    public enum Grade
    {
        A, B, C, D, F
    }

    public class Enrollment
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int EnrollmentId { get; set; }
        public int CourseId { get; set; }
        public int StudentId { get; set; }
        public Grade? Grade { get; set; }

        public virtual Course Course { get; set; }
        public virtual Student Student { get; set; }
    }

    public class Course
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CourseId { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }

        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
}
```

For our models we do need a `DbContext` against which we can interact with our database.

```csharp
using Microsoft.EntityFrameworkCore;

namespace ContosoUniversity
{
    public class SchoolContext : DbContext
    {
        public DbSet<Student> Students { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Course> Courses { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlite("Data Source=uni.db");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>()
                .HasMany(t => t.Enrollments)
                .WithOne(t => t.Student)
                .HasForeignKey(t => t.StudentId);

            modelBuilder.Entity<Enrollment>()
                .HasIndex(t => new { t.StudentId, t.CourseId })
                .IsUnique();

            modelBuilder.Entity<Course>()
                .HasMany(t => t.Enrollments)
                .WithOne(t => t.Course)
                .HasForeignKey(t => t.CourseId);
        }
    }
}
```

The `SchoolContext` exposes access to our entities through `DbSet`. We can query a `DbSet<T>` with _LINQ_ or add new entities to it. Moreover, our `ShoolContext` has some configuration that defines the relations between our entities.

Copy the context as well to our project.

Next, we need to register our `SchoolContext` with the dependency injection so that our GraphQL server can request instances of it. For that lets open our `Startup.cs` and replace the `ConfigureServices` method with the following code.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SchoolContext>();
}
```

There is one last thing to finish up our preparations with the database and to get into GraphQL.

We somehow need to create our database. Since we are in this post only exploring how we can query data with entity framework and GraphQL we will also need to seed some data.

Add the following method to the `Startup.cs`:

```csharp
private static void InitializeDatabase(IApplicationBuilder app)
{
    using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
    {
        var context = serviceScope.ServiceProvider.GetRequiredService<SchoolContext>();
        if (context.Database.EnsureCreated())
        {
            var course = new Course { Credits = 10, Title = "Object Oriented Programming 1" };

            context.Enrollments.Add(new Enrollment
            {
                Course = course,
                Student = new Student { FirstMidName = "Rafael", LastName = "Foo", EnrollmentDate = DateTime.UtcNow }
            });
            context.Enrollments.Add(new Enrollment
            {
                Course = course,
                Student = new Student { FirstMidName = "Pascal", LastName = "Bar", EnrollmentDate = DateTime.UtcNow }
            });
            context.Enrollments.Add(new Enrollment
            {
                Course = course,
                Student = new Student { FirstMidName = "Michael", LastName = "Baz", EnrollmentDate = DateTime.UtcNow }
            });
            context.SaveChangesAsync();
        }
    }
}
```

`InitializeDatabase` ensures that our database is created and seeds some initial data so that we can do some queries.

Next call `InitializeDatabase` in the first line of the `Configure` method in the `Startup.cs`. The updated `Configure` method should look like the following:

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    InitializeDatabase(app);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}
```

We are basically done with our preparations. So far, we have defined our models, created our `ShoolContext` through which we can query the database. We also registered the `ShoolContext` with the dependency injection container and added some initialization logic so that our database is created with some initial data. With that settled let us move on and talk about GraphQL.

## GraphQL Schema

Everything in GraphQL resolves around a schema. The schema defines the types that are available and the data that our GraphQL server exposes.

In GraphQL we interact with the data through root types. In this post we will only query data which means that we only need to define the query root type.

The query root type exposes fields which are called root fields. The root fields define how we can query for data. For our university GraphQL server we want to be able to query the students and then drill deeper into what courses a student is enrolled to or what grade he/she has in a specific course.

Before we actually can put some GraphQL types in our project we again need to add some packages. This time we need to add the `HotChocolate.AspNetCore` package to enable the core GraphQL server functionality. Also we need the `HotChocolate.Types.Selections` package to be able to use _Entity Framework_ projections.

```bash
dotnet add package HotChocolate.AspNetCore
dotnet add package HotChocolate.Types.Selections
```

With Hot Chocolate and the _pure code-first_ approach the query root type is represented by a simple class. Public methods or public properties on that type are inferred as fields of our GraphQL type.

The following class:

```csharp
public class Query
{
    /// <summary>
    /// Gets all students.
    /// </summary>
    public IQueryable<Student> GetStudents() => throw new NotImplementedException();
}
```

Is translated to the following GraphQL type:

```graphql
type Query {
  """
  Gets all students
  """
  students: [Student]
}
```

> Hot Chocolate will apply GraphQL conventions to inferred types which will remove the verb `Get` for instance from the method or if it is an async method the postfix `async` will be removed. These conventions can be configured.

In GraphQL we call the method `GetStudents` a resolver since it resolves for us some data. Resolvers are executed independent from one another and each resolver has dependencies on different resources. Everything that a resolver needs can be injected as a method parameter. Our `GetStudents` resolver for instance needs the `ShoolContext` to fetch some data. By using argument injection the execution engine can better optimize how to execute a query.

OK, with this knowledge lets implement our `Query` class.

```csharp
public class Query
{
    /// <summary>
    /// Gets all students.
    /// </summary>
    public IQueryable<Student> GetStudents([Service]SchoolContext schoolContext) =>
        schoolContext.Students;
}
```

Our query class up there would already work. But only for the first level. It basically would resolve all students but we could not drill deeper. The enrollments would always be empty. In Hot Chocolate we have a concept of field middleware that can alter the execution pipeline of our field resolver.

The middleware order is important since multiple middleware form a field execution pipeline.

In our case we want _Entity Framework_ projections to work so that we can drill into data in our GraphQL query. For this we can add the selection middleware. Middleware in _pure code-first_ are represented by simple attributes. Since middleware order is important the order of these middleware attributes is important too. Middleware attributes always start with the verb `Use`. So, for our selections middleware we add `[UseSelection]`.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;

namespace ContosoUniversity
{
    public class Query
    {
        /// <summary>
        /// Gets all students.
        /// </summary>
        [UseSelection]
        public IQueryable<Student> GetStudents([Service]SchoolContext schoolContext) =>
            schoolContext.Students;
    }
}
```

Let’s paste this file into our project.

I pointed out that in GraphQL everything resolves around a schema. In order to get our GraphQL server up and running we need to create and host a GraphQL schema in our server. In Hot Chocolate we define a schema with the `SchemaBuilder`.

Open the `Startup.cs` again and then let us add a simple schema with our `Query` type.

For that replace the `ConfigureServices` method with the following code.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SchoolContext>();

    services.AddGraphQL(
        SchemaBuilder.New()
            .AddQueryType<Query>()
            .Create(),
        new QueryExecutionOptions { ForceSerialExecution = true });
}
```

The above code registers a GraphQL schema with the dependency injection container.

```csharp
SchemaBuilder.New()
    .AddQueryType<Query>()
    .Create()
```

The schema builder registers our `Query` class as GraphQL `Query` root type.

```csharp
new QueryExecutionOptions { ForceSerialExecution = true }
```

Also, we are defining that the execution engine shall be forced to execute serially since `DbContext` is not thread-safe.

> The upcoming version 11 of Hot Chocolate uses `DbContext` pooling to use multiple `DbContext` instances in one request. This allows version 11 to parallelize data fetching better with _Entity Framework_.

In order to enable our ASP.NET Core server to process GraphQL requests we need to register the Hot Chocolate GraphQL middleware.

For that we need to replace the `Configure` method of our `Startup.cs` with the following code.

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    InitializeDatabase(app);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseGraphQL();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}
```

`app.UseGraphQL();` registers the GraphQL middleware with the server. Since we did not specify any path the middleware will run on the root of our server. Like with field middleware the order of ASP.NET Core middleware is important.

## Testing a GraphQL Server

In order to now query our GraphQL server we need a GraphQL IDE to formulate queries and explore the schema. If you want a deluxe GraphQL IDE as an application, you can get our very own Banana Cake Pop which can be downloaded [here](/products/bananacakepop).

![Hot Chocolate](banana-cake-pop.png)

But you can also opt for _Playground_ and host a simple GraphQL IDE as a middleware with the server. If you want to use playground add the following package to the project:

```bash
dotnet add package HotChocolate.AspNetCore.Playground
```

After that we need to register the playground middleware. For that add `app.UsePlayground();` after `app.UseGraphQL()`. By default, playground is hosted on `/playground` meaning in our case `http://localhost:5000/playground`.

The `Configure` method should now look like the following:

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    InitializeDatabase(app);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseGraphQL();
    app.UsePlayground();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}
```

Let’s test our GraphQL server.

```bash
dotnet run --urls http://localhost:5000
```

### Testing with Banana Cake Pop

If you have chosen _Banana Cake Pop_ to test and explore the GraphQL Schema open it now.

_Banana Cake Pop_ will open with an empty tab. In the address bar type in the URL of our GraphQL server `http://localhost:5000` and hit `enter`.

![Hot Chocolate](banana-cake-pop-address.png)

Once our GraphQL IDE has fetched the schema we can start exploring it. On the left-hand side click on the `Book` button. The left-hand side now shows us the root types and the root fields.

![Hot Chocolate](banana-cake-pop-root-types.png)

In our current schema we can see that we have a single root field called `students`. If we click on that the schema explorer opens and we can drill into our type. We can see what fields we can request from our `Student` type. We also can see that we can drill in further and fetch the enrollments and from the enrollments the courses and so on.

![Hot Chocolate](banana-cake-pop-expanded-schema.png)

Now close the schema tab again so that we can write some queries.

### Testing with Playground

If you have opted for _Playground_ open your browser and navigate to `http://localhost:5000/playground`.

On the right-hand side click on the `Docs` button. A pane will slide out showing us the root types and root fields of our schema.

![Hot Chocolate](playground-root-types.png)

In our current schema we can see that we have a single root field called `students`. If we click on that the schema explorer opens and we can drill into our type. We can see what fields we can request from our `Student` type. We also can see that we can drill in further and fetch the enrollments and from the enrollments the courses and so on.

![Hot Chocolate](playground-expanded-schema.png)

Now click onto `Docs` again so that the schema tab slides back in again. We are now ready to write our first query.

### Recap

While we just added one field that exposes the `Student` entity to Hot Chocolate, Hot Chocolate explored what data is reachable from that entity. In conjunction with the `UseSelection` middleware we can now query all that data and drill into our graph.

We have explored tooling with which we can explore the schema before issuing the first request.

If we would print our schema it would now look like the following.

> The schema SDL can be downloaded from <http://localhost:5000/schema>.

```graphql
schema {
  query: Query
}

type Query {
  students: [Student]
}

type Student {
  enrollmentDate: DateTime!
  enrollments: [Enrollment]
  firstMidName: String
  id: Int!
  lastName: String
}

type Course {
  courseId: Int!
  credits: Int!
  enrollments: [Enrollment]
  title: String
}

type Enrollment {
  course: Course
  courseId: Int!
  enrollmentId: Int!
  grade: Grade
  student: Student
  studentId: Int!
}

enum Grade {
  A
  B
  C
  D
  F
}

"The `DateTime` scalar represents an ISO-8601 compliant date time type."
scalar DateTime

"The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
scalar Int

"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
scalar String
```

### Writing Queries

In both GraphQL IDEs we can type in the GraphQL queries on the left-hand pane. If we click on the play button the result will be displayed on the right-hand side pane.

Let us start with a simple query in which we ask for the first name of all students that we have in our database.

```graphql
query {
  students {
    firstMidName
  }
}
```

The above query resolves correctly the data from our database, and we get the following result:

```json
{
  "data": {
    "students": [
      {
        "firstMidName": "Rafael"
      },
      {
        "firstMidName": "Pascal"
      },
      {
        "firstMidName": "Michael"
      }
    ]
  }
}
```

What is interesting is that the GraphQL engine rewrites the incoming GraphQL request to an expression tree that is applied onto the `IQueryable<Student>` our root field resolver returns. The expression will only query for data from the database that was needed to fulfill our request.

The SQL query in this case will look like the following:

```sql
SELECT "s"."FirstMidName" FROM "Students" AS "s"
```

Let us drill into the data a little more and fetch additionally to the `firstMidName` also the title of the course the students are enlisted to.

```graphql
query {
  students {
    firstMidName
    enrollments {
      course {
        title
      }
    }
  }
}
```

The above query returns:

```json
{
  "data": {
    "students": [
      {
        "firstMidName": "Rafael",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      },
      {
        "firstMidName": "Pascal",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      },
      {
        "firstMidName": "Michael",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      }
    ]
  }
}
```

In order to fetch the data, the GraphQL query is rewritten to the following SQL:

```sql
SELECT "s"."FirstMidName",
       "s"."Id",
       "t"."Title",
       "t"."EnrollmentId",
       "t"."CourseId"
    FROM "Students" AS "s"
    LEFT JOIN (
        SELECT "c"."Title",
               "e"."EnrollmentId",
               "c"."CourseId",
               "e"."StudentId"
        FROM "Enrollments" AS "e"
        INNER JOIN "Courses" AS "c"
              ON "e"."CourseId" = "c"."CourseId"
    ) AS "t" ON "s"."Id" = "t"."StudentId"
    ORDER BY "s"."Id", "t"."EnrollmentId", "t"."CourseId"
```

The `UseSelection` middleware allows us by just attributing it to a field resolver that returns an `IQueryable<T>` to drill into that data set.

Without a lot of code, we already have a working GraphQL server that returns all the students. We are already able to drill into our data and the `UseSelection` middleware rewrites GraphQL selections into `IQueryable<T>` projections that ensures that we only select the data that we need from the database.

Think about it, we really just added entity framework and exposed a single root field that basically just returns the `DbSet<Student>`.

## Filtering

Let us go further with this. We actually can do more here and Hot Chocolate provides you with a filter and sorting middleware to really give you the power to query your data with complex expressions.

First, we need to add two more packages that will add the sorting and filtering middleware.

```bash
dotnet add package HotChocolate.Types.Filters
dotnet add package HotChocolate.Types.Sorting
```

With these new packages in place let us rewrite our query type in order to enable proper filtering support.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;

namespace ContosoUniversity
{
    public class Query
    {
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Student> GetStudents([Service]SchoolContext context) =>
            context.Students;
    }
}
```

The above query type has now two new attributes `UseFiltering` and `UseSorting`. Let me again state that the order of middleware is important.

In order to understand how a field pipeline with middleware works have a look at the following sequence diagram which depicts our data pipeline applied to the above resolver.

```mermaid
sequenceDiagram
    autonumber
        UsePaging->>UseSelection: next(context)
        activate UseSelection
        UseSelection->>UseFiltering: next(context)
        activate UseFiltering
        UseFiltering->>UseSorting: next(context)
        activate UseSorting
        UseSorting->>Resolver: next(context)
        activate Resolver
        Resolver-->>UseSorting: apply sorting
        deactivate Resolver
        UseSorting-->>UseFiltering: apply filters
        deactivate UseSorting
        UseFiltering-->>UseSelection: apply projections
        deactivate UseFiltering
        UseSelection-->>UsePaging: apply paging
        deactivate UseSelection
```

Each field middleware initially yields control to the next field middleware until the resolver is invoked. The resolver returns its result and the field middleware will now on the way back apply their functionality to the result. In our case the field middleware are applying expressions to the queryable to build up the database query.

With that upgraded `Query` type let us restart our server.

```bash
dotnet run --urls http://localhost:5000
```

Now let us inspect our schema again. When we look at the `students` field we can see that there are new arguments called `where` and `orderBy`.

![Hot Chocolate](banana-cake-pop-arguments.png)

For our first query let us fetch the students with the `lastName` `Bar` or `Baz`.

```graphql
query {
  students(where: { OR: [{ lastName: "Bar" }, { lastName: "Baz" }] }) {
    firstMidName
    lastName
    enrollments {
      course {
        title
      }
    }
  }
}
```

Which will return the following result:

```json
{
  "data": {
    "students": [
      {
        "firstMidName": "Pascal",
        "lastName": "Bar",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      },
      {
        "firstMidName": "Michael",
        "lastName": "Baz",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      }
    ]
  }
}
```

Again, we are rewriting the whole GraphQL query into one expression tree that translates into the following SQL.

```sql
SELECT "s"."FirstMidName",
       "s"."LastName",
       "s"."Id",
       "t"."Title",
       "t"."EnrollmentId",
       "t"."CourseId"
    FROM "Students" AS "s"
    LEFT JOIN (
        SELECT "c"."Title",
               "e"."EnrollmentId",
               "c"."CourseId",
               "e"."StudentId"
        FROM "Enrollments" AS "e"
        INNER JOIN "Courses" AS "c"
              ON "e"."CourseId" = "c"."CourseId"
    ) AS "t" ON "s"."Id" = "t"."StudentId"
    WHERE ("s"."LastName" = 'Bar') OR ("s"."LastName" = 'Baz')
    ORDER BY "s"."Id", "t"."EnrollmentId", "t"."CourseId"
```

But we can go further and even allow more. Let’s say we want to allow the consumer of our API to search for specific grades in our student’s enrolment list.

In order to allow filtering on the enrollments we can add the same `UseFiltering` attribute in our entity on the `Enrollments` collection and this property becomes filterable.

```csharp
public class Student
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string LastName { get; set; }
    public string FirstMidName { get; set; }
    public DateTime EnrollmentDate { get; set; }

    [UseFiltering]
    public virtual ICollection<Enrollment> Enrollments { get; set; }
}
```

We don\`t need to apply `UseSelections` again. `UseSelections` really only has to be applied where the data is initially fetched. In this case we do only want to support filtering but no sorting on enrollments. I could again add both but decided to only use filtering here.

Let us restart our server and modify our query further.

```bash
dotnet run --urls http://localhost:5000
```

For the next query we will get all students with the last name `Bar` that are enrolled in the course with the `courseId` `1`.

```graphql
query {
  students(where: { lastName: "Bar" }) {
    firstMidName
    lastName
    enrollments(where: { courseId: 1 }) {
      courseId
      course {
        title
      }
    }
  }
}
```

The following query translates again to a single SQL statement.

```sql
SELECT "s"."FirstMidName",
       "s"."LastName",
       "s"."Id",
       "t"."CourseId",
       "t"."Title",
       "t"."EnrollmentId",
       "t"."CourseId0"
    FROM "Students" AS "s"
    LEFT JOIN (
        SELECT "e"."CourseId",
               "c"."Title",
               "e"."EnrollmentId".
               "c"."CourseId" AS "CourseId0",
               "e"."StudentId"
        FROM "Enrollments" AS "e"
        INNER JOIN "Courses" AS "c"
              ON "e"."CourseId" = "c"."CourseId"
        WHERE "e"."CourseId" = 1
    ) AS "t" ON "s"."Id" = "t"."StudentId"
    WHERE "s"."LastName" = 'Bar'
    ORDER BY "s"."Id", "t"."EnrollmentId", "t"."CourseId0"
```

With filtering and sorting we infer complex filters from our models without almost any code. This allows us to query our data with complex expressions while drilling into the data graph.

Hot Chocolate supports complex expressions with a variety of query operators that can be enabled by just adding a simple attribute on your field resolver. We can also configure the filter capabilities which we want to allow. This means you can for instance disallow `OR` combinations of filter clauses.

## Paging

But we still might get too much data back. What if we select all the students from a real university database? This is where our paging middleware comes in. The paging middleware implements the relay cursor pagination spec.

> Since we cannot do a skip while with _Entity Framework_, we actually use an indexed based pagination underneath. For convenience we are wrapping this as really cursor pagination. With mongoDB and other database provider we are supporting real cursor based pagination.

Like with filtering, sorting and selection we just annotate the paging middleware and it just works. Again, middleware order is important, so we need to put the paging attribute on the top since the most top field middleware is actually applied last like shown in the diagram.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Types.Relay;

namespace ContosoUniversity
{
    public class Query
    {
        [UsePaging]
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Student> GetStudents([Service]SchoolContext context) =>
            context.Students;
    }
}
```

Since paging adds metadata for pagination like a `totalCount` or a `pageInfo` the actual result structure now changes. Also, the paging middleware adds arguments to our field that we need to navigate between pages.

Our `students` field now returns a `StudentConnection` which allows us to either fetch the actual `Student` nodes of the current page or to ask for the pagination metadata.

We could in fact just fetch the `totalCount` of our data set.

```graphql
query {
  students(first: 1) {
    totalCount
  }
}
```

Which would again translate to a simple SQL.

```sql
SELECT 1 FROM "Students" AS "s"
```

Next let us just fetch the `lastName` of the first student.

```graphql
query {
  students(first: 1) {
    nodes {
      lastName
    }
  }
}
```

Which translates to a simple limit query for _SQLLite_.

```sql
SELECT "s"."LastName"
    FROM "Students" AS "s"
    LIMIT @__p_0
```

In order to navigate forward through pages we also need to get data from our `pageInfo` like if there is a next page and the last cursor of the current page.

```graphql
query {
  students(first: 1) {
    nodes {
      lastName
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```json
{
  "data": {
    "students": {
      "nodes": [
        {
          "lastName": "Foo"
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "endCursor": "eyJfX3RvdGFsQ291bnQiOjMsIl9fcG9zaXRpb24iOjB9"
      }
    }
  }
}
```

With the `endCursor` of a page we can get the next page that comes after the `endCursor` by feeding the `endCursor` into the `after` argument.

```graphql
query {
  students(first: 1, after: "eyJfX3RvdGFsQ291bnQiOjMsIl9fcG9zaXRpb24iOjB9") {
    nodes {
      lastName
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```json
{
  "data": {
    "students": {
      "nodes": [
        {
          "lastName": "Bar"
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "endCursor": "eyJfX3RvdGFsQ291bnQiOjMsIl9fcG9zaXRpb24iOjF9"
      }
    }
  }
}
```

This will then be translated into simple offset navigation when using _Entity Framework_.

```sql
SELECT "s"."LastName"
    FROM "Students" AS "s"
    ORDER BY (SELECT 1)
    LIMIT @__p_0 OFFSET @__p_0
```

Again, without a lot of effort we were able to create a powerful GraphQL server with advanced filter and pagination capabilities by just writing basically one line of code with lots of attributes on top of that.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Types.Relay;

namespace ContosoUniversity
{
    public class Query
    {
        [UsePaging]
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Student> GetStudents([Service]SchoolContext context) =>
            context.Students;
    }
}
```

Each request in GraphQL translates into native SQL. Whenever possible we translate it into a single SQL request reducing the need to fetch multiple times from the database.

## Single Selects

We still can improve our query and allow to explore the data from different angles.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Types.Relay;

namespace ContosoUniversity
{
    public class Query
    {
        [UsePaging]
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Student> GetStudents([Service]SchoolContext context) =>
            context.Students;

        [UsePaging]
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Course> GetCourses([Service]SchoolContext context) =>
            context.Courses;
    }
}
```

With the above code we can now drill into the data from both sides. In order to get an even nicer API, we might also want to allow dedicated fetches maybe for a `Student` by the student ID.

We could do something like the following and it would work.

```csharp
public Task<Student> GetStudentByIdAsync([Service]SchoolContext context, int studentId) =>
    context.Students.FirstOrDefaultAsync(t => t.Id == studentId);
```

If we did something like that with _Entity Framework_ we actually would need to write a couple more resolvers to fetch the edges of the entity like the `Enrollments` since with this resolver there is no middleware that does the hard work for us. With the resolver above we are fully in control of the data fetching.

Also doing it like that will lead into other problems since now we are causing multiple fetches to the database and we would no need to think about things like `DataLoader` to guarantee consistency between fetches in a single request.

But we actually have a simple solution for this since we could use our selection middleware still and just tell the middleware pipeline that we actually just want a single result for that resolver.

Let us rewrite the above resolver and look at it again.

```csharp
[UseFirstOrDefault]
[UseSelection]
public IQueryable<Student> GetStudentById([Service]SchoolContext context, int studentId) =>
    context.Students.Where(t => t.Id == studentId);
```

This now looks like the initial resolvers that we wrote to fetch all students. We predefined the where clause and we added a new middleware called `UseFirstOrDefault`. The `UseFirstOrDefault` middleware will rewrite the result type for the GraphQL schema from `[Student]` to `Student` and ensure the we will only fetch a single entity from the database.

`UseFirstOrDefault` from a semantics perspective aligns to `FirstOrDefaultAsync` provided by the _Entity Framework_. Hot Chocolate also provides you with a `UseSingleOrDefault` middleware that will produce a GraphQL field error whenever there is more than one result.

## Conclusion and Outlook

Hot Chocolate has a powerful execution model that allows to natively integrate with data sources of any kind.

The middleware that we showed you here like `UseSelection` or `UseFiltering` etc. do not only work with _Entity Framework_ but also support other providers that support `IQueryable<T>` to express database queries.

But even if you want to support native SQL without `IQueryable<T>` it is super simple to inherit from our query rewriter base classes and and add this translation.

By just implementing such a query rewriter you are creating a native database provider for Hot Chocolate that integrates fully with the query engine.

We also support the full features shown here with multiple other approaches like code-first with schema types or SDL first.

With version 11 we are introducing a new more powerful query engine that will provide full query execution plan support. Version 11 will have even better filters and push what we showed here today to the limit.

The example used in this post can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/blog/2020/2020-03-18-entity-framework/ContosoUni).

We also have a more complex real-time GraphQL server example in multiple flavors and different database integrations [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/workshop/src/Server).

If you want to get into contact with us head over to our slack channel and join our community.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Get started with Hot Chocolate and Entity Framework]]></title>
        <id>https://chillicream.com/blog/2020/03/18/entity-framework</id>
        <link href="https://chillicream.com/blog/2020/03/18/entity-framework"/>
        <updated>2020-03-18T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
In this post I will walk you through how to build a GraphQL Server using Hot Chocolate and _Entity Framework_.

_Entity Framework_ is an OR-mapper from Microsoft that implements the unit-of-work pattern. This basically means that with _Entity Framework_ we work against a `DbContext` and once in a while commit changes aggregated on that context to the database by invoking `SaveChanges`.

With _Entity Framework_ we can write database queries with _LINQ_ and do not have to deal with _SQL_ directly. This means that we can compile our database queries and can detect query errors before we run our code.

## Introduction

This blog post is based on the Contoso University example application used by Microsoft to demonstrate the usage of _Entity Framework_ with ASP.NET Core.

In this blog post we will take that example and build with it a simple GraphQL server for the university website. With it, we can query students, courses, and instructor information.

Before we get started let us setup our server project.

```bash
mkdir ContosoUniversity
dotnet new web
```

Next wee need to add _Entity Framework_ to our project.

```bash
dotnet add package Microsoft.EntityFrameworkCore
```

Last but not least we are adding the SQLLite _Entity Framework_ provided in order to have a lightweight database.

```bash
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
```

For our data we have three models representing the student, the enrollments and the courses.

The student entity has some basic data about the student like the first name, the last name or the date when the student first enrolled into the university.

The enrollment entity represents the enrollment of a student to a specific course. The enrollment entity not only represents the relationship between the student and the course but also holds the Grade that a student achieved in that course.

Last but not least we have the course to which many students are enrolled to. The course has a title and a property defining the credit that a student can achieve in that course.

Let’s copy our models into our project.

```csharp
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity
{
    public class Student
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }

        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }

    public enum Grade
    {
        A, B, C, D, F
    }

    public class Enrollment
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int EnrollmentId { get; set; }
        public int CourseId { get; set; }
        public int StudentId { get; set; }
        public Grade? Grade { get; set; }

        public virtual Course Course { get; set; }
        public virtual Student Student { get; set; }
    }

    public class Course
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CourseId { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }

        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
}
```

For our models we do need a `DbContext` against which we can interact with our database.

```csharp
using Microsoft.EntityFrameworkCore;

namespace ContosoUniversity
{
    public class SchoolContext : DbContext
    {
        public DbSet<Student> Students { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Course> Courses { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlite("Data Source=uni.db");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>()
                .HasMany(t => t.Enrollments)
                .WithOne(t => t.Student)
                .HasForeignKey(t => t.StudentId);

            modelBuilder.Entity<Enrollment>()
                .HasIndex(t => new { t.StudentId, t.CourseId })
                .IsUnique();

            modelBuilder.Entity<Course>()
                .HasMany(t => t.Enrollments)
                .WithOne(t => t.Course)
                .HasForeignKey(t => t.CourseId);
        }
    }
}
```

The `SchoolContext` exposes access to our entities through `DbSet`. We can query a `DbSet<T>` with _LINQ_ or add new entities to it. Moreover, our `ShoolContext` has some configuration that defines the relations between our entities.

Copy the context as well to our project.

Next, we need to register our `SchoolContext` with the dependency injection so that our GraphQL server can request instances of it. For that lets open our `Startup.cs` and replace the `ConfigureServices` method with the following code.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SchoolContext>();
}
```

There is one last thing to finish up our preparations with the database and to get into GraphQL.

We somehow need to create our database. Since we are in this post only exploring how we can query data with entity framework and GraphQL we will also need to seed some data.

Add the following method to the `Startup.cs`:

```csharp
private static void InitializeDatabase(IApplicationBuilder app)
{
    using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
    {
        var context = serviceScope.ServiceProvider.GetRequiredService<SchoolContext>();
        if (context.Database.EnsureCreated())
        {
            var course = new Course { Credits = 10, Title = "Object Oriented Programming 1" };

            context.Enrollments.Add(new Enrollment
            {
                Course = course,
                Student = new Student { FirstMidName = "Rafael", LastName = "Foo", EnrollmentDate = DateTime.UtcNow }
            });
            context.Enrollments.Add(new Enrollment
            {
                Course = course,
                Student = new Student { FirstMidName = "Pascal", LastName = "Bar", EnrollmentDate = DateTime.UtcNow }
            });
            context.Enrollments.Add(new Enrollment
            {
                Course = course,
                Student = new Student { FirstMidName = "Michael", LastName = "Baz", EnrollmentDate = DateTime.UtcNow }
            });
            context.SaveChangesAsync();
        }
    }
}
```

`InitializeDatabase` ensures that our database is created and seeds some initial data so that we can do some queries.

Next call `InitializeDatabase` in the first line of the `Configure` method in the `Startup.cs`. The updated `Configure` method should look like the following:

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    InitializeDatabase(app);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}
```

We are basically done with our preparations. So far, we have defined our models, created our `ShoolContext` through which we can query the database. We also registered the `ShoolContext` with the dependency injection container and added some initialization logic so that our database is created with some initial data. With that settled let us move on and talk about GraphQL.

## GraphQL Schema

Everything in GraphQL resolves around a schema. The schema defines the types that are available and the data that our GraphQL server exposes.

In GraphQL we interact with the data through root types. In this post we will only query data which means that we only need to define the query root type.

The query root type exposes fields which are called root fields. The root fields define how we can query for data. For our university GraphQL server we want to be able to query the students and then drill deeper into what courses a student is enrolled to or what grade he/she has in a specific course.

Before we actually can put some GraphQL types in our project we again need to add some packages. This time we need to add the `HotChocolate.AspNetCore` package to enable the core GraphQL server functionality. Also we need the `HotChocolate.Types.Selections` package to be able to use _Entity Framework_ projections.

```bash
dotnet add package HotChocolate.AspNetCore
dotnet add package HotChocolate.Types.Selections
```

With Hot Chocolate and the _pure code-first_ approach the query root type is represented by a simple class. Public methods or public properties on that type are inferred as fields of our GraphQL type.

The following class:

```csharp
public class Query
{
    /// <summary>
    /// Gets all students.
    /// </summary>
    public IQueryable<Student> GetStudents() => throw new NotImplementedException();
}
```

Is translated to the following GraphQL type:

```graphql
type Query {
  """
  Gets all students
  """
  students: [Student]
}
```

> Hot Chocolate will apply GraphQL conventions to inferred types which will remove the verb `Get` for instance from the method or if it is an async method the postfix `async` will be removed. These conventions can be configured.

In GraphQL we call the method `GetStudents` a resolver since it resolves for us some data. Resolvers are executed independent from one another and each resolver has dependencies on different resources. Everything that a resolver needs can be injected as a method parameter. Our `GetStudents` resolver for instance needs the `ShoolContext` to fetch some data. By using argument injection the execution engine can better optimize how to execute a query.

OK, with this knowledge lets implement our `Query` class.

```csharp
public class Query
{
    /// <summary>
    /// Gets all students.
    /// </summary>
    public IQueryable<Student> GetStudents([Service]SchoolContext schoolContext) =>
        schoolContext.Students;
}
```

Our query class up there would already work. But only for the first level. It basically would resolve all students but we could not drill deeper. The enrollments would always be empty. In Hot Chocolate we have a concept of field middleware that can alter the execution pipeline of our field resolver.

The middleware order is important since multiple middleware form a field execution pipeline.

In our case we want _Entity Framework_ projections to work so that we can drill into data in our GraphQL query. For this we can add the selection middleware. Middleware in _pure code-first_ are represented by simple attributes. Since middleware order is important the order of these middleware attributes is important too. Middleware attributes always start with the verb `Use`. So, for our selections middleware we add `[UseSelection]`.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;

namespace ContosoUniversity
{
    public class Query
    {
        /// <summary>
        /// Gets all students.
        /// </summary>
        [UseSelection]
        public IQueryable<Student> GetStudents([Service]SchoolContext schoolContext) =>
            schoolContext.Students;
    }
}
```

Let’s paste this file into our project.

I pointed out that in GraphQL everything resolves around a schema. In order to get our GraphQL server up and running we need to create and host a GraphQL schema in our server. In Hot Chocolate we define a schema with the `SchemaBuilder`.

Open the `Startup.cs` again and then let us add a simple schema with our `Query` type.

For that replace the `ConfigureServices` method with the following code.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SchoolContext>();

    services
      .AddGraphQLServer()
      .AddQueryType<Query>()
      .AddFiltering()
      .AddSorting();
}
```

The above code registers a GraphQL schema with the dependency injection container.

```csharp
services
    .AddGraphQLServer()
    .AddQueryType<Query>()
```

The schema builder registers our `Query` class as GraphQL `Query` root type.

```csharp
new QueryExecutionOptions { ForceSerialExecution = true }
```

Also, we are defining that the execution engine shall be forced to execute serially since `DbContext` is not thread-safe.

> The upcoming version 11 of Hot Chocolate uses `DbContext` pooling to use multiple `DbContext` instances in one request. This allows version 11 to parallelize data fetching better with _Entity Framework_.

In order to enable our ASP.NET Core server to process GraphQL requests we need to register the Hot Chocolate GraphQL middleware.

For that we need to replace the `Configure` method of our `Startup.cs` with the following code.

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    InitializeDatabase(app);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseGraphQL();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}
```

`app.UseGraphQL();` registers the GraphQL middleware with the server. Since we did not specify any path the middleware will run on the root of our server. Like with field middleware the order of ASP.NET Core middleware is important.

## Testing a GraphQL Server

In order to now query our GraphQL server we need a GraphQL IDE to formulate queries and explore the schema. If you want a deluxe GraphQL IDE as an application, you can get our very own Banana Cake Pop which can be downloaded [here](/products/bananacakepop).

![Hot Chocolate](banana-cake-pop.png)

But you can also opt for _Playground_ and host a simple GraphQL IDE as a middleware with the server. If you want to use playground add the following package to the project:

```bash
dotnet add package HotChocolate.AspNetCore.Playground
```

After that we need to register the playground middleware. For that add `app.UsePlayground();` after `app.UseGraphQL()`. By default, playground is hosted on `/playground` meaning in our case `http://localhost:5000/playground`.

The `Configure` method should now look like the following:

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    InitializeDatabase(app);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseGraphQL();
    app.UsePlayground();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}
```

Let’s test our GraphQL server.

```bash
dotnet run --urls http://localhost:5000
```

### Testing with Banana Cake Pop

If you have chosen _Banana Cake Pop_ to test and explore the GraphQL Schema open it now.

_Banana Cake Pop_ will open with an empty tab. In the address bar type in the URL of our GraphQL server `http://localhost:5000` and hit `enter`.

![Hot Chocolate](banana-cake-pop-address.png)

Once our GraphQL IDE has fetched the schema we can start exploring it. On the left-hand side click on the `Book` button. The left-hand side now shows us the root types and the root fields.

![Hot Chocolate](banana-cake-pop-root-types.png)

In our current schema we can see that we have a single root field called `students`. If we click on that the schema explorer opens and we can drill into our type. We can see what fields we can request from our `Student` type. We also can see that we can drill in further and fetch the enrollments and from the enrollments the courses and so on.

![Hot Chocolate](banana-cake-pop-expanded-schema.png)

Now close the schema tab again so that we can write some queries.

### Testing with Playground

If you have opted for _Playground_ open your browser and navigate to `http://localhost:5000/playground`.

On the right-hand side click on the `Docs` button. A pane will slide out showing us the root types and root fields of our schema.

![Hot Chocolate](playground-root-types.png)

In our current schema we can see that we have a single root field called `students`. If we click on that the schema explorer opens and we can drill into our type. We can see what fields we can request from our `Student` type. We also can see that we can drill in further and fetch the enrollments and from the enrollments the courses and so on.

![Hot Chocolate](playground-expanded-schema.png)

Now click onto `Docs` again so that the schema tab slides back in again. We are now ready to write our first query.

### Recap

While we just added one field that exposes the `Student` entity to Hot Chocolate, Hot Chocolate explored what data is reachable from that entity. In conjunction with the `UseSelection` middleware we can now query all that data and drill into our graph.

We have explored tooling with which we can explore the schema before issuing the first request.

If we would print our schema it would now look like the following.

> The schema SDL can be downloaded from <http://localhost:5000/schema>.

```graphql
schema {
  query: Query
}

type Query {
  students: [Student]
}

type Student {
  enrollmentDate: DateTime!
  enrollments: [Enrollment]
  firstMidName: String
  id: Int!
  lastName: String
}

type Course {
  courseId: Int!
  credits: Int!
  enrollments: [Enrollment]
  title: String
}

type Enrollment {
  course: Course
  courseId: Int!
  enrollmentId: Int!
  grade: Grade
  student: Student
  studentId: Int!
}

enum Grade {
  A
  B
  C
  D
  F
}

"The `DateTime` scalar represents an ISO-8601 compliant date time type."
scalar DateTime

"The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
scalar Int

"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
scalar String
```

### Writing Queries

In both GraphQL IDEs we can type in the GraphQL queries on the left-hand pane. If we click on the play button the result will be displayed on the right-hand side pane.

Let us start with a simple query in which we ask for the first name of all students that we have in our database.

```graphql
query {
  students {
    firstMidName
  }
}
```

The above query resolves correctly the data from our database, and we get the following result:

```json
{
  "data": {
    "students": [
      {
        "firstMidName": "Rafael"
      },
      {
        "firstMidName": "Pascal"
      },
      {
        "firstMidName": "Michael"
      }
    ]
  }
}
```

What is interesting is that the GraphQL engine rewrites the incoming GraphQL request to an expression tree that is applied onto the `IQueryable<Student>` our root field resolver returns. The expression will only query for data from the database that was needed to fulfill our request.

The SQL query in this case will look like the following:

```sql
SELECT "s"."FirstMidName" FROM "Students" AS "s"
```

Let us drill into the data a little more and fetch additionally to the `firstMidName` also the title of the course the students are enlisted to.

```graphql
query {
  students {
    firstMidName
    enrollments {
      course {
        title
      }
    }
  }
}
```

The above query returns:

```json
{
  "data": {
    "students": [
      {
        "firstMidName": "Rafael",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      },
      {
        "firstMidName": "Pascal",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      },
      {
        "firstMidName": "Michael",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      }
    ]
  }
}
```

In order to fetch the data, the GraphQL query is rewritten to the following SQL:

```sql
SELECT "s"."FirstMidName",
       "s"."Id",
       "t"."Title",
       "t"."EnrollmentId",
       "t"."CourseId"
    FROM "Students" AS "s"
    LEFT JOIN (
        SELECT "c"."Title",
               "e"."EnrollmentId",
               "c"."CourseId",
               "e"."StudentId"
        FROM "Enrollments" AS "e"
        INNER JOIN "Courses" AS "c"
              ON "e"."CourseId" = "c"."CourseId"
    ) AS "t" ON "s"."Id" = "t"."StudentId"
    ORDER BY "s"."Id", "t"."EnrollmentId", "t"."CourseId"
```

The `UseSelection` middleware allows us by just attributing it to a field resolver that returns an `IQueryable<T>` to drill into that data set.

Without a lot of code, we already have a working GraphQL server that returns all the students. We are already able to drill into our data and the `UseSelection` middleware rewrites GraphQL selections into `IQueryable<T>` projections that ensures that we only select the data that we need from the database.

Think about it, we really just added entity framework and exposed a single root field that basically just returns the `DbSet<Student>`.

## Filtering

Let us go further with this. We actually can do more here and Hot Chocolate provides you with a filter and sorting middleware to really give you the power to query your data with complex expressions.

First, we need to add two more packages that will add the sorting and filtering middleware.

```bash
dotnet add package HotChocolate.Types.Filters
dotnet add package HotChocolate.Types.Sorting
```

With these new packages in place let us rewrite our query type in order to enable proper filtering support.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;

namespace ContosoUniversity
{
    public class Query
    {
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Student> GetStudents([Service]SchoolContext context) =>
            context.Students;
    }
}
```

The above query type has now two new attributes `UseFiltering` and `UseSorting`. Let me again state that the order of middleware is important.

In order to understand how a field pipeline with middleware works have a look at the following sequence diagram which depicts our data pipeline applied to the above resolver.

```mermaid
sequenceDiagram
    autonumber
        UsePaging->>UseSelection: next(context)
        activate UseSelection
        UseSelection->>UseFiltering: next(context)
        activate UseFiltering
        UseFiltering->>UseSorting: next(context)
        activate UseSorting
        UseSorting->>Resolver: next(context)
        activate Resolver
        Resolver-->>UseSorting: apply sorting
        deactivate Resolver
        UseSorting-->>UseFiltering: apply filters
        deactivate UseSorting
        UseFiltering-->>UseSelection: apply projections
        deactivate UseFiltering
        UseSelection-->>UsePaging: apply paging
        deactivate UseSelection
```

Each field middleware initially yields control to the next field middleware until the resolver is invoked. The resolver returns its result and the field middleware will now on the way back apply their functionality to the result. In our case the field middleware are applying expressions to the queryable to build up the database query.

With that upgraded `Query` type let us restart our server.

```bash
dotnet run --urls http://localhost:5000
```

Now let us inspect our schema again. When we look at the `students` field we can see that there are new arguments called `where` and `orderBy`.

![Hot Chocolate](banana-cake-pop-arguments.png)

For our first query let us fetch the students with the `lastName` `Bar` or `Baz`.

```graphql
query {
  students(where: { OR: [{ lastName: "Bar" }, { lastName: "Baz" }] }) {
    firstMidName
    lastName
    enrollments {
      course {
        title
      }
    }
  }
}
```

Which will return the following result:

```json
{
  "data": {
    "students": [
      {
        "firstMidName": "Pascal",
        "lastName": "Bar",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      },
      {
        "firstMidName": "Michael",
        "lastName": "Baz",
        "enrollments": [
          {
            "course": {
              "title": "Object Oriented Programming 1"
            }
          }
        ]
      }
    ]
  }
}
```

Again, we are rewriting the whole GraphQL query into one expression tree that translates into the following SQL.

```sql
SELECT "s"."FirstMidName",
       "s"."LastName",
       "s"."Id",
       "t"."Title",
       "t"."EnrollmentId",
       "t"."CourseId"
    FROM "Students" AS "s"
    LEFT JOIN (
        SELECT "c"."Title",
               "e"."EnrollmentId",
               "c"."CourseId",
               "e"."StudentId"
        FROM "Enrollments" AS "e"
        INNER JOIN "Courses" AS "c"
              ON "e"."CourseId" = "c"."CourseId"
    ) AS "t" ON "s"."Id" = "t"."StudentId"
    WHERE ("s"."LastName" = 'Bar') OR ("s"."LastName" = 'Baz')
    ORDER BY "s"."Id", "t"."EnrollmentId", "t"."CourseId"
```

But we can go further and even allow more. Let’s say we want to allow the consumer of our API to search for specific grades in our student’s enrolment list.

In order to allow filtering on the enrollments we can add the same `UseFiltering` attribute in our entity on the `Enrollments` collection and this property becomes filterable.

```csharp
public class Student
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string LastName { get; set; }
    public string FirstMidName { get; set; }
    public DateTime EnrollmentDate { get; set; }

    [UseFiltering]
    public virtual ICollection<Enrollment> Enrollments { get; set; }
}
```

We don\`t need to apply `UseSelections` again. `UseSelections` really only has to be applied where the data is initially fetched. In this case we do only want to support filtering but no sorting on enrollments. I could again add both but decided to only use filtering here.

Let us restart our server and modify our query further.

```bash
dotnet run --urls http://localhost:5000
```

For the next query we will get all students with the last name `Bar` that are enrolled in the course with the `courseId` `1`.

```graphql
query {
  students(where: { lastName: "Bar" }) {
    firstMidName
    lastName
    enrollments(where: { courseId: 1 }) {
      courseId
      course {
        title
      }
    }
  }
}
```

The following query translates again to a single SQL statement.

```sql
SELECT "s"."FirstMidName",
       "s"."LastName",
       "s"."Id",
       "t"."CourseId",
       "t"."Title",
       "t"."EnrollmentId",
       "t"."CourseId0"
    FROM "Students" AS "s"
    LEFT JOIN (
        SELECT "e"."CourseId",
               "c"."Title",
               "e"."EnrollmentId".
               "c"."CourseId" AS "CourseId0",
               "e"."StudentId"
        FROM "Enrollments" AS "e"
        INNER JOIN "Courses" AS "c"
              ON "e"."CourseId" = "c"."CourseId"
        WHERE "e"."CourseId" = 1
    ) AS "t" ON "s"."Id" = "t"."StudentId"
    WHERE "s"."LastName" = 'Bar'
    ORDER BY "s"."Id", "t"."EnrollmentId", "t"."CourseId0"
```

With filtering and sorting we infer complex filters from our models without almost any code. This allows us to query our data with complex expressions while drilling into the data graph.

Hot Chocolate supports complex expressions with a variety of query operators that can be enabled by just adding a simple attribute on your field resolver. We can also configure the filter capabilities which we want to allow. This means you can for instance disallow `OR` combinations of filter clauses.

## Paging

But we still might get too much data back. What if we select all the students from a real university database? This is where our paging middleware comes in. The paging middleware implements the relay cursor pagination spec.

> Since we cannot do a skip while with _Entity Framework_, we actually use an indexed based pagination underneath. For convenience we are wrapping this as really cursor pagination. With mongoDB and other database provider we are supporting real cursor based pagination.

Like with filtering, sorting and selection we just annotate the paging middleware and it just works. Again, middleware order is important, so we need to put the paging attribute on the top since the most top field middleware is actually applied last like shown in the diagram.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Types.Relay;

namespace ContosoUniversity
{
    public class Query
    {
        [UsePaging]
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Student> GetStudents([Service]SchoolContext context) =>
            context.Students;
    }
}
```

Since paging adds metadata for pagination like a `totalCount` or a `pageInfo` the actual result structure now changes. Also, the paging middleware adds arguments to our field that we need to navigate between pages.

Our `students` field now returns a `StudentConnection` which allows us to either fetch the actual `Student` nodes of the current page or to ask for the pagination metadata.

We could in fact just fetch the `totalCount` of our data set.

```graphql
query {
  students(first: 1) {
    totalCount
  }
}
```

Which would again translate to a simple SQL.

```sql
SELECT 1 FROM "Students" AS "s"
```

Next let us just fetch the `lastName` of the first student.

```graphql
query {
  students(first: 1) {
    nodes {
      lastName
    }
  }
}
```

Which translates to a simple limit query for _SQLLite_.

```sql
SELECT "s"."LastName"
    FROM "Students" AS "s"
    LIMIT @__p_0
```

In order to navigate forward through pages we also need to get data from our `pageInfo` like if there is a next page and the last cursor of the current page.

```graphql
query {
  students(first: 1) {
    nodes {
      lastName
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```json
{
  "data": {
    "students": {
      "nodes": [
        {
          "lastName": "Foo"
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "endCursor": "eyJfX3RvdGFsQ291bnQiOjMsIl9fcG9zaXRpb24iOjB9"
      }
    }
  }
}
```

With the `endCursor` of a page we can get the next page that comes after the `endCursor` by feeding the `endCursor` into the `after` argument.

```graphql
query {
  students(first: 1, after: "eyJfX3RvdGFsQ291bnQiOjMsIl9fcG9zaXRpb24iOjB9") {
    nodes {
      lastName
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```json
{
  "data": {
    "students": {
      "nodes": [
        {
          "lastName": "Bar"
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "endCursor": "eyJfX3RvdGFsQ291bnQiOjMsIl9fcG9zaXRpb24iOjF9"
      }
    }
  }
}
```

This will then be translated into simple offset navigation when using _Entity Framework_.

```sql
SELECT "s"."LastName"
    FROM "Students" AS "s"
    ORDER BY (SELECT 1)
    LIMIT @__p_0 OFFSET @__p_0
```

Again, without a lot of effort we were able to create a powerful GraphQL server with advanced filter and pagination capabilities by just writing basically one line of code with lots of attributes on top of that.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Types.Relay;

namespace ContosoUniversity
{
    public class Query
    {
        [UsePaging]
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Student> GetStudents([Service]SchoolContext context) =>
            context.Students;
    }
}
```

Each request in GraphQL translates into native SQL. Whenever possible we translate it into a single SQL request reducing the need to fetch multiple times from the database.

## Single Selects

We still can improve our query and allow to explore the data from different angles.

```csharp
using System.Linq;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Types.Relay;

namespace ContosoUniversity
{
    public class Query
    {
        [UsePaging]
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Student> GetStudents([Service]SchoolContext context) =>
            context.Students;

        [UsePaging]
        [UseSelection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Course> GetCourses([Service]SchoolContext context) =>
            context.Courses;
    }
}
```

With the above code we can now drill into the data from both sides. In order to get an even nicer API, we might also want to allow dedicated fetches maybe for a `Student` by the student ID.

We could do something like the following and it would work.

```csharp
public Task<Student> GetStudentByIdAsync([Service]SchoolContext context, int studentId) =>
    context.Students.FirstOrDefaultAsync(t => t.Id == studentId);
```

If we did something like that with _Entity Framework_ we actually would need to write a couple more resolvers to fetch the edges of the entity like the `Enrollments` since with this resolver there is no middleware that does the hard work for us. With the resolver above we are fully in control of the data fetching.

Also doing it like that will lead into other problems since now we are causing multiple fetches to the database and we would no need to think about things like `DataLoader` to guarantee consistency between fetches in a single request.

But we actually have a simple solution for this since we could use our selection middleware still and just tell the middleware pipeline that we actually just want a single result for that resolver.

Let us rewrite the above resolver and look at it again.

```csharp
[UseFirstOrDefault]
[UseSelection]
public IQueryable<Student> GetStudentById([Service]SchoolContext context, int studentId) =>
    context.Students.Where(t => t.Id == studentId);
```

This now looks like the initial resolvers that we wrote to fetch all students. We predefined the where clause and we added a new middleware called `UseFirstOrDefault`. The `UseFirstOrDefault` middleware will rewrite the result type for the GraphQL schema from `[Student]` to `Student` and ensure the we will only fetch a single entity from the database.

`UseFirstOrDefault` from a semantics perspective aligns to `FirstOrDefaultAsync` provided by the _Entity Framework_. Hot Chocolate also provides you with a `UseSingleOrDefault` middleware that will produce a GraphQL field error whenever there is more than one result.

## Conclusion and Outlook

Hot Chocolate has a powerful execution model that allows to natively integrate with data sources of any kind.

The middleware that we showed you here like `UseSelection` or `UseFiltering` etc. do not only work with _Entity Framework_ but also support other providers that support `IQueryable<T>` to express database queries.

But even if you want to support native SQL without `IQueryable<T>` it is super simple to inherit from our query rewriter base classes and and add this translation.

By just implementing such a query rewriter you are creating a native database provider for Hot Chocolate that integrates fully with the query engine.

We also support the full features shown here with multiple other approaches like code-first with schema types or SDL first.

With version 11 we are introducing a new more powerful query engine that will provide full query execution plan support. Version 11 will have even better filters and push what we showed here today to the limit.

The example used in this post can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/blog/2020/2020-03-18-entity-framework/ContosoUni).

We also have a more complex real-time GraphQL server example in multiple flavors and different database integrations [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/workshop/src/Server).

If you want to get into contact with us head over to our slack channel and join our community.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 10.3.0]]></title>
        <id>https://chillicream.com/blog/2019/12/26/hot-chocolate-10.3.0</id>
        <link href="https://chillicream.com/blog/2019/12/26/hot-chocolate-10.3.0"/>
        <updated>2019-12-26T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we are releasing Hot Chocolate version 10.3.0. Although the version number sounds like a small change, it is quite a nice update with lots of new features making Hot Chocolate the most versatile and feature rich GraphQL server on the .NET platform.

We are now working for a long time on version 11. Work on that has begun long before version 10.0.0 was finished. As we progressed with version 11, we felt that we could push some nice productivity features down to the version 10 branch and make users of Hot Chocolate much happier.

This decision culminated in version 10.3.0 and it really feels like a major update with an array of new possibilities that will make you smile.

With version 10.3.0 we are introducing a new code-first variant which we internally call _pure code-first_.

We now really can for the first time build a fully-fledged GraphQL server just with C#.

> If you want to see how the Star Wars example looks like with the new 10.3.0 and _pure code-first_ then head over [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/PureCodeFirst).

Let`s dive into the features and explore what we can do with the newest version of Hot Chocolate.

## Nullability

The first feature that I want to introduce is C# 8 nullable reference type support.

With previous versions of C# we always had the problem that C# had only nullable reference types, hence we had to give our classes always some extra context to be able to infer non-null GraphQL types.

```csharp
public class Query
{
    /// <summary>
    /// This field says hello.
    /// </summary>
    [GraphQLNonNull]
    public string SayHello(string name)
    {
        return name is null ? "Hello!" : $"Hello {name}!"
    }
}
```

It is needless to say that we also could do that with our schema types.

```csharp
public class QueryType : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor.Field(t => t.SayHello(default)).Type<NonNullType<StringType>>();
    }
}
```

With C# 8.0 _Microsoft_ introduced a new language feature called nullable reference types that allows us to define when reference types can be null.

```csharp
public class Query
{
    /// <summary>
    /// This field says hello.
    /// </summary>
    public string SayHello(string? name)
    {
        return name is null ? "Hello!" : $"Hello {name}!"
    }
}
```

When activated either setting the _MSBuild_ property `<Nullable>enable</Nullable>` or by adding a preprocessor directive `#nullable enable` Hot Chocolate will automatically infer the nullability of GraphQL types from the corresponding .NET types.

Hence the above class is now correctly inferred and translates nicely into GraphQL types.

```graphql
type Query {
  "This field says hello."
  sayHello(name: String): String!
}
```

## Descriptor Attributes

One big issue that we still saw with _pure code-first_ was how people should apply middleware to their fields. This was for a long time a roadblock for us in making this experience more powerful and easy to use.

Our solution to this are descriptor attributes which act as a kind of an interceptor into the inferred schema type. This allows users to create their own attributes in an easy way and with all the power that is available through the schema type APIs.

```csharp
public sealed class ToUpperAttribute : ObjectFieldDescriptorAttribute
{
    public override void OnConfigure(
        IDescriptorContext context,
        IObjectFieldDescriptor descriptor,
        MemberInfo member)
    {
        descriptor.Use(next => async ctx =>
        {
            await next(ctx);

            if(ctx.Result is string s)
            {
                ctx.Result = s.ToUpperInvariant();
            }
        })
    }
}
```

The attributes very cleanly package all the logic for a middleware or other configuration aspects. This makes it very easy to use. By just applying an attribute to a class, property, method or any other member kind we can add completely new functionality to that specific element or even completely reconfigure it.

```csharp
public class Query
{
    /// <summary>
    /// This field says hello.
    /// </summary>
    [ToUpper]
    public string SayHello(string? name)
    {
        return name is null ? "Hello!" : $"Hello {name}!"
    }
}
```

We have created attribute base classes for all the important descriptors.

- EnumTypeDescriptorAttribute
- EnumValueDescriptorAttribute
- InputObjectTypeDescriptorAttribute
- InputFieldDescriptorAttribute
- InterfaceTypeDescriptorAttribute
- InterfaceFieldDescriptorAttribute
- ObjectTypeDescriptorAttribute
- ObjectFieldDescriptorAttribute
- ArgumentDescriptorAttribute
- UnionTypeDescriptorAttribute

But sometimes we even want to drill deeper with attributes and use a single attribute with multiple descriptors.

Maybe we only want to apply arguments through an attribute to a field if the field is on an interface.

```csharp
public interface IFoo
{
    [UseOffsetPaging]
    IQueryable<IFoo> GetFoos();
}
```

```graphql
interface Foo {
  foos(skip: Int, take: Int): [Foo!]!
}
```

But if the same attribute is applied to an object field then we might also want to apply a middleware that adds some cross-cutting functionality to it like a paging algorithm.

```csharp
public interface Bar : IFoo
{
    [UseOffsetPaging]
    IQueryable<IFoo> GetFoos();
}
```

```graphql
type Bar implements Foo {
  foos(skip: Int, take: Int): [Foo!]!
}
```

For this we can use the attribute base class `DescriptorAttribute`.

```csharp
public sealed class UseOffsetPagingAttribute : DescriptorAttribute
{
    protected internal override void TryConfigure(
        IDescriptorContext context,
        IDescriptor descriptor,
        ICustomAttributeProvider element)
    {
        if (element is MemberInfo m)
        {
            if (descriptor is IObjectFieldDescriptor ofd)
            {
                // do something
            }
            else if (descriptor is IInterfaceFieldDescriptor ifd)
            {
                // do something
            }
        }
    }
}
```

The `TryConfigure` method passes in the `IDescriptorContext` which provides us access to conventions and other services. Also, we have access to the `descriptor` that is associated with the annotated element. Additionally the `element` to which the attribute is annotated to is also passed in.

With this it is very easy to probe for different cases and build complex functionality in a simple attribute that is easy to use by others.

Last but not least we also have added a set of built-in attributes for paging, filtering, sorting and authorization.

```csharp
public class Query
{
    /// <summary>
    /// This field says hello.
    /// </summary>
    [Authorize(Policy = "MyPolicy")]
    [UsePaging]
    [UseFiltering]
    [UseSorting]
    public IQueryable<Customer> GetCustomers()
    {
        ...
    }
}
```

The attributes can be chained just like with the fluent API. The above code would translate into the following schema type.

```csharp
public class QueryType : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor descriptor)
    {
        descriptor.Field(t => t.GetCustomers())
            .Description("This field says hello.")
            .Authorize("MyPolicy")
            .UsePaging<ObjectType<Customer>>()
            .UseFiltering()
            .UseSorting();
    }
}
```

## Type Attributes

Another issue that we had was telling the schema builder that we want to force types to bind as specific GraphQL type.

A class for instance is automatically inferred as an object type when the type is discovered in an output context. But a `struct` on the other hand is not automatically inferred if it is not mapped as a scalar since it could become quite messy with distinguishing if a `struct` should become a scalar or an object type or an input object type.

For this problem we have created a special set of descriptor attributes that mark the .NET type as a specific GraphQL type.

```csharp
[ObjectType(Name = "QueryRoot")]
public struct Query
{
    public string Foo => "Foo";
}
```

The same would work if we wanted to enforce that an abstract base class for instance becomes an interface or even a union type. It is important that the context in which this type is discovered also matters. So, one type could translate into an input type and an output type at the same time.

```csharp
public class Query
{
    public Foo GetFoo(Foo foo) => foo;
}

public class Foo
{
    public string Bar { get; set; }
}
```

The above example would automatically translate into a GraphQL schema where `Foo` would be represented by two types in the GraphQL schema.

```graphql
type Query {
  foo(input: FooInput): Foo
}

type Foo {
  bar: String
}

input FooInput {
  bar: String
}
```

OK, it starts to feel quite nice :)

But still we are not there yet.

When people start building big APIs, they tend to want to split up types. The most asked question on our slack channel is how to split up the query type.

With SDL-first and our traditional code-first approach this is as easy as eating pie since we can write type extensions.

So, we added for 10.3.0 the ability to also split up types with the _pure code-first_ approach.

Let\`s say we have a query type and we want to divide this up into logical units. We could add a bodiless query type by either adding an empty class to our `SchemaBuilder` or by using a schema type.

**Approach 1 - Empty Class**

```csharp
public class Query
{
}

SchemaBuilder.New()
    .AddQueryType<Query>()
    ...
```

**Approach 2 - Schema Type**

```csharp
public class Query : ObjectType
{
    protected override void Configure(IObjectTypeDescriptor descriptor)
    {
        descriptor.Name("Query");
    }
}

SchemaBuilder.New()
    .AddQueryType<QueryType>()
    ...
```

Next we could create standard C# classes to extend on the query type. We can divide our type into as many classes as we want. Also, since each class is independent we could for instance have extra query fields during development time by just adding an extension class on dev to our schema builder and on prod we could leave that away.

```csharp
[ExtendObjectType(Name = "Query")]
public class FooQueries
{
    public string Hello() => "abc";
}

SchemaBuilder.New()
    .AddQueryType<QueryType>()
    .AddType<FooQueries>()
    .Create();
```

The above code would result in the following schema:

```graphql
type Query {
  hello: String
}
```

Object type extensions let us divide our GraphQL types into multiple .NET types. This lets us be more flexible in building our API. Moreover, we can divide our query type into logical units and test them independently from each other. We can do that by just writing a clean C# class that only really would need one attribute to mark it as an extension.

## Interfaces

Hot Chocolate is able to infer interface types from C# APIs since version 10.0.0. But now with the new capabilities of Hot Chocolate in 10.3.0 this becomes a really great feature.

```csharp
public class Query
{
    /// <summary>
    /// Get my pet :)
    /// </summary>
    public IPet? GetPet(int id)
    {
        // some code
    }
}

public interface IPet
{
    // some code
}

public class Dog : IPet
{
    // some code
}

public class Cat : IPet
{
    // some code
}

SchemaBuilder.New()
    .AddQuery<Query>()
    .AddType<Dog>()
    .AddType<Cat>()
    .Create();
```

```graphql
type Query {
  "Get my pet :)"
  pet(id: Int!): IPet
}

interface Pet {
    // fields
}

type Dog implements Pet {
    // fields
}

type Cat implements Pet {
    // fields
}
```

This feels awesome. The schema builder translates our C# types exactly the way we meant them into a clean GraphQL schema. We do not have to write all those schema types anymore. We just write clean C# code and let the schema builder handle the rest.

> It is important to know that we still can use schema types. Also, we can mix our approach, for instance we could use schema types in situations where we do not want to add attributes to our types.

## Optional

Another concept we are introducing with 10.3.0 is optional on input object types. We are planning to use optional even more with version 11 but with 10.3.0 you can use them on input object types in order to distinguish between **not set** and **null**.

```csharp
public class Foo
{
    public Optional<string> Bar { get; set; }
}
```

The important thing with optional is that they implicitly convert to the type specified as type parameter. This means that the following is valid code:

```csharp
var foo = new Foo { Bar = "ABCDEF" };
string fooValue = foo.Bar;
```

But we also can now distinguish between **not set** and **null** since we can ask the optional if it has a value.

```csharp
var foo = new Foo { Bar = "ABCDEF" };
if(foo.Bar.HasValue)
{
    // property was set.
}
```

Optional in 10.3.0 only work on properties of input objects meaning we cannot use them on output types. With 10.3.0 the execution engine has no knowledge about optional at all.

Also, we cannot use optional on arguments in the way that we could ask the context for an optional like the following:

```csharp
context.Argument<Optional<string>>("foo");
```

We will introduce this with the upcoming version 11 release. We decided to not change the execution engine to much with 10.3.0 since we are doing a lot of work on the execution engine with version 11.

Another caveat here is that if you are using `Optional<T>` on a property, the property cannot have a default value. This is also one thing we will change with version 11.

Still, optional can help already in version 10.3.0 with some scenarios and with version 11 we will go all the way to make this an awesome addition.

## Type Extensions

For the last few paragraphs I only talked about the _pure code-first_ approach but we actually also added a new feature to the schema types (aka _code-first_ approach).

For a long time now, we can extend types or break types up into multiple parts.

```csharp
public class FooExtension : ObjectTypeExtension
{
    protected override void Configure(ObjectTypeDescriptor descriptor)
    {
        descriptor.Name("Foo");
        descriptor.Field<Foo>(t => t.Bar).Use(...);
        descriptor.Field("baz").Use(...);
    }
}
```

But the type extension until now did not allow to specify an underlying model. With 10.3.0 we now allow you to specify any type extension with a generic type parameter.

```csharp
public class FooExtension : ObjectTypeExtension<Foo>
{
    protected override void Configure(ObjectTypeDescriptor<Foo> descriptor)
    {
        descriptor.Name("Foo");
        descriptor.Field(t => t.Bar).Use(...);
    }
}
```

## Immutable Input Objects

We are not done yet :) There are still more features on 10.3.0.

Another feature we have integrated into the input object types is support for immutable input objects. This becomes important when working with C# 8.0 and nullable reference types.

With version 10.3.0 we can now specify immutable classes like the following one as input object.

```csharp
public class ImmutableFoo
{
    public ImmutableFoo(string bar)
    {
        Bar = bar;
    }

    public string Bar { get; }
}
```

If we use the above class as input object the type can deserialize or parse it correctly by using the constructor instead of setting the properties.

Also supported is to use the constructor just for non-null reference types like the following:

```csharp
public class Foo
{
    public Foo(string bar)
    {
        Bar = bar;
    }

    public string Bar { get; set; }

    public string? Baz { get; set; }
}
```

## Subscriptions

Last but not least we did some work to make subscriptions easier and allow people to leverage the power of async streams.

If you are happy with subscriptions today, you do not need to change anything.

But if you want to easily hook up Azure ServiceBus or stream something over what ever, then this has become super simple with the new subscribe resolver.

```csharp
public class SubscriptionType : ObjectType
{
    protected override void Configure(ObjectTypeDescriptor<Foo> descriptor)
    {
        descriptor.Field("foo")
            .Subscribe(async ctx =>
            {
                async foreach(var payload in await serviceBus.OnMessageReceiveAsync())
                {
                    yield return payload;
                }
            })
            ...
    }
}
```

You also can bind the subscribe resolver like any other resolver to an underlying method.

```csharp
public class SubscriptionType : ObjectType<Subscription>
{
    protected override void Configure(ObjectTypeDescriptor<Foo> descriptor)
    {
        descriptor
            .Field(t => t.GetMessageAsync())
            .Subscribe(t => t.OnReceiveMessage())
            ...
    }
}
```

The subscribe resolvers accepts `IAsyncEnumerable<T>`, `IEnumerable<T>` and `IObservable<T>` as result.

## Wrapping it up

With Hot Chocolate 10.3.0 we focused on productivity features that have a minor impact on the overall system. This means that we enable a whole bunch of new scenarios with the current Hot Chocolate server generation.

With version 11 we will take this to a whole new level with a completely new execution engine that is much more efficient and allows for completely new features like `@defer`.

Also, version 11 will introduce new tools and libraries to the platform like _Banana Cake Pop_ (preview dropping very soon), _Strawberry Shake_ or our new _Visual Studio for Windows Integration_.

We have a lot more in our pipeline and are totally obsessed with GraphQL and .NET.

I hope you will enjoy 10.3.0 as much as I already do and join the Hot Chocolate fold.

BTW, head over to our _pure code-first_ [Star Wars example](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/PureCodeFirst).

If you want to get into contact with us head over to our slack channel and join our community.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Lets supercharge your GraphQL schema :)]]></title>
        <id>https://chillicream.com/blog/2019/11/29/schema-design</id>
        <link href="https://chillicream.com/blog/2019/11/29/schema-design"/>
        <updated>2019-11-29T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
When you think about how we build our GraphQL schemas with Hot Chocolate we always need to fall back to either the schema types or the GraphQL SDL in order to get the typings right.

This brings with it a lot of boiler plate code that we actually could infer from our C# code. With version 10.3.0 we have decided to integrate some of the version 11 features to make it possible to have these capabilities now instead of next year.

## Nullability

First, let us get the obvious out of the way. C# with version 8.0 has now nullable reference types, or actually they now have non-null reference types.

It does not matter how you look at it, but the result is that we now can differentiate between nullable reference types and reference types that cannot be null.

With version 10.3.0-preview.2 we can infer these, and you finally do not need helpers like attributes and other things to define your schema types with non-null types.

A simple query like ...

```csharp
public class Query
{
    /// <summary>
    /// This field says hello.
    /// </summary>
    public string SayHello(string? name)
    {
        return name is null ? "Hello!" : $"Hello {name}!"
    }
}
```

... is now correctly inferred to:

```graphql
type Query {
  "This field says hello."
  sayHello(name: String): String!
}
```

Do not get me wrong here, I still love our schema types and we will not get rid of them since they are the foundation of every schema. We still are using them in the above example, you just do not need to see them anymore. Moreover, we see these improvements more as an additional way to define a GraphQL schemas with pure C# types.

In the beginning we decided that people should be free in their way of how they want to define their schemas. We are still 100% committed to SDL first, code-first with schema types and code-first with pure C# types.

## Interfaces

Since version 10.0.0 Hot Chocolate is able to infer interface types from API usage. This means that we will correctly infer the interfaces that you use and the types that implement those interfaces.

```csharp
public class Query
{
    /// <summary>
    /// Get my pet :)
    /// </summary>
    public IPet? GetPet(int id)
    {
        // some code
    }
}

public interface IPet
{
    // some code
}

public class Dog : IPet
{
    // some code
}

public class Cat : IPet
{
    // some code
}

SchemaBuilder.New()
    .AddQuery<Query>()
    .AddType<Dog>()
    .AddType<Cat>()
    .Create();
```

```graphql
type Query {
  "Get my pet :)"
  pet(id: Int!): IPet
}

interface Pet {
    // fields
}

type Dog implements Pet {
    // fields
}

type Cat implements Pet {
    // fields
}
```

This feels awesome. The schema builder translates our C# types exactly the way we meant them. We do not have to tell the schema builder any more how to do that it will just work.

## Descriptor Attributes

But what about field middleware and other more complex features like type extensions and so on.

This was something we contemplated for a long time. In the end we came up with powerful descriptor attributes. This basically allows you to create attributes for your schema in which you have access to the full descriptor API. Let me give you an example for this.

Let us say we want to create a simple middleware that can be put on properties and methods and that applies a `ToUpper` on every resulting `string` on the annotated member.

```csharp
public sealed class ToUpperAttribute : ObjectFieldDescriptorAttribute
{
    public override void OnConfigure(IObjectFieldDescriptor descriptor)
    {
        descriptor.Use(next => async ctx =>
        {
            await next(ctx);

            if(ctx.Result is string s)
            {
                ctx.Result = s.ToUpperInvariant();
            }
        })
    }
}
```

The neat thing is that we have full access to all the things we have on our fluent API. The attributes very cleanly packages all the logic and makes it very easy applicable. By just applying an attribute to a property or method I can add huge functionality to that member (resolver).

```csharp
public class Query
{
    /// <summary>
    /// This field says hello.
    /// </summary>
    [ToUpper]
    public string SayHello(string? name)
    {
        return name is null ? "Hello!" : $"Hello {name}!"
    }
}
```

This allows us to enable the full power of schema types with pure C# types. The new attributes will arrive with 10.3.0-preview.3 probably on Monday.

We will add attributes for each descriptor type. Moreover, you can apply input and output attributes on the same type, and we will create automatically an output- and an input-version of that type.

We will also provide attributes for all our middleware like paging, filtering, sorting and authorization. So, you will have the full power of Hot Chocolate even when you do not use our schema type directly.

> I really love this feature :)

## Type Extensions

Another thing we want to make better with 10.3.0 are the code-first type extensions. You could already do cool things with the type extensions but there are two things that did not feel nice enough.

First, we did not have a generic type extension type. This means that defining fields can sometimes be a pain. We had to either declare fields and provide the declaring type with them or we had to specify the field with a string name.

```csharp
public class FooExtension : ObjectTypeExtension
{
    protected override void Configure(ObjectTypeDescriptor descriptor)
    {
        descriptor.Name("Foo");
        descriptor.Field<Foo>(t => t.Bar).Use(...);
        descriptor.Field("baz").Use(...);
    }
}
```

With the new version we can now basically do the same than we do with standard types by providing a type parameter:

```csharp
public class FooExtension : ObjectTypeExtension<Foo>
{
    protected override void Configure(ObjectTypeDescriptor<Foo> descriptor)
    {
        descriptor.Name("Foo");
        descriptor.Field(t => t.Bar).Use(...);
    }
}
```

The second thing that is sometimes good and other times bad is that we have to provide an name. With 10.3.0 we first of all can now infer the type from the mode.

You also can just type in the name like before. Or you provide as with the type that you want to actually extend.

```csharp
public class FooExtension : ObjectTypeExtension<Foo>
{
    protected override void Configure(ObjectTypeDescriptor<Foo> descriptor)
    {
        descriptor.Extend<FooType>()
        descriptor.Field(t => t.Bar).Use(...);
    }
}
```

## Optional

Another concept we will introduce with 10.3.0 is optionals. This is often a thing we want to use when we are talking about input types. We have introduced this concept already with _Strawberry Shake_ and like it a lot.

So, we are porting it now back to the server. In your resolvers you can now use for every argument the optional wrapper type and this will tell you if the argument was not provided. This will allow you to easily do partial updates. We could do partial updates before but not as elegant as now. With version 11 we will improve on that by having a nice patch type.

```csharp
public async Task<Foo> GetMyFoo(Optional<string> id)
{
    // ...
}
```

Also you can use optionals in input objects.

```csharp
public class Foo
{
    public Optional<string> Bar { get; set; }
}
```

The nice thing with the inputs are that they implicitly convert.

```csharp
var foo = new Foo { Bar = "My String" };
```

## Wrapping it up

Hot Chocolate 10.3.0 will bring a lot new improvements to how we can create GraphQL schemas. All these changes are just additions and there are no breaking changes involved meaning we give you a lot of version 11 productivity improvements now.

So, when can you expect 10.3.0. We will deliver nullable ref types with 10.3.0-preview.2 (tonight) and the attributes will come 10.3.0-preview.3. We think the final version should be ready end of next week. We initially planned end of this week but we still have some bug fixing to do.

I hope you are as exited as I am about this. Happy Thanksgiving :) and get a super awesome Hot Chocolate with marshmallows to get into your GraphQL groove.

If you want to get into contact with us head over to our slack channel and join our community.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Building a real-time .NET GraphQL Client API]]></title>
        <id>https://chillicream.com/blog/2019/11/25/strawberry-shake_2</id>
        <link href="https://chillicream.com/blog/2019/11/25/strawberry-shake_2"/>
        <updated>2019-11-25T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
We are busy, busy, busy working on version 11 of Hot Chocolate and _Strawberry Shake_.

In this post I want to explore the client side of GraphQL on .NET more with a special emphasis on subscriptions.

Since, with the new version of _Strawberry Shake_ our initial blog has become kind of invalid I also will walk you trough the basics again before heading into subscriptions and what lies beyond.

## Getting Started

Let us have a look at how we want to tackle things with _Strawberry Shake_. For this little walk-through I will use our [_Star Wars_ server example](https://github.com/ChilliCream/graphql-platform/tree/master/examples/AspNetCore.StarWars).

If you want to follow along then install the [.NET Core 3 SDK](https://dotnet.microsoft.com/download/dotnet-core/3.0) . We are also supporting other .NET variants but for this example you will need the .NET Core 3 SDK.

Before we can start let us clone the Hot Chocolate repository and start our _Star Wars_ server.

```bash
git clone https://github.com/ChilliCream/graphql-platform.git
cd hotchocolate
dotnet run --project examples/AspNetCore.StarWars/
```

Now that we have our _Star Wars_ server running, lets create a folder for our client and install the _Strawberry Shake_ CLI tools.
The _Strawberry Shake_ CLI tools are optional but make initializing the client project much easier.

```bash
mkdir berry
dotnet new tool-manifest
dotnet tool install StrawberryShake.Tools --version 11.0.0-preview.58 --local
```

In our example we are using the new .NET CLI local tools. `dotnet new tool-manifest` creates the tools manifest which basically is like a packages.config and holds the information of which tools in which version we are using in our directory.

This is the great thing about local tools if you think about it, you can install tools to your repository and have always the right set of tools available to you in the moment you clone that repository.

The next command `dotnet tool install StrawberryShake.Tools --version 11.0.0-preview.58 --local` installs our _Strawberry Shake_ tools. Once we have a final release of _Strawberry Shake_ you do not need to specify the version anymore.

Next we need a little project. Let’s create a new console application so that we can easily run and debug what we are doing.

```bash
dotnet new console -n BerryClient
cd BerryClient
dotnet add package StrawberryShake --version 11.0.0-preview.58
dotnet add package Microsoft.Extensions.Http --version 3.0.0
dotnet add package Microsoft.Extensions.DependencyInjection --version 3.0.0
```

OK, now that we have a project setup lets initialize the project by creating a local schema. Like with _Relay_ we are holding a local schema file that can be extended with local types and fields. Our _GraphQL_ compiler will use this schema information to validate the queries we write. This makes _GraphQL_ query documents a part of the compilation process and with that a first-class citizen of our C# library.

> For the next step ensure that the _Star Wars_ _GraphQL_ server is running since we will fetch the schema from the server.

> If you want to check out what commands are available with the tools just run `dotnet graphql` and the CLI tools will output the available commands.

```bash
dotnet graphql init http://localhost:5000/graphql -n StarWars -p ./StarWars
```

The init command will download the schema as GraphQL SDL and create a config to re-fetch the schema. Also, the config contains the client name. The client name defines how the client class and interface shall be named.

> Note: You can pass in the token and scheme if your endpoint is authenticated. There is also an update command to update the local schema.

The configuration will look like the following:

```json
{
  "Schemas": [
    {
      "Name": "StarWars",
      "Type": "http",
      "File": "StarWars.graphql",
      "Url": "http://localhost:5000/graphql"
    }
  ],
  "ClientName": "StarWarsClient"
}
```

OK, now let’s get started by creating our first client API. For this open your editor of choice. I can recommend using _VSCode_ for this at the moment since you will get GraphQL highlighting. As we move forward, we will refine the tooling and provide proper IntelliSense.

Now let us create a new file in our `StarWars` folder called `Queries.graphql` and add the following query:

> The file does not necessarily have to be called queries. You can call it however you want. The GraphQL compiler will figure out what files contain queries and what files contain schema definitions.

```graphql
query getFoo {
  foo
}
```

Now build your project.

```bash
dotnet build
```

When we now compile, we get an _MSBuild_ error on which we can click in _VSCode_ and we are pointed to the place in our query file from which the error stems from. The error tells us that there is no field `foo` on the `Query` type.

```bash
/Users/michael/Local/play/berry/BerryClient/StarWars/Queries.graphql(2,3): error GQL: The field `foo` does not exist on the type `Query`. [/Users/michael/Local/play/berry/BerryClient/BerryClient.csproj]
```

Your GraphQL query document is not just a string, it properly compiles and is fully typed. Let's change our query and compile again:

```graphql
query getFoo {
  hero {
    name
  }
}
```

```bash
dotnet build
```

Now our project changes and we get a new `Generated` folder that has all the types that we need to communicate with our backend.

Let us have a closer look at our client interface for a minute.

```csharp
public interface IStarWarsClient
{
    Task<IOperationResult<IGetFoo>> GetFooAsync(
        CancellationToken cancellationToken = default);
}
```

The named operation `getFoo` has become the method `GetFooAsync` in our generated client. This is nice since we kind of control from our GraphQL document the shape of our C# API. But there is more to that. A query document can hold multiple named operations. In essence the query document describes the interface between the client and the server.

```graphql
query function_a {
  ...
}

query function_b {
  ...
}

query function_c {
  ...
}
```

Since, with GraphQL you essentially design your own service API by writing a query document you want to have control over the structure of your generated types. _Strawberry Shake_ uses fragments to help you describe clean and reusable code components.

Let us redesign our query with fragments and make it a bit more complex.

```graphql
query getHero {
  hero {
    ...SomeDroid
    ...SomeHuman
  }
}

fragment SomeHuman on Human {
  ...HasName
  homePlanet
}

fragment SomeDroid on Droid {
  ...HasName
  primaryFunction
}

fragment HasName on Character {
  name
}
```

The fragments will yield in the following type structure:

```csharp
public interface ISomeHuman
    : IHasName
{
    string HomePlanet { get; }
}

public interface ISomeDroid
    : IHasName
{
    string PrimaryFunction { get; }
}

public interface IHasName
{
    string Name { get; }
}
```

Let us reflect on that, fragments not only let us re-use type selections in our query document but also let us create and mold our C# API into a clean type structure. This puts us as the consumer of _Strawberry Shake_ in the driver seat.

**We** decide what data we **need** and how they are **shaped**.

> We are currently looking into how we can aggregate data and flatten the type structure. We initially thought about introducing some directives to flatten the type structure. But as we thought further on that and we really felt we want to have something like [lodash](https://github.com/APIs-guru/graphql-lodash). We are still discussing on what we want to do here. So stay tuned.

Let's make one more tweak to our query and then we get this example running.

```graphql
query getHero($episode: Episode) {
  hero(episode: $episode) {
    ...SomeDroid
    ...SomeHuman
  }
}

fragment SomeHuman on Human {
  ...HasName
  homePlanet
}

fragment SomeDroid on Droid {
  ...HasName
  primaryFunction
}

fragment HasName on Character {
  name
}
```

By defining a variable with our operation we now can pass in arguments. This makes our operation re-usable and a good interface with the server. GraphQL servers can pre-compile and optimize those parametrized query documents.

```csharp
public interface IStarWarsClient
{
    Task<IOperationResult<IGetHero>> GetHeroAsync(
        Optional<Episode> episode = default,
        CancellationToken cancellationToken = default);
}
```

OK, let's get it running and then go into more details.

By default the generator will also generate dependency injection code for `Microsoft.Extensions.DependencyInjection`.

In order to get our client up and running we just have to set up a dependency injection container.

> Note: You can shut off dependency injection generation with a _MSBuild_ property. The client can also be instantiated with a builder or by using a different dependency injection container.

Replace your `Program` class with the following code.

```csharp
class Program
{
    static async Task Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddHttpClient(
            "StarWarsClient",
            c => c.BaseAddress = new Uri("http://localhost:5000/graphql"));
        serviceCollection.AddStarWarsClient();

        IServiceProvider services = serviceCollection.BuildServiceProvider();
        IStarWarsClient client = services.GetRequiredService<IStarWarsClient>();

        IOperationResult<IGetHero> result = await client.GetHeroAsync(Episode.Newhope);
        Console.WriteLine(((ISomeDroid)result.Data.Hero).Name);

        result = await client.GetHeroAsync(Episode.Empire);
        Console.WriteLine(((ISomeHuman)result.Data.Hero).Name);
    }
}
```

Run the console and it will output the following;

```bash
R2-D2
Luke Skywalker
```

That is quite awesome. The client is easy to setup and easy to use. We just had to initialize our project and write a GraphQL query document and everything was generated so that we can focus on using our GraphQL endpoint instead of writing a bunch of code that we do not want to actually write. Moreover, we only get the types from the schema that we actually use in our query documents, that means we are not burdened with all the schema types and fields and so on that we do not need and do not want.

_Strawberry Shake_ let`s you take all the power of GraphQL and package it up into a fully typed client that works well with .NET. It does not limit you by introducing a new programming model like Linq or some other .NET API, instead _Strawberry Shake_ makes **GraphQL a first class citizen in the .NET world**.

OK, now let us have a look at the result object since we also carefully discussed how we expose results to the consumer.

The result of an operation can be a `IOperationResult<T>` or a `IResponseStream<T>`.

The operation result represents a single result and we expose the GraphQL result structure as specified in the GraphQL spec.

This means that we give you a chance to take advantage of partial results in case of errors. However, we also make it easy to raise an exception in case of any error with the `EnsureNoErrors` method on the result object. This is kind of like with responses from a `HttpClient`.

Also, we allow you to have full access to provider specific data that is included in a dictionary called `Extensions`. This for instances is used in cases like active persisted queries or other provider specific extensions.

## Renaming Type Elements

Did you notice the enum type `Episode.Newhope` in the upper example. This really is not nice to see as a C# developer :). Since the generator is built on top of the stitching API we easily can amend things like that in order to make our client API nice to use.

So, before we go into subscriptions let`s fix that :)

First, add another GraphQL file and call it `StarWars.Extensions.graphql`. Again, the name does not really matter, you could call it `Foo.graphql` and _Strawberry Shake_ would also handle it correctly.

GraphQL allows to extend types with the `extend` keyword in the GraphQL SDL. In the example below we extend the `Episode` enum and add a directive (annotation) called `@name`. The `@name` directive allows us to provide the generator with a name for a type element that we actually want to use in our C# client API.

Now add the following type extension to the GraphQL file `StarWars.Extensions.graphql`:

```graphql
extend enum Episode {
  NEWHOPE @name(value: "NewHope")
}
```

Rebuild your project and voila ... `Episode.NewHope` is now correctly cased.

The nice thing is that we are just describing what we want to change in this schema extension file, so every time you update the server schema, we will preserve this file and reapply the type extensions to the newly downloaded schema.

##  Subscriptions

OK, OK, most of this was already in place, so let us have a look at something more challenging like subscriptions.

Subscriptions will need a state-full connection to a server through a WebSocket. There are other ways to do this like SignalR (which essentially is a socket abstraction) or gRPC or even over a standard TCP socket.

While we are in the works to get SignalR and gRPC in let us have a look at how we can do it through WebSockets.

When we started on this we found that WebSockets should be as easy as setting up the HttpClient nowadays. So, we have introduced a new interface called `IWebSocketClientFactory`. But just having a factory is not enough since we want to maybe pool socket connections and reuse those with multiple subscriptions.

With the solution that we are introducing with version 11.0.0-preview.58 we are making WebSockets super simple to setup, and we will do all the hard parts like reusing the connection and things like that without you ever noticing it.

Let us have a look at how we can get subscriptions to work.

The first thing we have to do is going back to our query document. The _Star Wars_ server has one subscription that is raised whenever a review is written. So, let’s use it and add it to our query file.

```graphql
query getHero($episode: Episode!) {
  hero(episode: $episode) {
    ...SomeDroid
    ...SomeHuman
  }
}

subscription onReviewCreated(episode: $episode) {
  onReview(episode: $episode) {
    commentary
    stars
  }
}

fragment SomeHuman on Human {
  ...HasName
  homePlanet
}

fragment SomeDroid on Droid {
  ...HasName
  primaryFunction
}

fragment HasName on Character {
  name
}
```

Now, lets rebuild our project and then look at the client interface.

```csharp
public interface IStarWarsClient
{
    Task<IOperationResult<IGetHero>> GetHeroAsync(
        Optional<Episode> episode = default,
        CancellationToken cancellationToken = default);

    Task<IResponseStream<IOnReviewCreated>> OnReviewCreatedAsync(
        Optional<Episode> episode = default,
        CancellationToken cancellationToken = default);
}
```

Our client has now a new method that returns a response stream. A response stream is essentially an `IAsyncEnumerable` that will loop over the subscription event stream until the stream completes or the client disposes the stream.

Now let us put everything together. First we need to configure the WebSocket client connection.

```csharp
services.AddWebSocketClient(
    "StarWarsClient",
    c => c.Uri = new Uri("ws://localhost:5000/graphql"));
```

This kind of looks exactly the way we would configure an HttpClient and it hides all the complex logic about connecting and pooling WebSocket connections. It also lets you easily intercept the connect process to include authentication logic.

The next thing we need to do to consume data from subscriptions is to read from our event stream.

```csharp
class Program
{
    static async Task Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddHttpClient(
            "StarWarsClient",
            c => c.BaseAddress = new Uri("http://localhost:5000/graphql"));
        serviceCollection.AddStarWarsClient();

        IServiceProvider services = serviceCollection.BuildServiceProvider();
        IStarWarsClient client = services.GetRequiredService<IStarWarsClient>();

        var stream = await client.OnReviewCreatedAsync(Episode.NewHope);

        await foreach (var result in stream)
        {
            result.EnsureNoErrors();
            Console.WriteLine(result.Data!.OnReview.Commentary);
        }
    }
}
```

If you look at the code above it looks so easy how you can use subscription with _Strawberry Shake_, it almost looks no different from fetching a simple query with the `HttpClient`. This is exactly what we want the experience to be, simple but when you want to get into the pluming then we will allow you to easily intercept and extend the whole pipeline.

So, in order to try subscriptions out in your example open a tool like playground and the fire the following query against the local GraphQL Server while your console app is running.

```graphql
mutation {
  createReview(
    episode: NEWHOPE
    review: { commentary: "Awesome movie.", stars: 5 }
  ) {
    commentary
    stars
  }
}
```

As soon as you trigger the above mutation the client will print the commentary to the console, it is kind of like magic :)

## Custom Scalars

The mean thing with all these examples that I posted in this blog is that I am only using the _Star Wars_ example. The _Star Wars_ uses no custom scalars and is super simple to use. That is the reason why I like to use it for demos, because people get easily on board with it. But it also is frustrating when you want to go deeper. This is especially true with custom scalars.

_Strawberry Shake_ supports an array of built-in scalars that go beyond the GraphQL spec. But still if you download the GitHub schema for instance you will get a ton of custom scalars.

With the current version we have made dealing with custom scalars a lot easier. First, if we do not know a scalar, then we will treat it as a `String`. While this is not always what you want, it lets you get started quickly and then change things when you really need them to change.

Let us have a look at how we can bring in a custom scalar. For this example, let us assume we have a scalar called `ByteArray`. This scalar serializes a `System.Byte[]` to a base64 string. This is easy enough. So on the client side we want the generator to generate models that expose `System.Byte[]` as property type. But in the communication between server and client the type shall be serialized as base64 string.

So, in order to give the generator a hint about these things we need to extend our schema. We would need to create a GraphQL file that holds our schema extensions (basically like with the enum example, where we renamed the enum value). The same way we can extend enums we can extend other types. In this case we want to annotate a scalar type.

```graphql
extend scalar ByteArray
  @runtimeType(name: "System.Byte[]")
  @serializationType(name: "System.String")
```

The above example declares that for the `ByteArray` scalar the runtime type (the type that is used in the C# models) shall be a `System.Byte[]` and that the serialization type (the type which client and server use to send the data) shall be a `System.String`. For the generator that is enough to generate everything accordingly.

We still have to implement an `IValueSerializer` to specify the logic how the type shall actually serialize and deserialize.

```csharp
public class ByteArrayValueSerializer
    : ValueSerializerBase<byte[], string>
{
    public override string Name => "ByteArray";

    public override ValueKind Kind => ValueKind.String;

    public override object? Serialize(object? value)
    {
        if (value is null)
        {
            return null;
        }

        if (value is byte[] b)
        {
            return Convert.ToBase64String(b);
        }

        throw new ArgumentException(
            "The specified value is of an invalid type. " +
            $"{ClrType.FullName} was expected.");
    }

    public override object? Deserialize(object? serialized)
    {
        if (serialized is null)
        {
            return null;
        }

        if (serialized is string s)
        {
            return Convert.FromBase64String(s);
        }

        throw new ArgumentException(
            "The specified value is of an invalid type. " +
            $"{SerializationType.FullName} was expected.");
    }
}
```

The serializer can be added as a singleton and will be automatically integrated by the generated client.

```csharp
services.AddSingleton<IValueSerializer, ByteArrayValueSerializer>();
```

> We are refining how those serializers are registered. This is important for cases where one wants to have multiple clients with different kinds of serializers. I know this is rare but still this should work. The coming versions of _Strawberry Shake_ will fine tune this.

## Digging Deeper

Apart from being able to add custom scalars we might want to dig deeper and allow new scenarios with our client like persisted queries. It is needles to say that we will add persisted query support out of the box. But it is also a good example to use to show how we can enable advance server / client protocols with _Strawberry Shake_.

The way we built-in things like that is by providing an operation middleware. This basically works like the query middleware in the server on the request level.

_Strawberry Shake_ allows us to swap out the default operation execution pipeline and add our own custom operation execution pipeline.

In order to setup a custom operation execution pipeline you can use for instance the `HttpPipelineBuilder`. Each transport has it`s own transport specific pipeline since the protocol between socket communication and stateless communication is quite different.

```csharp
serviceCollection.AddSingleton<OperationDelegate>(
    sp => HttpPipelineBuilder.New()
        .Use<CreateStandardRequestMiddleware>()
        .Use<CustomMiddleware>()
        .Use<SendHttpRequestMiddleware>()
        .Use<ParseSingleResultMiddleware>()
        .Build(sp));
```

```csharp
public class CustomMiddleware
{
    private readonly OperationDelegate _next;
    private readonly IOperationSerializer _service;

    public CustomMiddleware(
        OperationDelegate next,
        ISomeCustomService service)
    {
        _next = next ?? throw new ArgumentNullException(nameof(next));
        _service = service ?? throw new ArgumentNullException(nameof(service));
    }

    public async Task InvokeAsync(IHttpOperationContext context)
    {
        // the custom middleware code
        await _next(context);
    }
}
```

## Generation Options

By default _Strawberry Shake_ generates dependency injection code for `Microsoft.Extensions.DependencyInjection` this can be switched of by adding the following `MSBuild` property `<GraphQLEnableDI>false</GraphQLEnableDI>`.

The generator will automatically detect if you are using C# 8.0 with nullable reference types or if you are using an older version of C#.

You can use the following `MSBuild` properties to control this.

```xml
<PropertyGroup>
  <LangVersion>8.0</LangVersion>
  <Nullable>enable</Nullable>
</PropertyGroup>
```

We also by default take the root namespace from the project for generating files. You can however override this by providing the `<BerryNamespace />` property. However, we will change this to an item group soon in order to also enable multiple clients in a single project to use different namespaces.

```xml
<PropertyGroup>
  <BerryNamespace>$(RootNamespace)</BerryNamespace>
</PropertyGroup>
```

## Dependency Injection

The client API can be used with other dependency injection container and also without dependency injection at all.

We initially had a limited builder API for this but decided to give it a do over. So, at the moment you could look at the generated dependency injection code and build your own integration.

We will allow with future build to add custom generators that can provide additional code for custom use cases. The way that would work is that such a generator would sit in a NuGet package that is being added to the project. The custom generator would register its generators to an item group and _Strawberry Shake_ would pick those up and integrate them. These custom generators however are somewhere in the version 12 time-frame.

## Roadmap

What are our next steps on _Strawberry Shake_ and when are we planning to release it?

We have some more ground to cover before we have this version complete.

1. MSBuild Integration
   We are working on making the _MSBuild_ integration better. There are still instances with _VSCode_ where you have to compile twice. This is OK for a preview,but we are on it and think that in the next view preview builds we will have this fixed. With _Visual Studio for Windows_ you can already enjoy design time code generation. This means that when you save a GraphQL file the generator will update the C# files.

1. Tooling
   We are heavy at work on _Banana Cake Pop_ which is our GraphQL IDE that will help you write and analyze GraphQL queries.
   We plan to use what we have done for _Banana Cake Pop_ to create a nice integration with _VSCode_. We want to have a rich integration with which you can work on huge schemas.

   Beyond _VSCode_ we are looking at writing a nice integration with _Visual Studio for Windows_ and _Visual Studio for macOS_ that will make _Strawberry Shake_ and _GraphQL_ a first-class citizen in Microsoft IDEs.

   We hope to deliver all of this in the version 11 time-frame.

1. Persisted Query Support
   Persisted queries are one of our very next features that we will add to the client. We want to allow the same flows that we support on the server side.

1. Batching Support
   Batching support with the `@export` directive is as well planned for the initial release of _Strawberry Shake_.

1. Code Generation
   The current code generation produces quite nice code, but it can produce issues where the types from your own project collide with the generated code. With the next view builds we will add an option to use full type names in those cases.
   Also, we will add the code generation attribute to the generated files. So there are refinements going on in this area.

1. Defer / Stream
   We are planning to add support for defer and stream to the client. This feature depends on our server implementation so we will have to see how far we are on execution plans before we can start on it for the client.

I hope you enjoy what we are building. We are tying to bring GraphQL on .NET to the next level. While we still are miles away from what the JavaScript world has to offer we hope to close these gaps over the next year and even pull ahead in some areas. We love GraphQL and are passionate about it. We strongly believe that with our newest member _Strawberry Shake_ we really can make things like _Xamarin_ and _Blazor_ so much better. We have planned a lot more and hope to bring data fetching in .NET to a whole new level over the next year. Ideally you just want to declare in your .NET component the data that you need and all the client logic is inferred from that, kind of the way relay works in JavaScript.

If you want to get into contact with us head over to our slack channel and join our community.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Building a .NET GraphQL Client API]]></title>
        <id>https://chillicream.com/blog/2019/09/27/strawberry-shake</id>
        <link href="https://chillicream.com/blog/2019/09/27/strawberry-shake"/>
        <updated>2019-09-27T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
**This post has been updated, please head over to the newer post [here](/blog/2019/11/25/strawberry-shake_2).**

We for a while now have two big GraphQL server projects on the .NET platform. So, if you just want to build a decent GraphQL server you can pick and choose between _GraphQL .NET_ or Hot Chocolate.

If you are looking at consuming a GraphQL server in your _Blazor_ or _Xamarin_ application, then things are not so promising. You can either go with a bare bone client from the _GraphQL .NET_ project or you can decide to go it alone and build on `HttpClient`.

After the version 10 release of our Hot Chocolate GraphQL server we have started to build a new GraphQL client API that is more in line with how people in JavaScript consume GraphQL endpoints.

## Introduction

Before we get into it let me first outline what our goals for our approach are:

- Strongly typed API.
- Define the API with GraphQL.
- No magic strings.
- Everything compiles.
- Customizable request pipelines.
- Support for local resolvers.
- Support for custom scalars.

The preview that we released today is a prototype that has a ton of bugs and is meant at the moment to get feedback. Starting with this preview we will now release every other day a new preview and think that we will release this new API with version 11 of Hot Chocolate.

## Getting Started

Let us have a look at how we want to tackle things with _Strawberry Shake_. For this little walk-through I will use our [_Star Wars_ server example](https://github.com/ChilliCream/graphql-platform/tree/master/examples/AspNetCore.StarWars).

If you want to follow along then install the [.NET Core 3 SDK](https://dotnet.microsoft.com/download/dotnet-core/3.0) . We are also supporting other .NET variants but for this example you will need the .NET Core 3 SDK.

Before we can start let us clone the Hot Chocolate repository and start our _Star Wars_ server.

```bash
git clone https://github.com/ChilliCream/graphql-platform.git
cd hotchocolate
dotnet run --project examples/AspNetCore.StarWars/
```

Now that we have our _Star Wars_ server running, lets create a folder for our client and install the _Strawberry Shake_ tools.

```bash
mkdir berry
dotnet new tool-manifest
dotnet tool install StrawberryShake.Tools --version 11.0.0-preview.35 --local
```

In our example we are using the new .NET CLI local tools. `dotnet new tool-manifest` creates the tools manifest which basically is like a packages.config and holds the information of which tools in which version we are using.

The next command `dotnet tool install StrawberryShake.Tools --version 11.0.0-preview.35 --local` installs our _Strawberry Shake_ tools.

Next we need a little project. Let’s create a new console application so that we can easily run and debug what we are doing.

```bash
dotnet new console -n BerryClient
cd BerryClient
dotnet add package StrawberryShake --version 11.0.0-preview.35
dotnet add package Microsoft.Extensions.Http --version 3.0.0
dotnet add package Microsoft.Extensions.DependencyInjection --version 3.0.0
```

OK, now that we have a project setup lets initialize the project by creating a local schema. Like with _relay_ we are holding a local schema file that can be extended with local types and fields. Our _Graphql_ compiler will use this schema information to validate the queries.

> For the next step ensure that the _Star Wars_ _GraphQL_ server is running since we will fetch the schema from the server.

```bash
dotnet graphql init ./StarWars http://localhost:5000/graphql -n StarWars
```

The init command will download the schema as GraphQL SDL and create a config to refetch the schema. Also, the config contains the client name. The client name defines how the client class is and interface is named.

> Note: You can pass in the token and scheme if your endpoint is authenticated. There is also an update command to update the local schema.

The configuration will look like the following:

```json
{
  "Schemas": [
    {
      "Name": "StarWars",
      "Type": "http",
      "File": "StarWars.graphql",
      "Url": "http://localhost:5000/graphql"
    }
  ],
  "ClientName": "StarWarsClient"
}
```

OK, now let’s get started by creating our first client API. For this open your editor of choice. I can recommend using VSCode for this at the moment since you will get GraphQL highlighting. As we move forward, we will refine the tooling more and provide proper IntelliSense.

Now let us create a new file in our `StarWars` folder called `Queries.graphql` and add the following query:

```graphql
query getFoo {
  foo
}
```

Now build your project.

```bash
dotnet build
```

When we now compile, we get an _MSBuild_ error on which we can click in VSCode and we are pointed to the place in our query file from which the error stems from. The error tells us that there is no field `foo` on the `Query` type.

```bash
/Users/michael/Local/play/berry/BerryClient/StarWars/Queries.graphql(2,3): error GQL: The field `foo` does not exist on the type `Query`. [/Users/michael/Local/play/berry/BerryClient/BerryClient.csproj]
```

Your GraphQL query document is not just a string, it properly compiles and is fully typed. Let's change our query to the following and compile again:

```graphql
query getFoo {
  hero {
    name
  }
}
```

```bash
dotnet build
```

Now our project changes and we get a new `Generated` folder that has all the types that we need to communicate with our backend.

Let us have a look at our client interface for a minute.

```csharp
public interface IStarWarsClient
{
    Task<IOperationResult<IGetFoo>> GetFooAsync();

    Task<IOperationResult<IGetFoo>> GetFooAsync(
        CancellationToken cancellationToken);
}
```

The client will have for each operation in your query file one method that will execute that exact operation.

Since, with GraphQL you essentially design your own service API by writing a query document your types can become quite messy very quickly.

In order to avoid getting a messy API and to give you control over how your C# API will look like we are using fragments to infer types.

Let us redesign our query with fragments and make it a bit more complex.

```graphql
query getHero {
  hero {
    ...SomeDroid
    ...SomeHuman
  }
}

fragment SomeHuman on Human {
  ...HasName
  homePlanet
}

fragment SomeDroid on Droid {
  ...HasName
  primaryFunction
}

fragment HasName on Character {
  name
}
```

The fragments will yield in the following type structure:

```csharp
public interface ISomeHuman
    : IHasName
{
    string HomePlanet { get; }
}

public interface ISomeDroid
    : IHasName
{
    string PrimaryFunction { get; }
}

public interface IHasName
{
    string Name { get; }
}
```

As we go forward, we will introduce some directives that will let you further manipulate the types like `@spread`. `@spread` will let you spread the fields of a child object over its parent object.

Let's make one more tweak to our query and then we get this example running.

```graphql
query getHero($episode: Episode) {
  hero(episode: $episode) {
    ...SomeDroid
    ...SomeHuman
  }
}

fragment SomeHuman on Human {
  ...HasName
  homePlanet
}

fragment SomeDroid on Droid {
  ...HasName
  primaryFunction
}

fragment HasName on Character {
  name
}
```

By defining a variable with our operation we now can pass in arguments into our operation.

```csharp
public interface IStarWarsClient
{
    Task<IOperationResult<IGetHero>> GetHeroAsync(
        Episode episode);

    Task<IOperationResult<IGetHero>> GetHeroAsync(
        Episode episode,
        CancellationToken cancellationToken);
}
```

OK, let's get it running and then go into more details. By default the generator will also generate dependency injection code for `Microsoft.Extensions.DependencyInjection`. In order to get our client up and running we just have to set up a dependency injection container.

> Note: You can shut of dependency injection generation with a _MSBuild_ property. The client can also be instantiated with a builder or by using a different dependency injection container.

Replace you `Program` class with the following code.

```csharp
class Program
{
    static async Task Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddDefaultScalarSerializers();
        serviceCollection.AddStarWarsClient();
        serviceCollection.AddHttpClient("StarWarsClient")
            .ConfigureHttpClient(client =>
                client.BaseAddress = new Uri("http://localhost:5000/graphql"));

        IServiceProvider services = serviceCollection.BuildServiceProvider();
        IStarWarsClient client = services.GetRequiredService<IStarWarsClient>();

        IOperationResult<IGetHero> result = await client.GetHeroAsync(Episode.Newhope);
        Console.WriteLine(((ISomeDroid)result.Data.Hero).Name);

        result = await client.GetHeroAsync(Episode.Empire);
        Console.WriteLine(((ISomeHuman)result.Data.Hero).Name);
    }
}
```

Run the console and it will output the following;

```bash
R2-D2
Luke Skywalker
```

## Generation Options

By default, _Strawberry Shake_ will generate C# 7.3 without nullable reference types. We also by default generate dependency injection code for `Microsoft.Extensions.DependencyInjection`.

If the generator detects that you are using C# 8.0 and enabled support for nullable reference types, then the generate is switching to produce code with nullable reference types.

```xml
<PropertyGroup>
  <LangVersion>8.0</LangVersion>
  <Nullable>enable</Nullable>
</PropertyGroup>
```

In order to manually overwrite those defaults, we added some build properties that you can use.

```xml
<PropertyGroup>
  <BerryLangVersion>CSharp_8_0</BerryLangVersion>
  <BerryEnableDI>true</BerryEnableDI>
  <BerryNamespace>$(RootNamespace)</BerryNamespace>
</PropertyGroup>
```

## Dependency Injection

The client API can be used with other dependency injection container and also without dependency injection at all.

The execution pipeline can be extended or completely swapped out. This is an important aspect of _Strawberry Shake_ since this allows us to add cross-cutting concerns like auto-batching, persisted query support and other features.

```csharp
private static IServiceCollection TryAddDefaultHttpPipeline(
    this IServiceCollection serviceCollection)
{
    serviceCollection.TryAddSingleton<OperationDelegate>(
        sp => HttpPipelineBuilder.New()
            .Use<CreateStandardRequestMiddleware>()
            .Use<SendHttpRequestMiddleware>()
            .Use<ParseSingleResultMiddleware>()
            .Build(sp));
    return serviceCollection;
}
```

When used with Microsoft's dependency injection container then we are also using the `IHttpFactory` which allows for integration with polly and others.

## Roadmap

We are still heavy at work on the client and generator and this first preview is where we invite people to try it out in order to get feedback.

There is still a ton of work to be done and a ton of tests to be written to get this up for prime time.

We will have I think two more weeks to work on the generator to iron out generation issues. We will add documentation tags and things like that over the next view weeks.

Also, there are some generator directives that should show up next week like `@spread`, `@name` and `@type`.

Moreover, we will add support for local schema stitching. We already integrated the stitching engine into the generator but have a view more things to do before this works properly.

Local schema stitching will allow you to focus on your client API without having to wonder which client you have to use for which service. Also, it will allow you to form one local schema from which you can generate the types exactly like you want them.

Furthermore, there are execution features that we are currently adding like auto-batching and manual-batching. Support for subscription, ´@defer´ and persisted queries are also coming.

Last but not least we have a lot to do on the tooling side. We want to have a nice integration with all Visual Studios and are working on things like live generation. You can get a feeling for this by doing `dotnet watch build`. We have updated the watch information to exclude the generated files and include the _GraphQL_ files.

Please check it out and give us feedback so we can adjust and refine the experience further.

If you want to get into contact with us head over to our slack channel and join our community.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 10.0.0]]></title>
        <id>https://chillicream.com/blog/2019/08/14/hot-chocolate-10.0.0</id>
        <link href="https://chillicream.com/blog/2019/08/14/hot-chocolate-10.0.0"/>
        <updated>2019-08-14T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we have released version 10 of Hot Chocolate. We originally started building version 9.1 which grew bigger and at one point became version 10. We have focused a lot on our server implementation. But let me walk you through our latest release.

## Filters

So, while we focused a lot on the server implementation, we also added some nice features to the GraphQL core. The main feature we added here is the new filter API.

Filters let you query your backend with a powerful query input type that translates into native database queries.

```graphql
{
  persons(
    where: { OR: [{ firstName_starts_with: "abc" }, { lastName: "def" }] }
  ) {
    firstName
    lastName
  }
}
```

The above query would translate to a something like `persons.Where(t => t.FirstName.StartsWith("abc") || t.LastName == def)`.

This works out of the box if you are using `IQueryable`.

All you have to do in your schema type is to add a `UseFiltering` to your field descriptor.

```csharp
public class QueryType
  : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor.Field(t => t.GetPersons(default))
          .Type<ListType<PersonType>>()
          .UseFiltering();
    }
}
```

Filters are easily combined with our pagination.

```csharp
public class QueryType
  : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor.Field(t => t.GetPersons(default))
          .UsePaging<PersonType>()
          .UseFiltering();
    }
}
```

Also, it is possible to customize filters by describing what fields are filterable and what operators are allowed.

```csharp
public class QueryType
  : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor
          .Field(t => t.GetPersons(default))
          .UsePaging<PersonType>()
          .UseFiltering(d => d.Ignore(t => t.LastName));
    }
}
```

If you want to use the same filter multiple times all over your schema you can also describe the filter input type separately.

```csharp
public class PersonFilterType
    : FilterInputType<Person>
{
    protected override void Configure(
        IFilterInputTypeDescriptor<Foo> descriptor)
    {
        descriptor
            .BindFieldsExplicitly()
            .Filter(t => t.Name)
            .BindOperationsExplicitly()
            .AllowEquals().Name("equals").And()
            .AllowContains().Name("contains").And()
            .AllowIn().Name("in");
    }
}
```

And then use this filter type where you need it.

```csharp
public class QueryType
  : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor
          .Field(t => t.GetPersons(default))
          .UsePaging<PersonType>()
          .UseFiltering<PersonFilterType>());
    }
}
```

The nice thing here is that the filter works out of the box on `IQueryable` and `IEnumerable` so you can use it for database queries as well as for in-memory lists.

With version 10 of Hot Chocolate we are supporting filters on scalar fields. But we are already working on support for object filters and enumerable filters.

Also, we are working on sorting which should be included in the first preview of version 11.

If you want to give input or follow our work, you can head over to these four issues that will be coming with version 11.

- [Object Filters #921](https://github.com/ChilliCream/graphql-platform/issues/921)
- [IEnumerable Filters #922](https://github.com/ChilliCream/graphql-platform/issues/922)
- [Sorting #923](https://github.com/ChilliCream/graphql-platform/issues/923)
- [Aggregations #924](https://github.com/ChilliCream/graphql-platform/issues/924)

> If you want to check out more about filters head over to our [documentation](https://hotchocolate.io/docs/filters).

Let me also thank [Pascal](https://github.com/PascalSenn) for his awesome work on this one.

## Subscriptions

Subscriptions was another big investment that we took for this release.

### Redis

For the core API we introduced a _Redis_ subscription provider. This means that you now can use _Redis_ as a pub/sub system without a hassle.

```csharp
var configuration = new ConfigurationOptions
{
    Ssl = true,
    AbortOnConnectFail = false,
    Password = password
};

configuration.EndPoints.Add("host:port");

services.AddRedisSubscriptionProvider(configuration);
```

That\`s all you have to do to connect the query engine with `Redis`.

**So why should we want to use `Redis` anyway.**

The thing with in-memory subscriptions is that they will only work reliable if you have one instance of Hot Chocolate. When you have deployed multiple instance of _Hot Chocolate_ or if you are scaling on demand with a massive amount of subscribers then you want to make sure that your pub/sub system scales and that mutations executed on one server raise an event on another one.

But there is more, sometimes you want to raise an event without triggering a mutation, maybe there was an event somewhere in your infrastructure that you want to relay as a GraphQL subscription, this can also be done through an external pub/sub system like Redis.

With version 11 We will add _Kafka_ and _Azure EventHub_ support and are also looking into other pub/sub systems, so that you can use whatever feels best to you.

### Pipelines

We also rebuild the whole WebSocket handling in the server by using the new `Pipeline` API that Microsoft introduced to .Net. This makes it now super-efficient how we handle the messages with our new `UTF8RequestParser`. But we are not done here and will with version 11 further optimize our parser to work even better with pipelines.

> If you want to check out more about subscriptions head over to our [documentation](https://hotchocolate.io/docs/code-first-subscription).

Let me also thank [Gabriel](https://github.com/glucaci) for his great work on subscriptions.

## Batching

Another big feature we have invested in was batching. When we started on this one we reflected a lot about how we want to do this and if we really need this one. In the end we decided that batching could enable great scenarios and is worth adding to our server.

When Lee Byron initially showed batching off, he explained that this would be useful in cases where you want to fetch important data first and delay more expensive data without needing to issue two separate calls.

They had this example that they want to fetch the news stream of a given user and the comments should appear once those are available.

`POST /graphql?batchOperations=[NewsFeed, StoryComments]`

```graphql
query NewsFeed {
  stories {
    id @export(as: "ids")
    actor
    message
  }
}

query StoryComments {
  stories(ids: $ids) {
    comments(first: 2) {
      actor
      message
    }
  }
}
```

In the above query we would first fetch the stories, collect all the story ids and use these as an input to the next query to fetch all the comments for the former stories.

The nice thing is that this is done in one HTTP call and as soon as query one is executed, we will write the result into the stream and the client can already work with that data while waiting for the second result.

This all is working over one HTTP call without WebSockets and is super-efficient.

**Why did we question its use?**

The thing is that with version 11 we will introduce `@defer` which will allow you to do the following:

```graphql
query NewsFeed {
  stories {
    id @export(as: "ids")
    actor
    message
    ... @defer {
      comments(first: 2) {
        actor
        message
      }
    }
  }
}
```

The fragment that is annotated with `@defer` will be deferred to when it is ready. This means you can write queries much cleaner with this and reap the same benefits.

**What makes batching a great feature then?**

First, you can defer query parts with this now in version 10.

Second, I think batching is very interesting with mutations where you can write complex mutation flows that use the results of one mutation to feed data in the next mutation. The ability to export result data into variables lets you write nice data flows.

Look at how easy you can export data as variable by just adding `@export`.

```graphql
{
  foo {
    bar @export
  }
}
```

What\`s important to know here is that you also can export objects that will convert to a matching input type.

```graphql
{
  foo @export(as: "something") {
    bar
  }
}
```

Third, we also wanted to support Apollo batching where Apollo collects all the queries of a client in a certain time window and sends those in one request to our server. One batch will share the _DataLoader_ instances which means that the batch request will be faster than sending them in separately.

> We are supporting operation batching and request batching and if you would like to know more about it head over to our [documentation](https://hotchocolate.io/docs/batching).

## Persisted Queries

With version 10 we now support persisted queries. With persisted queries you can add well-known queries to a second-level cache. All queries stored in there are considered valid.

**So, what is this for?**

Persisted queries are faster, since we validate those only once. Moreover, you do not need to send us the query every time, you can instead just send the query name and the server will look up the query and execute it. This can dramatically improves performance, reduces bandwidth and memory usage.

This makes it feasible to use a simple `GET` request instead of a `POST` request which can also have benefits when using things like CDNs.

`GET http://example.com/graphql?namedQuery=QUERYNAME&variables={"id":"QVBJcy5ndXJ1"}`

We have opted to support both active persisted queries and persisted queries.

> Read more about this [here](https://hotchocolate.io/docs/persisted-queries);

## Server Modularization

With Version 10 we have now a modularized server implementation. That each middleware is placed in its own package. You can still just add our `HotChocolate.AspNetCore` or `HotChocolate.AspNetClassic` package and do not worry what is included in your server. But with version 10 you could now just add some of the middleware like maybe just HTTP-GET or HTTP-POST. This way if you do not use for instance subscriptions than there will not even be the code for subscriptions.

With version 10 we have the following middleware available:

- HotChocolate.AspNetCore.HttpPost
- HotChocolate.AspNetCore.HttpGet
- HotChocolate.AspNetCore.HttpGetSchema
- HotChocolate.AspNetCore.Subscriptions
- HotChocolate.AspNetCore.Authorization

> Read more about this right [here](https://hotchocolate.io/docs/aspnet)

## UTF-8 Request Parser

With GraphQL most requests are provided as `JSON` that contains the request as an escaped string. This is kind of bad for performance since we first parse the `JSON` then take the string and parse again a string that we actually do not need.

With the new _UTF-8 request parser_ we can finally just read the binary request stream and parse the JSON and the GraphQL request in one go. But there is more, we have given our new UTF-8 request parser access to our document cache, meaning while we parse the JSON request and hit the part were the GraphQL request is, we can look up if this query is already cached. This dramatically reduces memory usage and performance since we will not consume the query property anyway.

![Request Parser Memory](request_parser_mem.png)

The new request parser does only allocate 1/3 of the memory that GraphQL-DotNet uses with it\`s combination of JSON.Net and it\`s string based GraphQL parser.

The Hot Chocolate GraphQL parser is twice as fast than the GraphQL-DotNet parser on average. The whole request pipeline is 3 times faster on average, but we are not done yet and will double down on performance with the new query execution plans and our updated syntax tree that allows to further reduce string usage.

## Everything Else

With version 10 we added a ton of bug fixes and also, we added a lot of API improvements that will make your day to day business so much easier.

Like now you can add error filter to the dependency injection instead of registering them with the execution builder.

```csharp
services.AddErrorFilter<MyCustomErrorFilter>();
```

The same goes for class _DataLoader_.

```csharp
services.AddDataLoader<MyCustomDataLoader>();
```

When you use this extension, we also will add the _DataLoader_ registry.

Also, we refined things like the schema builder so that you can in place now define all the types:

```csharp
SchemaBuilder.New()
  .AddEnumType(d => d.Name("MyEnum").Value("FOO))
  ...
  .Create();
```

There are so many little things that can make your day :)

## Version 11

Like with every release we are giving a little outlook for the next version. As the releases are fluid, we are sometimes moving things around.

We want to really focus on two major topics with the next release.

## Query Execution Plans

We originally planned for this one for version 10 (aka version 9.1) but decided that the current set of new features is already a good version that is worth to release. But with the next release this is one of the two things we really will focus on. With this in place we will double down on performance and will introduce features like `@defer` and `@stream`.

Moreover, this one will be the backbone of our new stitching layer that will bring lots of new features to schema stitching.

## Client API

The second thing we already started work on is a client API for .NET Core. We are currently experimenting with how we design this new piece of API. We have started a discussion around this in our slack channel and will start with some coding soon.

## Banana Cake Pop

**Oh, didn't you forget something?**

Yes, yes originally, we had planned to release _Banana Cake Pop_ alongside this version. We ran into some performance issues with the tree we originally selected when using large schemas with more than 1000 types.

We have now started to write the tree component ourselves which is taking some extra time. We already see that we can handle now massive schemas far beyond 1000 types without any hiccups. But we have still lots to do on the new tree.

I hope that we can see the promised preview in the next 4 to 8 weeks. We want to release something really good and not something half-backed.

## The Other Things

We also will add more features to our filter API and make working with databases even easier.

Also, we will add more subscription provider like Kafka and EventHub.

Furthermore, we will rework our `Utf8GraphQLReader` to use `ReadOnlySequence<byte>` instead of `ReadOnlySpan<byte>` in order to make this even better work with the Pipeline API. Apart from that we will optimize the syntax tree to be able to work with raw bytes instead of strings. At the moment scalar like String, Int, Float and Enum are parsed as string representation like with the original node parser. The scalar type parses then the string into the native type. The same goes for the new UTF-8 request parser. This is unnecessary with the `Utf8Parser` and `Utf8Formatter`. We will change the AST to instead have the raw bytes. The current `Value` property will still be there but only for compatibility with tools that use the current version of the AST. The new scalar types will have access to a `ReadOnlySpan<byte>` and can decide how to efficiently parse literals.

If you want to get into contact with us head over to our slack channel and join our community.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 9.0.0]]></title>
        <id>https://chillicream.com/blog/2019/06/05/hot-chocolate-9.0.0</id>
        <link href="https://chillicream.com/blog/2019/06/05/hot-chocolate-9.0.0"/>
        <updated>2019-06-05T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we have released version 9 of Hot Chocolate. This release was mainly focused on the schema APIs and performance. Furthermore, we started work on the wider _ChilliCream GraphQL Platform_ and today you will get some insides where we are heading with this.

## Schema Builder

The schema builder API is the most visible **new** API with version 9. It provides a simpler API that is easier to extend.

```csharp
SchemaBuilder.New()
    .AddQueryType<MyQueryType>()
    .AddObjectType(d => d.Name("Foo").Field("bar").Resolver("baz))
    .ModifyConfiguration(o => o.UseXmlDocumentation = true)
    .SetSchema(d => d.Description("This is my schema."))
    .AddServices(services)
    ...
    .Create();
```

With the new API you have a lot more capabilities, but do not worry, we did not throw out the old API. You still can use `Schema.Create` to build your schema. The classic API now uses the schema builder underneath so that you should have a seamless upgrade from version 8 to version 9.

> Read more about the new schema builder [here](/blog/2019/04/12/type-system).

## Extensibility

With the new schema builder, we have opened up the type system so that it is now easily extendable. Things like our relay integration and the upcoming GraphQL filters are built upon these new APIs. It is now very easy to introduce generic schema types and translate those to GraphQL types.

```csharp
public class EdgeType<TSchemaType>
    : ObjectType<IEdge>
    where T : IOutputType
{
    protected override void Configure(
        IObjectTypeDescriptor<IEdge> descriptor)
    {
        descriptor.Name(dependency => dependency.Name + "Edge")
            .DependsOn<TSchemaType>();
    }
}
```

Moreover, we have introduced metadata support to almost every corner of the GraphQL core. This means that you can pass in context data not only into the execution pipeline but also into types, fields, arguments, directives and even into the query result. This means we let you store custom context/state objects everywhere. This makes it very easy to customize the API without introducing new base types.

```csharp
descriptor
  .Extend()
  .OnBeforeCreate(definition =>
  {
      definition.ContextData["Foo"] = "Bar";
  });
```

You can access the context data on a type object like the following:

```csharp
schema.GetType<ObjectType>("Query").ContextData.ContainsKey("Foo");
```

> Read more about extending the type system [here](/blog/2019/04/12/type-system).

## Relay

We added a lot of APIs in the past to make it easy to create relay compliant schemas. With version 9 we will now make implementing the `Relay Global Object Identification Specification` as simple as eating cake.

In order to enable general support for relay you can now opt-in like the following:

```csharp
SchemaBuilder.New()
    .EnableRelaySupport()
    ...
    .Create();
```

This will automatically add the node field to your query type and add the node resolver logic. You now just have to declare which type is a node type and you are done:

```csharp
public class EntityType
    : ObjectType<Entity>
{
    protected override void Configure(
        IObjectTypeDescriptor<Entity> descriptor)
    {
        descriptor.AsNode()
            .IdField(t => t.Id)
            .NodeResolver((ctx, id) =>
                ctx.Service<Repository>().GetEntityAsync(id));
    }
}
```

> Also see our new [documentation](https://hotchocolate.io/docs/relay) about relay support.

## Performance

Starting with this version we have begun to invest into making Hot Chocolate one of the fastest GraphQL servers out there. Do not get me wrong, we are not quite there yet, and it will be an ongoing effort for quite a while.

With version 9 we are introducing the first step on this road with our new UTF-8 GraphQL parser. This new parser is not anymore, a port of the original graphql-js parser but a re-implementation that uses the raw bytes instead of strings, meaning we are using all those nice new `Span<T>` APIs. This makes it use less memory and perform faster. The new UTF-8 GraphQL parser is the fastest and most standard compliant parser on the .Net platform.

![Lexer Memory](lexer_mem.png)

![Lexer Performance](lexer_perf.png)

![Parser Memory](parser_mem.png)

![Parser Performance](parser_perf.png)

**What do these charts mean?**

The new `Utf8GraphQLReader` is our new lexer implementation, it does not allocate any extra memory to do its work. All allocations are done on the stack which means that we produce less work for the garbage collector.

Also, we only need 1/4th of the time to lex a document compared to the `GraphQL-DotNet` lexer.

What you can also see is that the `GraphQL-DotNet` lexer is unable to lex the kitchen sink test query which is used by the reference implementation to verify that the parser and lexer implementation perform as specified.

Furthermore, the new UTF-8 GraphQL parser uses 1/3 of the memory that the `GraphQL-DotNet` parser uses, meaning that we again produce less work for the GC which means that your server has more time to execute your business logic.

**Why does the parser still allocate some memory?**

The new parser still allocates some memory since we are producing a syntax tree here. The syntax tree is still the same syntax tree we produced with our old parser implementation in order to be compatible. This is where the allocation stems from. The parser itself is a `ref struct` and lives on the stack. So, all the parser state is allocated also on the stack and is gone after the execution has finished.

**So, how do we compare to graphql-js?**

Since, graphql-js is the reference implementation all other implementations of GraphQL should compare themselves to it.

At the moment graphql-js parses round about 52000 kitchen sink queries a second on my MacBook Pro compared to our new parser that does 48000 kitchen sink queries a second.

So, with version 9.0.0 they are still a little faster.

With our new version 9.1 parser preview we are hitting about 54000 kitchen sink queries a second. While version 9 has become the fastest .Net GraphQL parser implementation version 9.1 will start to rival other platform implementations.

Apart from that we have started making our execution engine more efficient. We are just starting here and there will be a much larger investment with version 9.1 when we are introducing our new UTF-8 request parser and the new execution plans feature.

With our release today Hot Chocolate is depending on the use case at least to times faster in executing queries and uses half of the memory compared to GraphQL-DotNet. If you are using schema-first then the performance gains are more dramatic and you could look at up to 13 times faster execution performance compared to GraphQL-DotNet.

![Execution Memory](exec_mem.png)

![Execution Performance](exec_perf.png)

**What will the new UTF-8 request parser help?**

The UTF-8 request parser will be an integrated JSON and GraphQL parser that does not any longer parse first the JSON and then extract a string that is then being parsed by the GraphQL parser. The parser will be able to parse a GraphQL JSON request in one go.

Also, we will create a server benchmarking suite based on _GraphQL Bench_ so that it is more transparent what we test and how we test.

We did our performance comparison against GraphQL-DotNet version 2.4 and 3.0.0-preview-1107.

##  Documentation

As we promised in the past, we are adding more documentation with every release. With version 9 we are adding documentation for our type system and a completely new tutorial that starts from scratch and shows how to build a GraphQL server with mongo as a database. We know that the more effort we are putting into our documentation the easier we make the life for you.

With this release we have published a first draft of the new documentation and will add missing parts during this week.

## Banana Cake Pop

When we released Hot Chocolate version 8 we announced a new _Hot Chocolate Developer Tool_. Since that announcement we were heavily at work building that new tool.

Today we are announcing _Banana Cake Pop_, a new tool that will help you explore and query GraphQL schemas.

![Banana Cake Pop](banana.png)

_Banana Cake Pop_ is **NOT** built on top of GraphiQL like all the other tools but built from the ground up with **Monaco** at its heart.

We plan to invest a lot more effort into _Banana Cake Pop_ going forward. Our plan is to build this ultimate GraphQL developer tool that provides advanced schema browsing, querying GraphQL endpoints, creating runbooks and many more things.

We will provide a plugin model so that you can add your own extensions.

Moreover, as we are introducing our new schema registry with version 10 you will be able to configure your GraphQL gateway via drag&drop, see how each GraphQL server in your network performs, how long each resolver takes and how much memory a resolver uses.

We will start very soon with a private preview and as the version matures, we will release a public preview probably together with version 9.1. If you want to participate in our private preview head over to our slack channel and send a message to `@rafael`.

## Roadmap

With every release we are giving a little roadmap what we are working on and what is coming next.

As you might have noticed we have not delivered all the announced version 9 features yet. The reason for that is that we have decided to split version 9 into three releases. Version 9.0.0 focused mainly on the GraphQL core and brings all the new schema goodness with it.

### Version 9.1

With version 9.1 we will now focus mainly on the server implementation, server performance and the new GraphQL filters.

#### GraphQL Filters

GraphQL filters or as we called them before Prisma filters will allow you to configure filter objects that are executed on `IQueryable` with just a view lines of code. This will make it very easy to expose databases through GraphQL.

```csharp
public class PersonFilterType
    : FilterType<Person>
{
    protected override void Configure(IFilterDescriptor<Person> descriptor)
    {
        descriptor.Filter(t => t.Name).AllowGreaterThan() ...
    }
}
```

As with all our types we will have an approach to infer possible filters and apply them to your API. You can declare that you want to define all filters explicitly or decide to override/limit specific filters. I myself are really keen on this one since it will safe you so much code. You will be able to pipeline filters with sorting and paging which makes this super powerful.

> Follow our work on filters [here](https://github.com/ChilliCream/graphql-platform/pull/711).

#### Subscriptions

We are supporting subscriptions for a long time now, but we were never really happy with the implementation.

The implementation was rushed and is not as we would have liked to implement it. With version 9.1 we are now swapping the implementation out with one built on top of the pipeline API of .Net Core.

This will create a very nice and clean API that will perform better with less memory usage. We pushed back subscription stitching in order to first get the backend sorted out and use a lot of the new code to build the subscription client we need for the stitching layer.

> Follow our work on subscriptions [here](https://github.com/ChilliCream/graphql-platform/pull/807).

#### Execution Plans

The execution plan feature is our biggest endeavor in version 9.1 and will fundamentally change how we execute queries. As of now we are executing resolvers level by level.

With execution plans we will pre-analyze the query and create a plan that defines which part of the query should be executed in parallel, which parts of the query could be inlined and so on.

Think about `@defer`.

With `@defer` you will be able to defer the execution of parts of your query. In order to understand this let’s look at an example query:

```graphql
{
  blogpost {
    title
    text
    comments {
      user
      message
    }
  }
}
```

The above query for instance represents a query to fetch a blog post with its comments. The query engine will return this query only after the blog and the comments are resolved. This means that the blog might have long loading times if it has many comments.

What if we could send this query like it is and get the blog data immediately and the comments once they have been resolved? This would let us specify a query once and profit from **DataLoader** usage and at the same time give us the most important data quickly.

This is what `@defer` is basically for. `@defer` lets me tell the query engine that some data can be delivered later so that the query engine can prioritize on the other parts of the query.

```graphql
{
  blogpost {
    title
    text
    comments @defer {
      user
      message
    }
  }
}
```

The execution engine can now branch this comment off and resolve it independently from the original query.

Also, execution plans will help make our stitching layer more powerful by being able to map out a plan what to get first and how to fold in data.

Execution plans can be created ahead of time and can be persisted so that consecutive calls will profit.

We will have a lot more to say about execution plans as we progress with this feature.

#### Batching

We are working to introduce batching and `@export` support. Batching lets me send a couple of queries at once to the server. The queries can produce variables and consecutive queries can use those. This is super powerful when you have mutations where you need the output of one mutation to execute another mutation.

With batching you can do that without having to manage that flow on the client-side.

```js
[
  {
    query: `
      mutation ($input: TokenizeCreditCardInput!) {
        tokenizeCreditCard(input: $input) {
          paymentMethod {
            id @export(as: "id")
          }
        }
      }
    `,
    variables: { input: "..." },
  },
  {
    query: `
      mutation ($id: ID, $transaction: TransactionInput!) {
        chargePaymentMethod(input: { id: $id, transaction: $transaction }) {
          transaction {
            id
            status
          }
        }
      }
    `,
    variables: { transaction: "..." },
  },
];
```

#### APQ and PQ

Another feature that is aimed at performance and bandwidth usage is automatic persisted queries and persisted queries.

Persisted queries are queries that you have stored with the hot chocolate service before deploying your application. With relay for instance you could export all your used APIs and export those to Hot Chocolate. The Hot Chocolate server could then validate and compile those once.

The frontend on the other hand has no longer to send the query to the server that it wants to execute but could just send a hash of that query.

Each execution then would fetch the prepared and optimized query from the cache or if not already on the cache from the query storage.

This saves time and bandwidth.

While persisted queries require you to setup some build scripts that extract the queries from your frontend and store them with the Hot Chocolate server, automatic persisted queries is a flow that you could use to add queries to the storage from the deployed frontend at runtime.

The automatic persisted queries work like the following:

The frontend will always assume that the query is already persisted with the server. So, by default we will just send in the hash instead of the query itself. This means that we basically do the same thing like with persisted queries.

If the server returns an error that it has no query stored with the specified has the client will send the request again, but this time with the hash and the full query.

So, while this will cause a slower execution for the first user of a query all consecutive users will profit.

We will have an abstraction for the query storage and a default implementation that will use redis.

#### Performance

The performance focus for 9.1 will be to make the server implementation faster and use less memory.

Moreover, we want to optimize startup performance and will introduce lazy resolver compilation. This will compile resolvers on first use. You will be able to choose if you want resolvers to be compiled at startup or at first usage.

We also will add support for custom resolver compiles. This will allow you to write nice extensions and simplifications on top of the schema builder.

The main focus for performance will be our visitor implementation which is not really optimized at the moment.

#### Spec Features

Specwise we will start implementing a new draft feature allowing interfaces to implement other interfaces.

<https://github.com/graphql/graphql-spec/pull/373>

I just looked again, it is not yet draft, but we hope that this will be sorted out at the next GraphQL workgroup meeting.

### Version 9.2

Version 9.2 will mainly focus on the stitching layer and will integrate the new execution plan feature. Also, we will finally do it and integrate subscription stitching.

On the experimental side, we will deliver our new GraphQL C# client. We have already started on this one but want to have a first release ready with version 9.2. We also want to have it compatible with Blazor and show case this with the that release.

### Version 10

Version 10 will be a huge release. It will take about three to four months to complete and we might decide to split it like version 9.

Version 10 will finally introduce our long-promised schema registry and allow to stitch together schemas without needing to code. Also, we will not need your microservices to have any knowledge about the registry or that they are rewritten into a larger schema.

With version 10 we will also release a production ready version of our C# client.

Last but not least as another new addition we will support automatic database mapping. This means that you can come with your database and we will make a GraphQL server from it.

We will support two things with that, building a database with GraphQL just like Prisma does. Moreover, we will support generating a GraphQL schema from your database. So, this will be pretty interesting stuff.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 9.0.0 - Performance Improvements]]></title>
        <id>https://chillicream.com/blog/2019/05/08/performance</id>
        <link href="https://chillicream.com/blog/2019/05/08/performance"/>
        <updated>2019-05-08T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we release preview 27 of version 9 and we are heading toward RC status which we are planning to hit next week.

This post will describe what we have done since preview 9 and where we are heading.

One of the main focuses on the second part of this release was performance. Performance will stay one big focus point for us going forward. This means that every new release should be faster then the previous.

Lets have a look at what we did with version 9 and what we are planing to do in this area in the next releases.

## Parser

The version 8 parser that we have built and maintained since version 1 was a very close port of the nodejs parser of `graphql-js`. `graphql-js` is the reference implementation of _GraphQL_ and also is basically the core of _Apollo_ and _relayjs_.

The problem that we had with the approach of the parser was that it parsed a string. Basically, the parser tokenized the string which meant that there was a lot of substrings creating new strings and so on.

Each time we use the V8 parser to parse a _GraphQL_ request we basically created a lot of objects. Instead of just producing our parsed _GraphQL_ document we have created a lot of garbage for the runtime to clean up.

With version 9 we wrote the parser from scratch to be allocation free. This means that we only use memory to create our GraphQL document tree but not for the actual parsing.

In order to do that we are no longer parsing using a string but a `ReadOnlySpan<byte>`. With spans on byte we can basically read the query from a binary stream and produce the GraphQL document without producing string objects. Also, the span allows us to slice the incoming data and create new windows on the underlying memory. So, each time we slice the data, we no longer create new string objects that the GC has to get rid of. All of the GraphQL keywords in a GraphQL document that is being parsed are never transformed to a string representation, but will only be represented to the parser as one byte on which the parser makes a decision on what the parsed token means. Also, comments and descriptions will only become strings if they are consumed saving us from un-escaping those and more. On a production GraphQL server we do not have the need to consume comment tokens for instance, so we can just skip over them.

Furthermore, un-escaping strings is now much more efficient since we create the string representation just once, all the escape logic is done on the span. We still have to get a second array on which we insert the escaped data but this second byte array can be rented if to large or in the best of cases be allocated on the stack with `stackalloc`.

But again the parser will only escape a string sequence and create an actual string object if needed.

Moreover, our new parser is now a `ref struct` meaning that all the memory we allocate for the parser state is allocated on the stack.

We still will keep our old parser around and will update both parsers going forward.

But we did not stop here. Actually, the GraphQL HTTP request is really bad to be processed efficiently. So, with version 9 we are actually still parsing from a string with our new parser.

**GraphQL Request Example**:

```json
{
  "query": "...",
  "operationName": "...",
  "variables": { "myVariable": "someValue", ... }
}
```

The issue here is that we first have to parse the server request which is JSON and then can use the GraphQL query stored as string in the JSON structure to parse the actual GraphQL query document.

This means that with version 9 we are around 2 to 3 times faster than any .Net parser implementation.

But as I said we are **NOT** stopping here, we are working on a new specialized request parser that will integrate the JSON parser with the GraphQL parser. That means that we are able to read the GraphQL request directly from the network stream and parse it without any manifestation to a string object.

Version 9 will bring the new `Utf8GraphQLParser` and we will follow that up with the `Utf8GraphQLRequestParser` in version 9.1.

In our experiments we see that this new request parser is about 10 times faster then the GraphQL-DotNet parser combined with Json.Net.

Also, as a side note the version 9 parser now supports all the GraphQL draft features and represents the most GraphQL spec compliant implementation on the .Net platform.

## Resolver Compiler

With version 9 we have removed the Roslyn compiler and are now using the expression compiler to compile our resolvers. This change was done since Roslyn caused the server to consume a lot of memory. Most of the memory was consumed by native metadata references and we were not able to solve that memory consumption issue. At Microsoft Build I talked to David Fowler about that and he knew about the issue and recommended that we move to expressions. The downside here is that the resolvers produced by the expression compiler are actually a little bit slower than resolvers compiled with roslyn. This has many reasons I do not want to go in here.

With version 9.1 we will further optimize the resolver compilation by allowing lazy compilation, this will improve startup performance and memory usage.

## Execution Engine

We have updated our execution engine to use less memory and execute faster. The new execution engine is at least 2.3 times faster and uses half of the memory GraphQL-DotNet does to execute a query. If you are using schema first we are actually seeing 8.9 times faster execution of queries with Hot Chocolate compared to GraphQL-DotNet.

GraphQL-DotNet is still faster when validating queries, but this is offset since we are caching validation results. Validation will be one of the things we will work on for version 9.1. So, expect improvements here.

Also, we are putting a lot of work in our new execution plan feature. With execution plans we are seeing 3 times faster query executions compared to the current Hot Chocolate version 9 preview bits.

The execution plan feature allows us to pre-analyze the query graph and in many cases optimize the execution of resolvers significantly. We will talk about this in more detail after we have shipped version 9.

## Serialization

The serialization of query results is one of the areas we want to improve. Microsoft did a lot of work in this area and we are waiting here for the new UTF8 APIs that will ship with .Net Core 3. We are completely removing Json.Net over the next releases in order to improve performance further.

## Summary

We are investing heavily in performance and stability and see performance as feature. One other area we are working on is the subscription implementation. We will replace the current implementation with one built on top of the Microsoft pipeline API, this is why we are moving again subscription stitching to the next version.

Stitching is also one area we will start to improve performance-wise once we have the execution plan feature implemented.

The bottom line here is that if you go with Hot Chocolate you will get the most spec compliant and most performant GraphQL server on the .Net platform.

Each time a GraphQL spec element hits draft status we will go ahead and implement it with Hot Chocolate, this means that with Hot Chocolate you will always get the latest GraphQL features.

Also, we are working to have all the benchmarking ready with GraphQL-Bench. This will make it more transparent what we are testing and will let us more easily assess where we are heading performance wise.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 9.0.0 - Type System]]></title>
        <id>https://chillicream.com/blog/2019/04/12/type-system</id>
        <link href="https://chillicream.com/blog/2019/04/12/type-system"/>
        <updated>2019-04-12T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Originally, I wanted to write a little post about what we are currently working on in version 9 and how those things are coming along, but every time I started writing on this post it got longer and longer and it felt a bit too messy.

Starting with this post we will start talking about version 9 in more detail. We will split this into several blog posts that will cover different parts of the new version. This post will focus on the type system improvements.

We started with version 9.0.0-preview.9 to deliver more and more parts of the new type system. With version 9.0.0-preview.11 we are delivering a ton of bug fixes and many more new features.

## Schema Builder

The most prominent API that we are introducing is the new `SchemaBuilder`. The `SchemaBuilder` provides us with a new way to define schemas. Do not worry the current `ISchemaConfiguration` API is still supported and will not go away. In fact, `ISchemaConfiguration` now is just an interface over `SchemaBuilder` and we will evolve both APIs over time so that you can pick the one that you like more.

```csharp
ISchema schema = SchemaBuilder.New()
    .AddQueryType<FooType>()
    .Create();
```

**So, why did we introduce a new API to define a schema?**

First, we wanted the builder API to be decoupled from the actual schema, we wanted to be able to start adding schema types and other parts to a schema builder without being forced to create the schema.

With the schema builder we are now more flexible in scenarios like schema stitching.

```csharp
ISchema schema = SchemaBuilder.New()
    .AddQueryType<FooType>()
    .AddDirectiveType<BarType>()
    .AddSchemaFromFile("./Schema.graphql")
    .AddContextData("foo", "bar")
    .ModifyOptions(options => {  })
    .AddServices(services_a)
    .AddServices(services_b)
    .Create();
```

## Conventions

With our new schema builder, we did a lot of work underneath and introduced the ability to use services during type construction.

**For what is that useful?**

For one you can now register our new `INamingConventions` with the dependency injection and then the new `SchemaBuilder` will use your naming conventions instead of the built-in naming conventions.

Also, you can register our new `ITypeInspector` and override how we infer schema types from POCOs. This will allow you for instance to add support for custom attributes, so no need to pollute your API with our attributes anymore.

But fear not, you do not have to implement the whole `INamingConventions` interface for instance since you can override each part of our default implementation.

Since, in many cases we just want to tune existing naming conventions we can inherit from the default implementation `DefaultNamingConventions` and overwrite just what we want to change.

So, if we wanted to add to all the input type names the prefix `super` we could do this like the following:

```csharp
public class MyNamingConventions
{
    public override NameString GetTypeName(Type type, TypeKind kind)
    {
        if (type == null)
        {
            throw new ArgumentNullException(nameof(type));
        }

        if (kind == TypeKind.InputObject)
        {
            if (!name.EndsWith("Super", StringComparison.Ordinal))
            {
                name = name + "Super";
            }
        }

        return base.GetTypeName(type, kind);
    }
}
```

Like with the naming conventions we provide a default implementation to `ITypeInspector` where we can replace or extend parts that we want to modify.

In order to register our conventions with the schema builder we can do the following:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<INamingConventions, MyNamingConventions>();
    services.AddGraphQL(sp => Schema.Create(c =>
    {
        c.RegisterServiceProvider(sp);
        c.RegisterQueryType<Foo>();
    }));

}
```

Or we could do it like the following with the new schema builder:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<INamingConventions, MyNamingConventions>();
    services.AddGraphQL(sp => SchemaBuilder.New()
        .AddQueryType<Foo>()
        .AddServices(sp));
}
```

## Extending Types

One other major reason to rethink our type system was that many of you wanted to extend on types. One common thing that people wanted to do is to introduce generic types. We did something like this with our relay types. GraphQL does not really have generic types but the idea here is that you could have a type like the following:

```csharp
public class EdgeType<TSchemaType>
    : ObjectType<IEdge>
    where TSchemaType : IOutputType
{
}
```

If we for instance put in the `StringType` as TSchemaType then the edge type would become `StringEdge` in the schema. While this is not so difficult if our `StringType` has a fixed name, it becomes more difficult if `StringType` would create its name also depending on another type.

With version 9 we redesigned the schema initialization process so, that you can register dependencies for a type with the `SchemaBuilder`. This way the `SchemaBuilder` knows which type has to be initialized in which order.

So, let us have a look at how we would create our edge type with version 9:

```csharp
public class EdgeType<TSchemaType>
    : ObjectType<IEdge>
    where T : IOutputType
{
    protected override void Configure(
        IObjectTypeDescriptor<IEdge> descriptor)
    {
        descriptor.Name(dependency => dependency.Name + "Edge")
            .DependsOn<TSchemaType>();
    }
}
```

With the new `Name` extension on the type descriptors we are now able to define a delegate that represents the naming algorithm for that type. Moreover, we can now express on which type this algorithm depends.

This new `Name` descriptor extension is built upon our new descriptor extension API that provides a new way to extend our descriptors without needing to create a new base class.

### Extending Descriptors

Each descriptor now provides a new method called `Extend`. `Extend` returns an extension descriptor that allows us to integrate some logic with the type initialization pipeline.

Types are created in three phases:

- Create Instance
  The initializer creates the type instance and the type definition.
  The type definition contains all information to create and initialize a type.
  After this step the type instance exists and is associated with a native .net type.
  The native .net type can be object but can also be something more specific.
  In this phase the type will also report all of its dependencies to the schema builder.

- Complete Name
  After all types are created the names of the types will be completed.

- Complete Type
  In the last step the types will be completed, this means that for instance the fields are assigned, or the directives are retrieved and associated with a type etc.
  After this the type is completed and becomes immutable.

The extension descriptor provides extension points to these three phases:

- OnBeforeCreate
  OnBeforeCreate will allow you to customize the type definition.
  It is important to know that this step is not allowed to be dependent on another type object. Also, at this point you will not have access to the type completion context.

- OnBeforeNaming
  OnBeforeNaming allows to provide logic to generate the name of a type.
  You can declare two kinds of dependencies in this step, either the dependency has to be named first or the dependency is allowed to be in any state.

- OnBeforeCompletion
  OnBeforeCompletion allows to provide further logic that modifies the type definition. For instance, we could be dependent on another type in order to generate fields based on the fields of that other type.
  You can declare two kinds of dependencies in this step, either the dependency has to be completed first or the dependency is allowed to be in any state.

Let us have a look at how we implemented our own `Name` extension method in order to understand what `Extend` is useful for:

```csharp
descriptor
  .Extend()
  .OnBeforeNaming((ctx, definition) =>
  {
      INamedType type = ctx.GetType<INamedType>(
          ClrTypeReference.FromSchemaType(typeInfo.ClrType));
      definition.Name = createName(type);
  })
  .DependsOn(dependency, mustBeNamed:true);
```

Let us pic that example apart in order to understand what we did here. First, we called `Extend`, `Extend` returns the `IDescriptorExtension<T>` which allows us to register some code with the descriptor events that I have described earlier.

Each event will provide us with the type definition and the completion context. The `ICompletionContext` is the API to request information from the schema builder. In the case of our `Name` extension we are requesting the type instance for our `TSchemaType`. After that we call the naming algorithm with the resolved schema type.

Also, we added a dependency with `DependsOn`. The Boolean argument on `DependsOn` declares that the type has to be named before our delegate can be executed. We can declare as many dependencies as we want, so we are not bound to have just one.

Let me sum that up. The new `Extend` method on the descriptors allow us to extend the type descriptors without the need to create a new type base class. This is nice because you can now create extension methods that work across multiple solutions without forcing the user of that extension to opt into a new type base class. This makes it easy to consume those extensions. It is important to know here that `Extend` is available on all descriptors, so it is available on field descriptors, argument descriptors, or type descriptors.

### Replacing Descriptors

Though `Extend` is very capable, in some cases we might want to limit what is available through our descriptor. This basically means we want to remove functionality or replace the descriptor entirely. Let us assume we want to introduce an input type that describes the filter capabilities that can be applied to an output type. Basically, we want to introduce a filter input type like Prisma does.

So, if we had a type like the following:

```graphql
type Foo {
  bar: String!
}
```

We would want to be able to describe the filter capabilities that are available to the user of our API. This could look something like the following:

```csharp
public class FooFilterType
    : FilterType<Foo>
{
    public void Configure(IFilterDescriptor descriptor)
    {
        descriptor.Filter(t => t.Bar).AllowSmallerThan();
    }
}
```

The `FilterType<Foo>` inherits from `InputObjectType` and can with version 9 add its own descriptor. In order to replace the descriptor on our input type we would have to replace the configure method and introduce our new filter descriptor:

```csharp
public class FilterType<T>
    : InputObjectType
{
    private readonly Action<IFilterTypeDescriptor<T>> _configure;

    public FilterType()
    {
        _configure = Configure;
    }

    public FilterType(Action<IFilterTypeDescriptor<T>> configure)
    {
        _configure = configure
            ?? throw new ArgumentNullException(nameof(configure));
    }

    #region Configuration

    protected override InputObjectTypeDefinition CreateDefinition(
        IInitializationContext context)
    {
        var descriptor =
            FilterTypeDescriptor.New<T>(
                DescriptorContext.Create(context.Services));
        _configure(descriptor);
        return descriptor.CreateDefinition();
    }

    protected virtual void Configure(
        IFilterTypeDescriptor<T> descriptor)
    {
    }

    protected sealed override void Configure(
        IInputObjectTypeDescriptor descriptor)
    {
        throw new NotSupportedException();
    }

    #endregion
}
```

Like the descriptor extend logic we basically can override those three type initialization events.

In order to replace the old descriptor, we sealed of the old `Configure` method. Also, we introduced our new `Configure` method with the new descriptor.

```csharp
protected virtual void Configure(
    IFilterTypeDescriptor<T> descriptor)
{
}

protected sealed override void Configure(
    IInputObjectTypeDescriptor descriptor)
{
    throw new NotSupportedException();
}
```

In order to initialize our new descriptor, we overrode the `CreateDefinition` method. Our descriptor has to produce a `InputObjectTypeDefinition` in order to abide to the `InputType` interface. If you want your descriptor extendable like our descriptors, all you have to do is inherit from our descriptor base. With version 9 all descriptor and type definition classes are now public, and we strongly recommend basing your descriptors on our base classes.

## Context Data Support on Types

Also, with the new version we added the context data dictionary to all types, fields and arguments. You can use this to add custom metadata to objects of the type system. Context data can be declared on the type definition and will be copied to the corresponding type object.

```csharp
descriptor
  .Extend()
  .OnBeforeCreate(definition =>
  {
      definition.ContextData["Foo"] = "Bar";
  });
```

You can access the context data on a type object like the following:

```csharp
schema.GetType<ObjectType>("Query").ContextData.ContainsKey("Foo");
```

## Improved Relay Support

With version 9 we are making creating relay compliant schemas a breeze. Lets have a look at the relay server spec parts and see how those translate to Hot Chocolate:

In order to activate relayjs support you can do now the following:

```csharp
SchemaBuilder.New()
    .EnableRelaySupport()
    .AddQueryType<Foo>()
    .Create()
```

`EnableRelaySupport` will add the node field to your query type and setup the general logic of how your nodes will be resolved using an id value. Moreover, this activates the id value serialization and deserialization. The schema will now have opaque identifiers, but you will not have to deal with those in your API.

In `ObjectType`s you can now declare a type as node type. That means this type will implement the node interface and can be resolved through the node field:

```csharp
public class FooType
    : ObjectType<Foo>
{
    protected override void Configure(IObjectTypeDescriptor<Foo> descriptor)
    {
        descriptor.AsNode<Foo,int>((ctx, id) =>
            ctx.Service<IMyRepository>().GetById(id));
    }
}
```

Ok, this is basically all you have to do to fulfill spec item `A mechanism for refetching an object.`.

The other spec items for the relay spec were already quite good with version 8. It felt always odd to expose so much logic about those node resolvers to the developers that we refined our current APIs. We used the new `Extend` mechanism to provide extensions that help you along the way without forcing you to use a special base class.

## Code-First Type Extensions

The last thing I want to talk about in this post are code-first type extensions. We already supported the `extend` keyword in the stitching layer but had no real code-first API for this. Also, we only supported this in the stitching layer. With version 9 you can now extend code-first and schema-first. Moreover, type extensions are not bound to the stitching layer and work also on a standard schema.

Let us say we have the type `FooType` that has one field `description`.

```csharp
public class FooType
    : ObjectType<Foo>
{
    protected override void Configure(
        IObjectTypeDescriptor<Foo> descriptor)
    {
        descriptor.Field(t => t.Description);
    }
}
```

We can now introduce a type extension for our `FooType` that adds for instance a new field `test`.

```csharp
public class FooTypeExtension
    : ObjectTypeExtension
{
    protected override void Configure(
        IObjectTypeDescriptor descriptor)
    {
        descriptor.Name("Foo");
        descriptor.Field("test")
            .Resolver(() => new List<string>())
            .Type<ListType<StringType>>();
    }
}
```

The code-first extension types can do much more then, the schema-first variant. For instance, with code-first you can add middleware parts to a field replace or update a field, replace the resolver, add or replace directives on fields, arguments and so on. Also, you have all the extension functionality that you have on normal types. In fact, since the type extension and the type are using the same descriptor you can apply the same extensions to both.

Also, you can define multiple type extensions for a single type.

So, let us have a look of how we add type extensions to our schema:

```csharp
ISchema schema = SchemaBuilder.New()
  .AddQueryType<FooType>()
  .AddType<FooTypeExtension>();
  .Create()
```

The schema builder basically treats them as types, so there is nothing special that you have to do in order to register them.

As we go forward, we will also introduce generic variants of the extension types. This will be quite nice in the stitching layer since you can provide a .Net type that we will use to deserialize the object. This means that you can write your resolvers against strong types instead of the generic types that we use per default in the stitching layer.

## Wrapping it up

This is just the first bunch of features that are included with version 9. The best thing, all of what I have showed you today is already included in version 9.0.0-preview.11 which we have released alongside this blog post.

The next few posts will focus on execution plan support in our query engine. Execution plans can be cached and persisted and will make stitching so much faster. Also, we need the new execution plan feature to introduce support for `@defer`.

Furthermore, we will give a peek at our new high-performance parser.

Also, we will have a look at subscription stitching and our reworked subscription implementation that is now based on the pipeline API of .Net Core.

Last but not least, we hope we are be able to squeeze in our new `FilterType` feature with version 9.

As you can see version 9 will bring quite a few improvements, so stay tuned for our next post on V9 and try out our previews. Also, join our slack channel and give us your take on GraphQL, tell us what you would like to see next in Hot Chocolate.

With Hot Chocolate we are building a GraphQL server for the community, so join and help us along.

We value any kind of contribution, whether you give us a star, a feedback, find a bug, a typo, or whether you contribute code. Every bit matters and makes our project better.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - How to write integration tests against Hot Chocolate]]></title>
        <id>https://chillicream.com/blog/2019/04/11/integration-tests</id>
        <link href="https://chillicream.com/blog/2019/04/11/integration-tests"/>
        <updated>2019-04-11T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
**This post is outdated. If you are looking to do tests for Hot Chocolate 12 or newer watch our YouTube episode on testing.**

<Video videoId="Nf7nX2H_iiM" />

Today I was asked in our slack channel how one could write an integration test against Hot Chocolate without setting up an ASP.NET Core _TestServer_.
Though the ASP.NET Core _TestServer_ API is quite nice, it is much more cumbersome to test a schema this way.

For full integration tests through all the layers we could in fact setup a test GraphQL endpoint with the complete ASP.net core pipeline by using the ASP.NET core _TestServer_ API.

With this approach we could ensure that the GraphQL endpoint is correctly configured and works well within our service. In many cases this seems too much since we only want to test parts of the schema.

> If you want to read more about the ASP.NET Core _TestServer_ API there is a nice article on the [Visual Studio Magazine](https://visualstudiomagazine.com/articles/2017/07/01/testserver.aspx).

## Setup

Before we get started, assume we have a simple query class representing our GraphQL `Query` type:

```csharp
public class Query
{
    public string SayHello() => "Hello";
}
```

In order to create a schema from that simple type we could just do the following:

```csharp
ISchema schema = Schema.Create(c => c.RegisterQueryType<Query>());
```

OK, now we have a schema against which we can write our tests.

Let\`s take a step back and let us think about what we want to actually test before we go into the how.

Most of the times we want to write tests that ensure that our internal services are correctly hooked up with the GraphQL layer. Basically, we want to test that our business logic works well in the context of GraphQL and that all data is passed correctly. This means that we want to write queries and assert the results of our query.

The second thing that might be worth to ensure is that our schema is correctly expressed, so that all the default values are ,correct and no unexpected field is exposed.

Last but not least we might want to test a query- or field-middleware in various situations.

## Integration Tests

All right, let us get started with the integration tests first. In order to write queries against our schema we need to create a query executor:

```csharp
IQueryExecutor executor = schema.MakeExecutable();
```

The next thing that is important when testing the query engine in isolation is dependency injection.

Dependency injection is provided through `IServiceProvider`, this makes it really easy to provide the services to the execution engine that we might need like our data layer or so on.

The easiest way ist to create a service collection and setup whatever we need.

```csharp
IServiceProvider serviceProvider =
    new ServiceCollection()
        .AddSingleton<Foo, Bar>()
        .BuildServiceProvider();
```

The second thing we have to ensure is that we did not use `HttpContext` in our resolver- or middleware-logic.

**Wait a minute, but how are we able to access properties from `HttpContext` when we are not allowed to access it?**

Agreed, in some cases we really need to have access to properties on the `HttpContext` like the current `HttpContext.User` or some header value. In these cases, we need to access some parts of the `HttpContext` and copy those parts we need to our context data. The context data dictionary is thread-safe and can be accessed in query-, field-middleware and the field-resolver. This makes it easy to abstract the user context from ASP.NET Core dependencies like `HttpContext`. By doing this we will make our schema more testable and less dependant on the service layer.

We can do this by writing a query middleware that copies these properties to our context or by using our `OnCreateRequestAsync` hook. I will show how this can be done at the end of this post.

For now, let us assume we have done that already, then the only thing that we would need to do is to set the context data when we create our request. So, lets put a simple test together to see how we can write a test:

```csharp
[Fact]
public async Task SayHello_HelloIsReturned()
{
    // arrange
    IServiceProvider serviceProvider =
        new ServiceCollection()
            .AddSingleton<IDataLayer, MyDataLayer>()
            .BuildServiceProvider();

    IQueryExecutor executor = Schema.Create(c =>
    {
        c.RegisterQueryType<Query>();
    })
    .MakeExecutable();

    IReadOnlyQueryRequest request =
        QueryRequestBuilder.New()
            .SetQuery("{ sayHello }")
            .SetServices(serviceProvider)
            .AddProperty("Key", "value")
            .Create();

    // act
    IExecutionResult result = await executor.ExecuteAsync(request);

    // assert
    // so how do we assert this thing???
}
```

That does look good already, but how do we assert the result and what is the result.

The query executor will return an execution result, depending on the type of operation it could be a `IResponseStream` or a `IReadOnlyQueryResult`.

An `IReadOnlyQueryResult` contains basically the result graph of the query, but asserting this could be very tiresome.

My good friend [Normen](https://github.com/nscheibe) who works at Swiss Life created a snapshot testing library that basically works like [Jest](https://jestjs.io). We use _Snapshooter_ internally to test the Hot Chocolate core.

[Snapshooter](https://github.com/SwissLife-OSS/snapshooter) will create a snapshot at the first execution of the test. The snapshots are saved in a folder `__snapshot__` that is co-located with our test class. Every consecutive test run will be validated against that first snapshot. If the snapshots do not match the test will fail and tell us what part did not match.

So, let us have a look how our test would look like with this assertion in place.

```csharp
[Fact]
public async Task SayHello_HelloIsReturned()
{
    // arrange
    IServiceProvider serviceProvider =
        new ServiceCollection()
            .AddSingleton<IDataLayer, MyDataLayer>()
            .BuildServiceProvider();

    IQueryExecutor executor = Schema.Create(c =>
    {
        c.RegisterQueryType<Query>();
    })
    .MakeExecutable();

    IReadOnlyQueryRequest request =
        QueryRequestBuilder.New()
            .SetQuery("{ sayHello }")
            .SetServices(serviceProvider)
            .AddProperty("Key", "value")
            .Create();

    // act
    IExecutionResult result = await executor.ExecuteAsync(request);

    // assert
    result.MatchSnapshot();
}
```

This test looks very clean now, the snapshots are serializing to json which makes them easy to read.

```json
{
  "Data": {
    "sayHello": "hello"
  },
  "Extensions": {},
  "Errors": []
}
```

The awesome thing with snapshooter is that we can ignore parts of our result-graph or validate one property of the result-graph in a special way.

```csharp
result.MatchSnapshot(o =>
    o.IgnoreField("Extensions.SomeProperty"));
```

For more information about how snapshooter works head over to their repository:

<https://github.com/SwissLife-OSS/snapshooter>

## Schema Tests

Ok, lets have a look at our second category. This I think is the simplest test we will write and probably we will just have one or two of those tests.

Hot Chocolate lets us print our schema as GraphQL SDL, this means that we can create a simple SDL representation like the following:

```graphql
type Query {
  sayHello: String
}
```

In order to get this representation we just have to do the following:

```csharp
Schema.Create(c => c.RegisterQueryType<Query>()).ToString();
```

That\`s quite simple, just calling `ToString()` on the schema will return the schema SDL representation.

The good thing with _Snapshooter_ is that we also can create snapshots of scalar values like a string. _Snapshooter_ will than just save the raw scalar as snapshot, so our SDL will **NOT** be polluted with JSON escape characters.

Our test could look like the following:

```csharp
[Fact]
public async Task Ensure_Schema_IsCorrect()
{
    // arrange
    ISchema schema = Schema.Create(c =>
    {
        c.RegisterQueryType<Query>();
    });

    // act
    string schemaSDL = schema.ToString();

    // assert
    schemaSDL.MatchSnapshot();
}
```

## Middleware/Resolver Tests

The last category concerns our middleware logic. I would strongly suggest testing a middleware with a unit test and not by firing a query against the query engine. You can use [Moq](https://github.com/Moq/moq4/wiki/Quickstart) to create a `IResolverContext` mock.

In cases that you want to test a resolver or middleware pipeline of a field you can retrieve those from that type like the following:

```csharp
[Fact]
public async Task SayHello_HelloIsReturned()
{
    // arrange
    IServiceProvider serviceProvider =
        new ServiceCollection()
            .AddSingleton<IDataLayer, MyDataLayer>()
            .BuildServiceProvider();

    ISchema schema = Schema.Create(c =>
    {
        c.RegisterQueryType<Query>();
    });

    ObjectType type = schema.GetType<ObjectType>("Query");
    ObjectField field = type.Fields["sayHello"];

    Mock<IResolverContext> contextMock = new Mock<IResolverContext>();
    // note that depending on what you are using in your resolver you will
    // have to setup properties for your mock.

    // act
    object result = await field.Resolver(contextMock.Object)

    // assert
    result.MatchSnapshot();
}
```

The resolver-property will just have the isolated resolver logic. In order to access the middleware pipeline, use the `Middleware` property on the field. The middleware represents the compiled middleware pipeline including the resolver.

## HttpContext Abstraction

So, lets come back the question about the `HttpContext`. In order to copy properties from the `HttpContext` to your GraphQL request I said that we can use `OnCreateRequestAsync`. This is actually the simplest way to do it.

Let us grab the user from the `HttpContext` and copy it to our context data dictionary as an example.

```csharp
app.UseGraphQL(new QueryMiddlewareOptions
{
    OnCreateRequest = (context, builder, ct) =>
    {
        builder.SetProperty("user", context.User);
        return Task.CompletedTask;
    }
})
```

The second way is a little bit more complicated but easier to test and feels cleaner.

We could write a little query middleware. The middleware could be provided as delegate like the upper example or we could take the extra effort to make a class.

```csharp
public class CopyUserMiddleware
{
    private readonly QueryDelegate _next;

    public CopyVariablesToResolverContextMiddleware(QueryDelegate next)
    {
        _next = next ?? throw new ArgumentNullException(nameof(next));
    }

    public Task InvokeAsync(IQueryContext context)
    {
        IHttpContextAccessor accessor = context.Services.GetService<IHttpContextAccessor>();
        context.ContextData["user"] = accessor.HttpContext.User;
        return _next.Invoke(context);
    }
}
```

So, this code does the same as our first example but is now easily testable and can be integrated like the following to our GraphQL execution pipeline:

```csharp
services.AddGraphQL(Schema.Create(c =>
    {
        c.RegisterQueryType<Query>();
    })
    .MakeExecutable(b => b.Use<CopyUserMiddleware>().UseDefaultPipeline()));
```

I hope this little post will help when you start writing tests for your schema. If you run into any issues or if you have further questions/suggestions head over to our slack channel and we will be happy to help you.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 0.8.1]]></title>
        <id>https://chillicream.com/blog/2019/03/31/hot-chocolate-0.8.1</id>
        <link href="https://chillicream.com/blog/2019/03/31/hot-chocolate-0.8.1"/>
        <updated>2019-03-31T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we release version 8.1 (0.8.1) of Hot Chocolate. This release brings improvements and bug fixes to the current version 8 release.

## Instrumentation

One focus of this release was to open up our diagnostic events to be used by developers. When we started thinking about how Hot Chocolate should provide information about its inner workings to users of the library, we opted against using one specific logging framework.

Instead we have looked at what Microsoft was doing in ASP.NET core and other components with diagnostic sources. Diagnostic sources let us create events that have non-serializable payloads.

This means that we can provide an event that gives full access to our context objects like the `IQueryContext` or the `IResolverContext`.

This enables you to add your own logger to your GraphQL server and grab exactly the information from the Hot Chocolate diagnostic events that you need to make your tracing solution work.

In order to read more on this subject checkout our blog: [Tracing with Hot Chocolate](/blog/2019/03/19/logging-with-hotchocolate) or head over to our [documentation](https://hotchocolate.io/docs/instrumentation).

## Stitching Refinements

One new feature that is now available in the stitching layer is support of error filters. This means that you can now write error filters like on a local schema and transform or enrich query errors that were extracted from remote queries.

In order to make it easier to use error filters we have changed the error structure of remote errors and provide the original error object as an extension property:

```csharp
serviceCollection.AddStitchedSchema(builder =>
    builder.AddSchemaFromHttp("messages")
        .AddSchemaFromHttp("users")
        .AddSchemaFromHttp("analytics"))
        .AddExecutionConfiguration(b =>
        {
            b.AddErrorFilter(error =>
            {
                if(error.Extensions.TryGetValue("remote", out object o)
                  && o is IError originalError)
                {
                    return error.AddExtension(
                      "remote_code",
                      originalError.Code);
                }
                return error;
            });
        }));
```

We also refined the default rewrite logic so that errors in most cases will now be correctly associated with the causing field.

## Bug Fixes

`DateTime` scalars are now correctly handled in the stitching layer, with version 8 we had some issues when `DateTime` scalars were provided through variables.

For more information on what other bugs we fixed head over to our [changelog](https://github.com/ChilliCream/graphql-platform/blob/master/CHANGELOG.md).

## Version 9 Development

We have made a lot of headway with the new type system that is coming with version 9. Also, we are working on the `@defer` directive at the moment. We will give a more detailed update on the next major version in a separate blog post. Version 9 is really shaping up to become our biggest release so far.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Tracing with Hot Chocolate]]></title>
        <id>https://chillicream.com/blog/2019/03/19/logging-with-hotchocolate</id>
        <link href="https://chillicream.com/blog/2019/03/19/logging-with-hotchocolate"/>
        <updated>2019-03-19T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
One common question that comes up on our slack channel is if Hot Chocolate supports some kind of logging infrastructure. My personal opinion here is that logging/tracing is often very project specific and an API should not force one specific logging solution onto its users.

Instead we have opted to provide diagnostic events through Microsoft`s diagnostic source which does not force us to serialize any payloads. This in turn gives you the ability to pick and choose the information that best fits your need for your tracing/logging solution.

This post will walk you through on how to add a logger of your choice to Hot Chocolate and get exactly the right amount of information for your project.

In this blog we will use the ASP.NET core logging API to show how a logger can be attached to our diagnostic events.

## Setup

But before we can get started let us first setup a web project with Hot Chocolate:

```bash
mkdir logging
cd logging
dotnet new web
dotnet add package HotChocolate.AspNetCore:9.0.0-preview.5
dotnet add package HotChocolate.AspNetCore.Playground:9.0.0-preview.5
```

## Configure the Logger

After our project is setup let us start with setting up the ASP.net core logging infrastructure. This is fairly easy with ASP.net core. Head over to the `Program.cs` and replace the builder configuration with the following one.

```csharp
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging((hostingContext, logging) =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        })
        .UseStartup<Startup>();
```

`ConfigureLogging` configures the various logging providers that are then available throughout our `WebHost`. In our simple example we clear all the providers and then add only the console logger.

Next head over to the `Startup.cs` and register the logger with the dependency injection by adding the following line to `ConfigureServices`.

```csharp
services.AddLogging();
```

Perfect, now we have setup all the basics and can get started.

## Diagnostic Observer

The Hot Chocolate server provides diagnostic events through a diagnostic source. We can subscribe to these events by providing a diagnostic observer. A diagnostic observer is basically any class that implements our marker interface `IDiagnosticObserver`.

Into this class we can add public methods that are subscribed to the actual diagnostic listener. The methods that shall subscribe to an event have to be annotated to with the `DiagnosticNameAttribute`.

We have listed the various available events and their payloads in our documentation that can be found [here](https://hotchocolate.io/docs/next/instrumentation).

Let us say that in our case we want to write a message to the console whenever a request begins. Moreover, if the request is a query or mutation then we also want to write the result to the console.

Before we add the actual event methods, let us create a class called `DiagnosticObserver`. In order to write events to the logger we need to inject a concrete logger to our class. So, our class could look like the following:

```csharp
public class DiagnosticObserver
    : IDiagnosticObserver
{
    private readonly ILogger _logger;

    public DiagnosticObserver(ILogger<DiagnosticObserver> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }
}
```

Next, let us add our two event methods.

```csharp
public class DiagnosticObserver
        : IDiagnosticObserver
{
    private readonly ILogger _logger;

    public DiagnosticObserver(ILogger<DiagnosticObserver> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    [DiagnosticName("HotChocolate.Execution.Query")]
    public void OnQuery(IQueryContext context)
    {
        // This method is used as marker to enable begin and end events
        // in the case that you want to explicitly track the start and the
        // end of this event.
    }

    [DiagnosticName("HotChocolate.Execution.Query.Start")]
    public void BeginQueryExecute(IQueryContext context)
    {
        _logger.LogInformation(context.Request.Query);
    }

    [DiagnosticName("HotChocolate.Execution.Query.Stop")]
    public void EndQueryExecute(IQueryContext context)
    {
        if(context.Result is IReadOnlyQueryResult result)
        {
            using (var stream = new MemoryStream())
            {
                var resultSerializer = new JsonQueryResultSerializer();
                resultSerializer.SerializeAsync(
                    result, stream).Wait();
                _logger.LogInformation(
                    Encoding.UTF8.GetString(stream.ToArray()));
            }
        }
    }
}
```

In order to enable start/stop events we have to add a third method that represents the subscription to the event.

This is only needed when subscribing to activities that consist of a start event and a stop event. These start and stop events allow for measuring performance.

Apart from our standard payloads that are described in our documentation we can also inject the `Activity` instance to your start/stop event and use the high precision time measurement that the diagnostics APIs provide.

The events always provide you with the full context objects that are available in the query and field middleware pipeline. You basically have full access to all the data that you would have access to in a middleware and by this you are able to pick the information you need for your tracing/logging solution and create the logging messages in a structure that fits your needs.

Moreover, you also can use the `ContextData` dictionary on the context objects to share information between your subscription events like a request identifier.

After we have implemented our observer, we have to register it as a service.

Add the following line to the `ConfigureServices` method in our `Startup.cs`.

```csharp
services.AddDiagnosticObserver<DiagnosticObserver>();
```

With that our logger is ready to receive events. We now just need a GraphQL API that produces events.

For this we add a simple query type:

```csharp
public class Query
{
    public string Hello() => "world";
}
```

Next we register the query type with our schema by adding the following line to the `ConfigureServices` method in our `Startup.cs`.

```csharp
services.AddGraphQL(c =>
{
    c.RegisterQueryType<Query>();
});
```

Last but not least we have to add our `GraphQL` middleware and in order to write some queries our `Playground` middleware.

Replace the `Configure` method in our `Startup.cs` with the following:

```csharp
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseGraphQL();
    app.UsePlayground();

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Hello World!");
    });
}
```

You should now be able to start the GraphQL server.

```bash
dotnet run
```

The server should be accessible through playground under the following URL `http://127.0.0.1:5000/playground`.

Add the following query and execute it:

```graphql
{
  hello
}
```

The query and the result should now be printed to your console.

This is just a simple example of how to subscribe to our diagnostic events. Checkout our documentation for a list of all of the events available [here](https://hotchocolate.io/docs/next/instrumentation).

We have added this example project to our example repo [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/Instrumentation).

Also, we have a more complex implementation of a Hot Chocolate ETW event source [here](https://github.com/ChilliCream/thor-client/tree/master/src/Clients/HotChocolate).

Another example is our [Apollo Tracing implementation](https://github.com/ChilliCream/graphql-platform/blob/master/src/Core/Core/Execution/Instrumentation/ApolloTracingDiagnosticObserver.cs) that is also based on our instrumentation API.

I hope this little field trip into our instrumentation API gives a little outlook of an often-overlooked feature that is coming with version 9. All of what I showed in this blog is available with preview 5 (9.0.0-preview.5) that we released today.

We will add stitching related events with the next view preview builds.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 0.8.0]]></title>
        <id>https://chillicream.com/blog/2019/03/04/hot-chocolate-0.8.0</id>
        <link href="https://chillicream.com/blog/2019/03/04/hot-chocolate-0.8.0"/>
        <updated>2019-03-04T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we are releasing Hot Chocolate version 8 (0.8.0) which mainly focused on schema stitching and brings our stitching layer to a whole new level.

## Schema Stitching

Since, my last blog post we were heavily at work ironing out bugs and making schema stitching easier.

Now, with the release finished, schema stitching with ASP.NET core has become super easy and feels quite nice to use.

Head over to our new documentation for [schema stitching](https://hotchocolate.io/docs/stitching).

## Voyager

With version 8 we now provide a GraphQL Voyager middleware. GraphQL Voyager is a nice schema explorer that can be useful during development time. If you want to know more about GraphQL Voyager head over to their [GitHub repo](https://github.com/APIs-guru/graphql-voyager).

## Authorization

Also, with version 8 we have invested some time to smooth out the `@authorize`-directive.

The `@authorize`-directive does now mirror almost the behavior of the authorize directive.

In contrast to the ASP.NET attribute we can specify the directive on field definitions and thereby have a fine-grained control over what data we want to give access to.

If you are using ASP.NET core then you can use authorization-policies with your `@authorize`-directive giving you even more control over your data.

Head over to our [authorization documentation](https://hotchocolate.io/docs/authorization) to learn more.

## Version 9

We have already started on quite a few areas for our next release. I can tell you already that, version 9 will be big.

### Type System

The most requested features from users of our API at the moment is to open up the type system. In the beginning we did keep a lot of extension points internal in order to give us some more time to figure out how to make certain areas extendable.

With version 9 we will reinvent the type system. Do not fret, there will be no breaking changes to the public APIs since the APIs that we are changing and making public are currently internal.

With version 9 you will be able to create your own base classes that expose your own descriptors to the users. This will allow for instance to introduce prisma-like filter APIs, or dynamic types that generate members on the base of other schema types.

### Prisma-like Filtering for IQueryable

On top of the new type system we will add new filter types that will allow you to configure filter and sorting inputs that can be used with the paging middleware. If you never heard of Prisma then head over to their web page and checkout their approach to filtering and sorting:

[Prisma](https://www.prisma.io/docs/prisma-graphql-api/reference/queries-qwe1/)

### Advanced Relay Support

With version 9 creating relay compliant schemas will be as easy as eating pie. You will no longer be bothered handling schema unique identifiers, since Hot Chocolate will do all of that for you. Also, the node field on the `Query` type will be automatically integrated. So, what we are doing here is removing boilerplate code for you so that you can focus on implementing a great API without having to worry about the relay server spec details.

### Subscription Stitching

We originally envisioned this feature for version 8 but moved this one into version 9 due to the fact that we needed some changes in the type system to handle it. This will make the schema stitching even more complete.

### Relay Schema Stitching

With the schema stitching version 8 you have to handle the node field on your own when you stitch multiple relay compliant schemas together. With version 9 we will keep track which id belongs to which remote schema and from which remote schema we have to fetch the data.

### Hot Chocolate UI

GraphQL is really awesome, but we are really not happy with the tooling situation. As of now we support GraphiQL, Playground and Voyager for Hot Chocolate, but none of these is a complete solution.

We have started some time ago to create a new developer tool for GraphQL that will replace all of these. We did not base our new UI on GraphiQL since we want to achieve more and create something unique. Look for instance at the tooling around rest, with _Postman_ developers have quite a good tool that enables them to do a lot.

The _Hot Chocolate UI_ will be a developer focused tool that will be able to replace all the GraphQL UIs out there. It already is my favorite tool and we cannot wait to show you the first preview versions of it.

By the way, we are still looking for a cool new chillicream compliant name like Hot Chocolate or Green Donut. So, if you have any cool or funny ideas head over to our slack channel

### GraphQL Compatibility Acceptance Tests

With version 8 we have started to invest in the GraphQL Compatibility Acceptance Tests and plan to have them fully implemented and integrated with version 11. This does not mean that we wait until version 11 to use them. Already now we are able to generate some of the test cases. Hopefully, we will have all the parser tests integrated with version 9. This subject is an ongoing effort and we will keep you posted on this one.

For more information on GraphQL Cats visit their [GitHub repository](https://github.com/graphql-cats/graphql-cats).

### Versioning

With version 9 we will change our versioning and follow the example of react in swapping the leading zero with the nine. So, the version number of version 9 will actually be 9.0.0.

## Version 10

With version 10 is in the early planning stages, we will build on the new type system and introduce two new services that will turn Hot Chocolate from a simple server into a GraphQL platform.

### Schema Registry

The schema registry will keep track of the schemas in your company. Moreover, with version 10 of our new `Hot Chocolate UI` you will be able to configure your GraphQL gateways with drag&drop. This means you will be able to stitch schemas together with an awesome UI and deploy new stitched schemas in seconds.

### Performance and Schema Warehouse

The second service will collect performance data from all your schemas. You will be able to analyze with the `Hot Chocolate UI` how good or bad you GraphQL servers are performing, which queries are the most used or which queries use the most resources. Furthermore, you will be able to drill into the query tracing results and see which resolvers are performing well or which resolvers are causing issues.

## Wrapping things up

We are planning around four to six weeks for version 9 with the first previews coming out in around two weeks.

We will really start hammering out the details on version 9 in the next three weeks.

If you have ideas or suggestions pleas head over to our slack channel and join the discussion.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Schema Stitching with Version 8]]></title>
        <id>https://chillicream.com/blog/2019/02/20/schema-stitching</id>
        <link href="https://chillicream.com/blog/2019/02/20/schema-stitching"/>
        <updated>2019-02-20T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
With version 8 of Hot Chocolate we have mainly focused on schema stitching. One of the most requested features in this area was auto-stitching. Auto-stitching will enable us to automatically pull in schemas from other GraphQL servers and merge those into one schema.

**What is schema stitching actually?**

Schema stitching is the capability to merge multiple GraphQL schemas into one schema that can be queried.

## Introduction

**So, for what is that useful?**

In our case we have lots of specialized services that serve data for specific problem domains. Some of these services are GraphQL services, some of them are REST services and yes sadly a little portion of those are still SOAP services.

With Hot Chocolate schema stitching we are able to create a gateway that bundles all those services into one GraphQL schema.

**Is schema stitching basically just putting two schemas together?**

Just putting two schemas into one and avoid name collisions is simple. But what we want to achieve with schema stitching is one consistent schema.

Hot Chocolate schema stitching allows us to really integrate services into one schema by folding types into one another and even renaming or removing parts.

With this we can create a consistent GraphQL schema that hides the implementation details of our backend services and provides the consumer of our endpoint with the capability to fetch the data they need with one call, no under- or over-fetching and most importantly no repeated fetching because we first needed to fetch that special id with which we now can fetch this other thingy.

## Getting Started

In order to showcase how schema stitching works and what the problems are let us assume we have a service like twitter, where a user can post messages.

Moreover, let us assume we have three teams working on internal micro-/domain-services that handle certain aspects of that service.

The first service is handling the message stream and has the following schema:

```graphql
type Query {
  messages(userId: ID!): [Message!]
  message(messageId: ID!): Message
}

type Mutation {
  newMessage(input: NewMessageInput!): NewMessagePayload!
}

type Message {
  id: ID!
  text: String!
  createdBy: ID!
  createdAt: DateTime!
  tags: [String!]
}

type NewMessageInput {
  text: String!
  tags: [String!]
}

type NewMessagePayload {
  message: Message
}
```

The second service is handling the users of the services and has the following schema:

```graphql
type Query {
  user(userId: ID!): User!
  users: [User!]
}

type Mutation {
  newUser(input: NewUserInput!): NewUserPayload!
  resetPassword(input: ResetPasswordInput!): ResetPasswordPayload!
}

type NewUserInput {
  username: String!
  password: String!
}

type ResetPasswordInput {
  username: String!
  password: String!
}

type NewUserPayload {
  user: User
}

type ResetPasswordPayload {
  user: User
}

type User {
  id: ID!
  username: String!
}
```

Last but not least we have a third service handling the message analytics. In our example case we keep it simple and our analytics service just tracks three different counters per message. The schema for this service looks like the following:

```graphql
type Query {
  analytics(messageId: ID!, type: CounterType!): MessageAnalytics
}

type MessageAnalytics {
  id: ID!
  messageId: ID!
  count: Int!
  type: CounterType!
}

enum CounterType {
  VIEWS
  LIKES
  REPLIES
}
```

With those three separate schemas our UI team would have to fetch from multiple endpoints.

Even worse for our UI team, in order to build a stream view that shows the message text and the name of the user who posted the message, they would have to first fetch all the messages and could only then fetch the names of the users.

This is actually one of the very things GraphQL tries to solve.

## Setting up our server

Before we start with stitching itself let`s get into how to setup our server.

Every Hot Chocolate server can be a stitching server. This means in order to get started we can just use the Hot Chocolate GraphQL server template and modify it a little bit to make the server a stitching server.

If you do not have the Hot Chocolate GraphQL server template installed execute first the following command.

```bash
dotnet new -i HotChocolate.Templates.Server
```

After that we will create a new folder and add a new server to that folder.

```bash
mkdir stitching-demo
cd stitching-demo
dotnet new graphql-server
```

With this we have now a functioning GraphQL server with a simple hello world example.

In order to make this server a stitching server we now have to add the Hot Chocolate stitching engine.

```bash
dotnet add package HotChocolate.Stitching
```

Now that our GraphQL server is ready we can start to configure the endpoints of our remote schemas.

> Remote schemas are what we call the GraphQL schemas that we want to include into our merged schema. Remote schemas can be any GraphQL Spec compliant server (Apollo, Sangria, Hot Chocolate etc.) that serves its schema over HTTP. Also we can include local schemas that are created with the Hot Chocolate .net API.

The endpoints are declared by using a named `HttpClient` via the HttpClient factory that is included with ASP.net core.

```csharp
services.AddHttpClient("messages", (sp, client) =>
{
  client.BaseAddress = new Uri("http://127.0.0.1:5050");
});
services.AddHttpClient("users", (sp, client) =>
{
  client.BaseAddress = new Uri("http://127.0.0.1:5051");
});
services.AddHttpClient("analytics", (sp, client) =>
{
  client.BaseAddress = new Uri("http://127.0.0.1:5052");
});
```

Now let\`s remove the parts from the server template that we don't need.

> We will show some strategies of how to handle authenticated services later on.

```csharp
services.AddDataLoaderRegistry();

services.AddGraphQL(sp => Schema.Create(c =>
{
    c.RegisterQueryType<Query>();
}));
```

## Stitching Builder

The stitching builder is the main API to configure a stitched GraphQL schema (GraphQL gateway). In order to have a simple auto-merge we have just to provide all the necessary schema names and the stitching layer will fetch the remote schemas via introspection on the first call to the stitched schema.

```csharp
services.AddStitchedSchema(builder => builder
  .AddSchemaFromHttp("messages")
  .AddSchemaFromHttp("users")
  .AddSchemaFromHttp("analytics"));
```

Since a stitched schema is essentially no different to any other GraphQL schema, we can configure custom types, add custom middleware or do any other thing that we could do with a Hot Chocolate GraphQL schema.

In our example we are stitching together schemas that come with non-spec scalar types like `DateTime`. So, the stitching layer would report a schema error when stitching the above three schemas together since the `DateTime` scalar is unknown.

In order to declare this custom scalar we can register the extended scalar set like with a regular Hot Chocolate GraphQL schema through the `AddSchemaConfiguration`-method on the stitching builder.

```csharp
services.AddStitchedSchema(builder => builder
  .AddSchemaFromHttp("messages")
  .AddSchemaFromHttp("users")
  .AddSchemaFromHttp("analytics"))
  .AddSchemaConfiguration(c =>
  {
    c.RegisterExtendedScalarTypes();
  })
```

> More information about our scalars can be found [here](https://hotchocolate.io/docs/custom-scalar-types).

With this in place our stitched schema now looks like the following:

```graphql
type Query {
  messages(userId: ID!): [Message!]
  message(messageId: ID!): Message
  user(userId: ID!): User!
  users: [User!]
  analytics(messageId: ID!, type: CounterType!): MessageAnalytics
}

type Mutation {
  newMessage(input: NewMessageInput!): NewMessagePayload!
  newUser(input: NewUserInput!): NewUserPayload!
  resetPassword(input: ResetPasswordInput!): ResetPasswordPayload!
}

type Message {
  id: ID!
  text: String!
  createdBy: ID!
  createdAt: DateTime!
  tags: [String!]
}

type NewMessageInput {
  text: String!
  tags: [String!]
}

type NewMessagePayload {
  message: Message
}

type NewUserInput {
  username: String!
  password: String!
}

type ResetPasswordInput {
  username: String!
  password: String!
}

type NewUserPayload {
  user: User
}

type ResetPasswordPayload {
  user: User
}

type User {
  id: ID!
  username: String!
}

type MessageAnalytics {
  id: ID!
  messageId: ID!
  count: Int!
  type: CounterType!
}

enum CounterType {
  VIEWS
  LIKES
  REPLIES
}
```

We have just achieved a simple schema merge without doing a lot of work. But honestly we would like to change some of the types. While the stitching result is nice, we would like to integrate the types with each other.

### Extending Types

So, the first thing that we would like to have is a new field on the query that is called `me`. The `me` field shall represent the currently signed in user of our service.

Further, the user type should expose the message stream of the user, this way we could fetch the messages of the signed in user like the following:

```graphql
{
  me {
    messages {
      text
      tags
    }
  }
}
```

In order to extend types in a stitched schema we can use the new GraphQL extend syntax that was introduced with the 2018 spec.

```graphql
extend type Query {
  me: User! @delegate(schema: "users", path: "user(id: $contextData:UserId)")
}

extend type User {
  messages: [Message!]
    @delegate(schema: "messages", path: "messages(userId: $fields:Id)")
}
```

With just that and no further code needed we have specified how the GraphQL stitching engine shall rewrite our schema.

Let us dissect the above GraphQL SDL in order to understand what it does.

First, let us have a look at the `Query` extension. We declared a field like we would do with the schema-first approach. After that we annotated the field with the `delegate` directive. The `delegate` directive basically works like a middleware that delegates calls to to a remote schema.

The `path`-argument on the `delegate` directive specifies how to fetch the data from the remote schema. The selection path can have multiple levels. So, if we wanted to fetch just the username we could do that like the following:

```graphql
user(id: $contextData:UserId).username
```

Moreover, we are using a special variable that can access the resolver context.

Currently this variable has four scopes:

- Arguments

  Access arguments of the annotated field field: `$arguments:ArgumentName`

- Fields

  Access fields of the declaring type: `$fields:FieldName`

- ContextData

  Access properties of the request context data map: `$contextData:Key`

- ScopedContextData

  Access properties of the scoped field context data map: `$contextData:Key`

The context data can be used to map custom properties into our GraphQL resolvers. In our case we will use it to map the internal user ID from the user claims into our context data map. This allows us to have some kind of abstraction between the actual HttpRequest and the data that is needed to process a GraphQL request.

> Documentation on how to add custom context data from a http request can be found [here](https://hotchocolate.io/docs/custom-context)

OK, let\`s sum this up, with the `delegate` directive we are able to create powerful stitching resolvers without writing one line of c# code. Furthermore, we are able to create new types that make the API richer without those types having any representation in any of the remote schemas.

In order to get our extensions integrated we need to add the extensions to our stitching builder. Like with the schema we have multiple extension methods to load the GraphQL SDL from a file or a string and so on.

In our case let\`s say we are loading it from a file called `Extensions.graphql`.

```csharp
services.AddStitchedSchema(builder => builder
  .AddSchemaFromHttp("messages")
  .AddSchemaFromHttp("users")
  .AddSchemaFromHttp("analytics"))
  .AddExtensionsFromFile("./graphql/Extensions.graphql")
  .AddSchemaConfiguration(c =>
  {
    c.RegisterExtendedScalarTypes();
  })
```

Now with all of this in place our schema looks like the following:

```graphql
type Query {
  me: User!
  messages(userId: ID!): [Message!]
  message(messageId: ID!): Message
  user(userId: ID!): User!
  users: [User!]
  analytics(messageId: ID!, type: CounterType!): MessageAnalytics
}

type Mutation {
  newMessage(input: NewMessageInput!): NewMessagePayload!
  newUser(input: NewUserInput!): NewUserPayload!
  resetPassword(input: ResetPasswordInput!): ResetPasswordPayload!
}

type Message {
  id: ID!
  text: String!
  createdBy: ID!
  createdAt: DateTime!
  tags: [String!]
}

type NewMessageInput {
  text: String!
  tags: [String!]
}

type NewMessagePayload {
  message: Message
}

type NewUserInput {
  username: String!
  password: String!
}

type ResetPasswordInput {
  username: String!
  password: String!
}

type NewUserPayload {
  user: User
}

type ResetPasswordPayload {
  user: User
}

type User {
  id: ID!
  username: String!
  messages: [Message!]
}

type MessageAnalytics {
  id: ID!
  messageId: ID!
  count: Int!
  type: CounterType!
}

enum CounterType {
  VIEWS
  LIKES
  REPLIES
}
```

### Renaming and Removing Types

Though this is nice, we would like to go even further and enhance our `Message` type like the following:

```graphql
type Message {
  id: ID!
  text: String!
  createdBy: User
  createdById: ID!
  createdAt: DateTime!
  tags: [String!]
  views: Int!
  likes: Int!
  replies: Int!
}
```

Moreover, we would like to remove the `analytics` field from our query type since we have integrated the analytics data directly into our `Message` type.

Since with the root field gone we have no way of accessing `MessageAnalytics` and `CounterType`, let\`s also get rid of these types.

The stitching builder has powerful refactoring functions that even can be extended by writing custom document- and type-rewriters.

In order to remove a field or a type we can tell the stitching builder to ignore them by calling one of the ignore extension methods.

```csharp
services.AddStitchedSchema(builder => builder
  .AddSchemaFromHttp("messages")
  .AddSchemaFromHttp("users")
  .AddSchemaFromHttp("analytics"))
  .AddExtensionsFromFile("./graphql/Extensions.graphql")
  .IgnoreField("analytics", "Query", "analytics")
  .IgnoreType("analytics", "MessageAnalytics")
  .IgnoreType("analytics", "CounterType")
  .AddSchemaConfiguration(c =>
  {
    c.RegisterExtendedScalarTypes();
  })
```

> There are also methods for renaming types and fields where the stitching engine will take care that the schema is consistently rewritten so that all the type references will refer to the current new type/field name.

With that we have removed the types from our stitched schema. Now, let us move on to extend our message type.

```graphql
extend type Message {
  createdBy: User!
    @delegate(schema: "users", path: "user(id: $fields:createdById)")
  views: Int! @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
  likes: Int! @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
  replies: Int!
    @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
}
```

Since we introduced a new field `createdBy` that basically overwrites the field that we have already declared on our original `Message` type, we need to rename the original field `createdBy` to `createdById` so that we are still able to use it.

```csharp
services.AddStitchedSchema(builder => builder
  .AddSchemaFromHttp("messages")
  .AddSchemaFromHttp("users")
  .AddSchemaFromHttp("analytics"))
  .AddExtensionsFromFile("./graphql/Extensions.graphql")
  .IgnoreField("analytics", "Query", "analytics")
  .IgnoreType("analytics", "MessageAnalytics")
  .IgnoreType("analytics", "CounterType")
  .RenameField("messages", "Message", "createdBy", "createdById")
  .AddSchemaConfiguration(c =>
  {
    c.RegisterExtendedScalarTypes();
  })
```

> It is important to now that the document- and type-rewriters are executed before the schemas are merged and the extensions integrated.

Our new schema now looks like the following:

```graphql
type Query {
  me: User!
  messages(userId: ID!): [Message!]
  message(messageId: ID!): Message
  user(userId: ID!): User!
  users: [User!]
}

type Mutation {
  newMessage(input: NewMessageInput!): NewMessagePayload!
  newUser(input: NewUserInput!): NewUserPayload!
  resetPassword(input: ResetPasswordInput!): ResetPasswordPayload!
}

type Message {
  id: ID!
  text: String!
  createdBy: User
  createdById: ID!
  createdAt: DateTime!
  tags: [String!]
  views: Int!
  likes: Int!
  replies: Int!
}

type NewMessageInput {
  text: String!
  tags: [String!]
}

type NewMessagePayload {
  message: Message
}

type NewUserInput {
  username: String!
  password: String!
}

type ResetPasswordInput {
  username: String!
  password: String!
}

type NewUserPayload {
  user: User
}

type ResetPasswordPayload {
  user: User
}

type User {
  id: ID!
  username: String!
  messages: [Message!]
}
```

### Query Rewriter

As can be seen, it is quite simple to stitch multiple schemas together and enhance them with the stitching builder.

**But how can we go further and hook into the query rewriter of the stitching engine?**

Let us for instance try to get rid of the `createdById` field of the `Message` type as we actually do not want to expose this field to the consumer of the stitched schema.

Since our resolver for the newly introduced `createdBy` field is dependent on the `createdById` field in order to fetch the `User` from the remote schema, we would need to be able to request it as some kind of a hidden field whenever a `Message` object is resolved.

We could then write a little field middleware that copies us the hidden field data into our scoped context data, so that we are consequently able to use the id in our `delegate` directive by accessing the `createdById` via the scoped context data instead of referring to a field of the `Message` type.

The stitching engine allows us to hook into the the query rewrite process and add our own rewrite logic that could add fields or even large sub-queries.

The first thing we need to do here is to create a new class that inherits from `QueryDelegationRewriterBase`.

The base class exposes two virtual methods `OnRewriteField` and `OnRewriteSelectionSet`.

A selection set describes a selection of fields and fragments on a certain type.

So, in order to fetch a hidden field every time a certain type is requested we would want to overwrite `OnRewriteSelectionSet`.

```csharp
private class AddCreatedByIdQueryRewriter
    : QueryDelegationRewriterBase
{
    public override SelectionSetNode OnRewriteSelectionSet(
        NameString targetSchemaName,
        IOutputType outputType,
        IOutputField outputField,
        SelectionSetNode selectionSet)
    {
        if(outputType.NamedType() is ObjectType objectType
          && objectType.Name.Equals("Message"))
        {
            return selectionSet.AddSelection(
                new FieldNode
                (
                    null,
                    new NameNode("createdBy"),
                    new NameNode("createdById"),
                    Array.Empty<DirectiveNode>(),
                    Array.Empty<ArgumentNode>(),
                    null
                ));
        }

        return selectionSet;
    }
}
```

The syntax nodes have a lot of little rewrite helpers like `AddSelection`. These helper methods basically branch of the syntax tree and return a new version that contains the applied change.

In our case we get a new `SelectionSetNode` that now also contains a field `createdBy` with an alias `createdById`. In a real-world implementation we should use a more complex alias name like `___internal_field_createdById` in order to avoid collisions with field selections of the query.

Query delegation rewriters are registered with the dependency injection and not with our stitching builder.

```csharp
services.AddQueryDelegationRewriter<AddCreatedByIdQueryRewriter>();
```

> Query delegation rewriters are hosted as scoped services and can be injected with `IStitchingContext` and `ISchema` in order to access the remote schemas or the stitched schema for advanced type information.

With that in place, the stitching engine will always fetch the requested field for us whenever a `Message` object is requested.

So, now let us move on to write a little middleware that copies this data into our scoped resolver context data map. The data in this map will only be available to the resolvers in the subtree of the message type.

A field middleware has to be declared via the stitching builder.

```csharp
services.AddStitchedSchema(builder => builder
  .AddSchemaFromHttp("messages")
  .AddSchemaFromHttp("users")
  .AddSchemaFromHttp("analytics"))
  .AddExtensionsFromFile("./graphql/Extensions.graphql")
  .IgnoreField("analytics", "Query", "analytics")
  .IgnoreType("analytics", "MessageAnalytics")
  .IgnoreType("analytics", "CounterType")
  .IgnoreField("messages", "Message", "createdBy")
  .AddSchemaConfiguration(c =>
  {
    c.RegisterExtendedScalarTypes();

    c.Use(next => async context =>
    {
        await next.Invoke(context);

        if(context.Field.Type.NamedType() is ObjectType objectType
          && objectType.Name.Equals("Message")
          && context.Result is IDictionary<string, object> data
          && data.TryGetValue("createdById", out object value))
        {
            context.ScopedContextData =
                context.ScopedContextData.SetItem("createdById", value);
        }
    })
  })
```

> We could also declare a field middleware as class. More about what can be done with a field middleware can be found [here](https://hotchocolate.io/docs/middleware).

With all of this in place we can now rewrite our `Message` type extension and access the `createdById` from the scoped context data:

```graphql
extend type Message {
  createdBy: User!
    @delegate(schema: "users", path: "user(id: $scopedContextData:createdById)")
  views: Int! @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
  likes: Int! @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
  replies: Int!
    @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
}
```

### Customizing Stitching Builder

The stitching builder can be extended on multiple levels by writing different kinds of schema syntax rewriter.

#### Source Schema Rewriter

The refactoring methods that we provide like `IgnoreField` or `RenameType` and so on rewrite the source schemas before they are merged.

In order to rewrite the source schema we can opt to create a `IDocumentRewriter` that is able to rewrite the whole schema document, or a `ITypeRewriter` that only can rewrite parts of a type definition.

If we wanted to delete a type or write a rewriter that also refactors the impacted types of a change then the `IDocumentRewriter` would be the way to go.

If we wanted to rewrite just parts of a type like adding some documentation or adding new fields to a type, basically things that do not impact other types, we could opt for the `ITypeRewriter`.

In both types we could opt to use the rewriter and visitor base classes that are included in our parser package.

> Information about our parser can be found [here](https://hotchocolate.io/docs/parser).

#### Merged Schema Rewriter

Apart from the source schema rewriters we can also rewrite the schema document after it has been merged:

```csharp
IStitchingBuilder AddMergedDocumentRewriter(Func<DocumentNode, DocumentNode> rewrite);
```

This can be very useful if we want to first let all source schema rewriters do their work and annotate the types. With the annotations in place we could write complex rewriters that further enhance our stitched schema.

Also, if we just wanted to validate the schema for merge errors or collect information on the rewritten schema we are able to add schema visitors that run after all schema modifications are done.

```csharp
IStitchingBuilder AddMergedDocumentVisitor(Action<DocumentNode> visit);
```

#### Merge Rules

In most cases the default merge rules should be enough. But with more domain knowledge about the source schemas one could write more aggressive merge rules.

The merge rules are chained and pass along what they cannot handle. The types of the various schemas are bucketed by name and passed to the merge rule chain.

## Authentication

In many cases schemas will be protected by some sort of authentication. In most cases http requests are authenticated with bearer tokens that are passed along as `Authorization` header.

Moreover, the most common case that we have seen so far is that people want to pass the tokens along to the remote schema.

The stitching engine creates a lazy query executor that will only start merging the schemas on the first call to the GraphQL gateway. This allows us to use the token of an incoming call to execute the introspection queries on the remote schemas. This also safes us from having to store some kind of service token with the GraphQL gateway.

In order to pass on the incoming `Authorization` header to our registered HttpClients we need to first register the HttpContext accessor from ASP.net core.

```csharp
services.AddHttpContextAccessor();
```

Next, we need to update our HttpClient factory declaration:

```csharp
services.AddHttpClient("messages", (sp, client) =>
{
    HttpContext context = sp.GetRequiredService<IHttpContextAccessor>().HttpContext;

    if (context.Request.Headers.ContainsKey("Authorization"))
    {
        client.DefaultRequestHeaders.Authorization =
            AuthenticationHeaderValue.Parse(
                context.Request.Headers["Authorization"]
                    .ToString());
    }

    client.BaseAddress = new Uri("http://127.0.0.1:5050");
});
```

Another variant can also be to store service tokens for the remote schemas with our GraphQL gateway.

How you want to implement authentication strongly depends on your needs. With the reliance on the HttpClient factory from the ASP.net core foundation we are very flexible and can handle multiple scenarios.

## Batching

The stitching layer transparently batches queries to the remote schemas. So, if you extend types like the following:

```graphql
extend type Message {
  views: Int! @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
  likes: Int! @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
  replies: Int!
    @delegate(schema: "analytics", path: "analytics(id: $fields:id)")
}
```

We do send only a single request to your remote schema instead of three. The batching mechanism works not only within one type but extends to all requests that are executed in a resolver batch.

Furthermore, we are also including calls that are done through direct calls on the `IStitchingContext`.

Batching works very similar to _DataLoader_ where the stitching engine sends requests through the `IRemoteQueryClient` which consequently only fetches the data once the query engine signals that all resolvers have been enqueued and have registered their calls against the remote schemas. This reduces the calls to the remote-schemas significantly and improves the overall performance.

So, if we had two query calls:

Query 1:

```graphql
{
  customer(id: "abc") {
    name
    contracts {
      id
    }
  }
}
```

Query 2:

```graphql
{
  customer(id: "def") {
    name
    contracts {
      id
    }
  }
}
```

We would merge those two queries into one:

```graphql
{
  __1: customer(id: "abc") {
    name
    contracts {
      id
    }
  }
  __2: customer(id: "def") {
    name
    contracts {
      id
    }
  }
}
```

This lets the remote schema optimize the calls much better since now the remote schema could take advantage of things like _DataLoader_ etc.

## Root Types

We are currently supporting stitching `Query` and `Mutation`.

With Version 9 we will introduce stitching the `Subscription` type.

Stitching queries is straight forward and works like described earlier. Mutations are also quite straight forward, but it is often overlooked that mutations are executed with a different execution strategy.

Query resolvers are executed in parallel when possible. All fields of a query have to be side-effect free.

<https://facebook.github.io/graphql/June2018/#sec-Normal-and-Serial-Execution>

> Normally the executor can execute the entries in a grouped field set in whatever order it chooses (normally in parallel). Because the resolution of fields other than top‐level mutation fields must always be side effect‐free and idempotent, the execution order must not affect the result, and hence the server has the freedom to execute the field entries in whatever order it deems optimal.

The top‐level mutation fields are executed serially which guarantees that the top-level fields are executed one after the other.

```graphql
mutation {
  createUser(userName: "foo") {
    someFields
  }
  addUserToGroup(userName: "foo", groupName: "bar") {
    someFields
  }
}
```

The above example first creates a user and then adds the created user to a group. This means that mutations can only be stitched on the top level. Everything, that you stitch in the lower levels is delegating the request to a `Query` type.

Or, even simpler put, only fields that are declared on the mutation type can delegate to a mutation field on a remote query.

Let's put that in a context.

```graphql
type Mutation {
  newUser(input: NewUserInput!): NewUserPayload! @delegate(schema: "users")
}

type NewUserInput {
  username: String!
  password: String!
}

type NewUserPayload {
  user: User
}

type User {
  id: ID!
  username: String!
  messages: [Message!]
    @delegate(schema: "messages", path: "messages(userId: $fields:Id)")
}
```

In the above example we have a mutation that delegates the `newUser` field to the `newUser` mutation of the `users` schema. The mutation returns the `NewUserPayload` which has a field `user` that returns the newly created user. The `User` object delegates the `messages` field to the message schema. Since this field is resolved in the third level it will delegated to the query type of the `messages` schema.

This also means that we cannot group mutations like we could group queries. So, something like the following would not work since it is not spec-compliant:

```graphql
type Mutation {
  userMutations: UserMutations
}

type UserMutations {
  newUser(input: NewUserInput): NewUserPayload
}
```

## Stitching Context

The stitching engine provides a lot of extension points, but if we wanted to write the stitching for one specific resolver by ourselves then we could do that by using the `IStitchingContext` which is a scoped service and can be resolved through the resolver context.

```csharp
IStitchingContext stitchingContext = context.Service<IStitchingContext>();
IRemoteQueryClient remoteQueryClient = stitchingContext.GetRemoteQueryClient("messages");
IExecutionResult result = remoteQueryClient.ExecuteAsync("{ foo { bar } }")
```

## Example

We have a simple stitching example [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/Stitching).

## Version 9

We originally wanted to include subscription stitching with version 8, but are now moving this feature to next version.

Apart from that, Version 9 will mainly focus on schema improvements.

If you have feedback or feature requests for our schema stitching we love to talk to you about it. Head over to our slack channel.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 0.7.0]]></title>
        <id>https://chillicream.com/blog/2019/02/04/hot-chocolate-0.7.0</id>
        <link href="https://chillicream.com/blog/2019/02/04/hot-chocolate-0.7.0"/>
        <updated>2019-02-04T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we have released Hot Chocolate version 0.7.0 which brings a lot of new features, improvements and bug fixes. With this post I walk you through the major changes.

The main focus of this release was to make the execution engine more extendable.

The execution engine in version 0.6.0 was closed and as a user of Hot Chocolate you didn't really have any chance to change it's behavior.

The only way to write field middleware components was through directives. With our new release this will fundamentally change.

## QueryExecutionBuilder

With version 0.7.0 we opened up the field middleware pipeline to be extended.

Moreover, we broke the query execution pipeline into query middleware components that can be swapped out or extended by writing a query middleware.

This all can be done with the new `QueryExecutionBuilder` that provides a simple to use API to customize how the query executor works.

```csharp
  IQueryExecutor executor = QueryExecutionBuilder.New()
    .Use(next => context =>
    {
      // ...
    })
    .UseDefaultPipeline()
    .Build(schema);
```

Instead of using the default pipeline we can also add the included middleware components one by one and swap out the ones that we do want to replace.

```csharp
  IQueryExecutor executor = QueryExecutionBuilder.New()
    .AddOptions(options)
    .AddErrorHandler()
    .AddQueryValidation()
    .AddDefaultValidationRules()
    .AddQueryCache(options.QueryCacheSize)
    .AddExecutionStrategyResolver()
    .AddDefaultParser()
    .Use(next => context =>
    {
      // ...
    })
    .UseInstrumentation(options.TracingPreference)
    .UseRequestTimeout()
    .UseExceptionHandling()
    .UseQueryParser()
    .UseValidation()
    .UseOperationResolver()
    .UseMaxComplexity()
    .UseOperationExecutor();
    .Build(schema);
```

On top of the new execution pipeline we build features like:

- Apollo Tracing
- Schema Stitching
- Pagination Support

More about this can be read [here](https://hotchocolate.io/docs/middleware).

## Syntax Rewriter

We also invested in our parser and added a lot of visitor and rewriter base classes that make working with the syntax tree less effort.

**What are visitors and rewriter good for?**

We started really thinking about this feature when we conceived the new schema stitching. We wanted to branch of parts of the query and rewrite them to become a query for another schema that is located somewhere else.

Rewriters are basically visitors that walk the graph and as they do that create a new query. Basically you pass in a syntax node and the rewriter returns a new syntax node that represents the rewritten node.

```csharp
FieldNode newField = rewriter.Rewrite(originalField);
```

This can be very useful if we want to map a graph to a database or create something like a schema stitching layer etc.

More about this can be read [here](https://hotchocolate.io/docs/parser).

## GraphQL Spec State

With version 0.7.0 we have added support for repeatable directives. This feature is slated for the next GraphQL spec version and allows to pipeline directives like the following:

{
a @fetch @replace('a' 'b') @replace('b' 'c')
}

This behavior feels really awesome when you use executable directives, since with this you can build the field resolver pipeline by stacking directives together.

_Directives are per default non-repeatable._

## Error Filter

One of the regular questions users had was about how to handle custom exceptions with Hot Chocolate.

With exception filters we now provide you with a simple way to do just this.

The execution engine will transform any exception thrown into a generic GraphQL error.

With exception filters you can then rewrite those errors for certain exceptions in order to provide more useful information.

More about this can be read [here](/docs/hotchocolate/v10/execution-engine/error-filter).

## Schema Stitching

On top of the execution improvements we built our new schema stitching capabilities. With those you are able to easily fuse service endpoints together.

More about this can be read [here](/blog/2019/01/24/schema-stitching).

## Apollo Tracing

With version 0.7.0 we have introduced diagnostic sources that can be used to add custom tracing and diagnostic solutions.

Furthermore, we now support [Apollo Tracing](https://github.com/apollographql/apollo-tracing). Apollo Tracing can be opted in by setting the tracing preference on the execution options. We recommend to switch it to on-demand, which allows you to send a header when ever you want to get performance performance information about a call.

## Relay and Paging

We made creating relay compliant schemas a lot easier with this release. We introduced the paging structures as well as the node interface.

Relay compliant paging can be done with one line of code if your data is provided by `IQueryable<T>`.

```csharp
descriptor
  .Field(t => t.GetCustomers)
  .UsePaging<CustomerType>();
```

Moreover, we have introduced a middleware that makes your IDs schema unique like required by the relay server specs without you having to implement any of that.

We will follow up this post with a post on how to best build schemas for relay.

More about paging can be found [here](https://hotchocolate.io/docs/pagination).

## Type Conversion

Until now the type conversion logic of Hot Chocolate was not accessible by the developer. This caused a lot of frustration since we were not able to add custom type conversions in a transparent way. So, basically the user had to add this code into his/her resolver logic. This felt like clutter that should not be there.

We have now introduced a new type conversion API.

Let us say you are working with mongo and you want to add an `ObjectId` conversion that basically converts `string` to `ObjectId` and `ObjectId` to `string`.

```csharp
TypeConversion.Default.Register<string, ObjectId>(from => ObjectId.Parse(from));
TypeConversion.Default.Register<ObjectId, string>(from => from.ToString());
```

So, that basically settles it. Two lines of code an you are done. You can also implement `ITypeConverter` in order to accommodate more complex code or just because you want to have your converters in class form.

Furthermore, we can create a new `TypeConversion` instance that only contains our specified conversion logic and none of our default converters in order to have tight control over them.

In this case we add the `TypeConversion` instance to our dependency injection and the execution engine will prefer the one provided via dependency injection over `TypeConversion.Default`.

## DataLoader

We already provided an API for writing _DataLoader_ but due to feedback from the community we rewrote our implementation to make it easier to use. You can now write _DataLoader_ with a single line of code by providing us with a delegate that fetches your data.

An example project that shows the new _DataLoader_ can be found [here](https://github.com/ChilliCream/hotchocolate-examples/tree/master/misc/DataLoader).

Or head over to our documentation [here](https://hotchocolate.io/docs/dataloaders).

## Scalar Types

We removed our extended scalars from the base setup. This means that you now have to tell your schema to use these.

```csharp
Schema.Create(c =>
{
    c.RegisterExtendedScalarTypes();
});
```

This gives you more control about your type system and allows you to implement your own version of long etc.

More about scalar types can be found [here](https://hotchocolate.io/docs/custom-scalar-types).

## Generic InterfaceType and UnionType

The generic `InterfaceType` allows you to assign a .Net interface to a GraphQL interface. All object types that then have a .Net type associated will automatically implement this interface if the .Net type implements the .Net interface. Confused :)

Let`s see some code:

```csharp
public class FooType : InterfaceType<IFoo>
{

}
```

If we would do nothing else we will infer the fields from the interface.

If we now had the following type:

```csharp
public class Bar : IFoo { }

public class BarType : ObjectType<Bar>
{

}
```

Then we do not explicitly need to point to the interface anymore since we can infer the usage of the interface.

The same works for generic union types where you now can use marker interfaces to assign types to a set. For our purists that only want to you .Net types the following works now to:

```csharp
Schema.Create(c =>
{
    c.RegisterType<IFoo>();
    c.RegisterType<Bar>();
});
```

## Source Code Link

We now support NuGet source code link. This means that you can debug into the Hot Chocolate source. This is often a great help when you are struggling with a bug or do want to check whats happening.

## What`s coming next

Version 7 was a big release with a lot of new features that make it very easy to setup a GraphQL schema in .Net. With this release out we now focus on Version 8 which will focus on schema stitching. We will introduce capabilities like auto-stitching and auto-mocking. We already started working on the new schema stitching stories and if you think you would like to contribute ideas or code or documentation just feel free to talk to us. We are quite happy for any help.

After the schema stitching enhancements we will focus on the new schema builder with Version 9. The schema builder will bring in completely new capabilities that let you extend the schema building process. We are basically opening up the schema building process like we did with the execution engine.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL .NET Instrumentation API and Apollo Tracing]]></title>
        <id>https://chillicream.com/blog/2019/02/04/instrumentation-and-apollo-tracing</id>
        <link href="https://chillicream.com/blog/2019/02/04/instrumentation-and-apollo-tracing"/>
        <updated>2019-02-04T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we have released Hot Chocolate `0.7.0`, containing one cool new feature,
we want to talk about here, namely _Apollo Tracing_ which is extremely powerful in
identifying things like performance bottlenecks in our _GraphQL_ _APIs_ for
example. As a result, we had to enhance our general instrumentation layer, which
we all benefit from. For instance, now it's way easier to register a
_DiagnosticObserver_ and bring in your own tracing framework, respectively. In
this blog article we will focus on these two topics.

## Apollo Tracing

_Apollo Tracing_ is a [performance tracing specification] for _GraphQL_ servers.
It's not part of the actual _GraphQL_ [specification] itself, but there is a
common agreement in the _GraphQL_ community that this should be supported by
all _GraphQL_ servers.

So, we decided to introduce built-in _Apollo Tracing_ support with this version.
In order to enable _Apollo Tracing_ we just need to provide our own instance of
`QueryExecutionOptions` to the `AddGraphQL` extension method and set the
`TracingPreference` option to either `TracingPreference.Always` or
`TracingPreference.OnDemand`. The difference between these two options is
whether tracing should be enabled always which means for each request or on
demand which means per request. But for now, enough words, let's see how this
would look like in code.

```csharp
services.AddGraphQL(sp => Schema.Create(c =>
{
    // Here goes the schema definition which is omitted for brevity purpose
}),
new QueryExecutionOptions
{
    TracingPreference = TracingPreference.Always
});
```

There it is. Very simple and straightforward, right? For more information head
over [here](https://hotchocolate.io/docs/apollo-tracing). Now, let's jump over to
the next topic.

## Instrumentation API

In this version we did some heavy lifting in form of refactorings regarding the
query execution pipeline. This really helped us enhancing the
_Instrumentation_ _API_ which has been evolved in two ways. First, we increased
the amount of available diagnostic events for more fine-grained tracing
scenarios. Second, we simplified the registering of _DiagnosticObservers_ by
using _Dependency Injection_ infrastructure. In the next example we can see how
to register a custom _DiagnosticObservers_.

```csharp
services.AddGraphQL(sp => Schema.Create(c =>
{
    // Here goes the schema definition which is omitted for brevity purpose
}),
builder =>
{
    return builder
        .UseDefaultPipeline()
        .AddDiagnosticObserver<CustomDiagnosticObserver>();
});
```

So far so good. Writing a custom _DiagnosticObservers_ is not difficult. Let's
see how we could achieve this.

```csharp
using HotChocolate.Execution;
using Microsoft.Extensions.DiagnosticAdapter;

namespace CustomNamespace
{
    internal class CustomDiagnosticObserver
        : IDiagnosticObserver
    {
        [DiagnosticName("HotChocolate.Execution.Query")]
        public void QueryExecute()
        {
            // This method is required to enable recording "Query.Start" and
            // "Query.Stop" diagnostic events. Do not write code in here.
        }

        [DiagnosticName("HotChocolate.Execution.Query.Start")]
        public void BeginQueryExecute(IQueryContext context)
        {
            // Here goes your code to trace begin query execution events.
        }

        [DiagnosticName("HotChocolate.Execution.Query.Stop")]
        public void EndQueryExecute(
            IQueryContext context,
            IExecutionResult result)
        {
            // Here goes your code to trace end query execution events.
        }
    }
}
```

In the above example we showed you just a few diagnostic events. Head over
[here](https://hotchocolate.io/docs/instrumentation) for a complete list of
diagnostic events.

We hope you enjoyed reading and be welcome to let us know what you think about
it in the comments section. Thank you!

[performance tracing specification]: https://github.com/apollographql/apollo-tracing
[specification]: https://facebook.github.io/graphql
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Schema Stitching]]></title>
        <id>https://chillicream.com/blog/2019/01/24/schema-stitching</id>
        <link href="https://chillicream.com/blog/2019/01/24/schema-stitching"/>
        <updated>2019-01-24T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
What is schema stitching actually? Schema stitching is the capability to merge multiple GraphQL schemas into one schema on which queries can be queried.

## Introduction

So, for what is that useful? In our case we have lots of specialized services that serve data for a specific problem domain. Some of these services are GraphQL services, some of them are REST services and yes sadly a little portion of those are still SOAP services.

Also, think about this, you cannot always start fresh and with schema stitching you can now create the schema of your **dreams** and merge all those other services into that new glorified schema.

Apart from that UI teams tend to **NOT** want to know about all those domain services and their specifics. They want to be able to fetch the data they need with one call, no under- or over-fetching and most importantly no repeated fetching because you first needed to fetch that special id with which you now can fetch this other thing. No, what we really want here is to have one source of truth and one call to get exactly what we want. That's what GraphQL is all about.

Furthermore, we believe the schemas should be consistent and provide a way that is easily to consume.

With the preview version 0.7.0-preview.35 we are now introducing schema stitching capabilities to [Hot Chocolate](https://hotchocolate.io/).

In this post I will walk you through how you can use schema stitching, what will be available with version 0.7.0 and what features come with the next releases.

## Getting Started

Assume we have two schemas one dealing with the customer data, basically the data that would be located in a CRM system of a company, the other representing insurance data about the customer, basically the technical domain specific data that gives you all the insights into the customers insurance contracts.

The stitching layer is not limited to two schemas, you can actually stitch together how many schemas you want. But for our example we use those two mentioned schemas about customers and their contracts.

So, let's say our customer schema looks something like the following:

```graphql
type Query {
  customer(id: ID!): Customer
  consultant(id: ID!): Consultant
}

type Customer {
  id: ID!
  name: String!
  consultant: Consultant
}

type Consultant {
  id: ID!
  name: String!
}
```

In real life this schema would boast a lot more information about our customer but this will suffice for our little demo.

And our second schema dealing with the insurance contracts looks like the following:

```graphql
type Query {
  contract(contractId: ID!): Contract
  contracts(customerId: ID!): [Contract!]
}

interface Contract {
  id: ID!
}

type LifeInsuranceContract implements Contract {
  id: ID!
  premium: Float
}

type SomeOtherContract implements Contract {
  id: ID!
  expiryDate: DateTime
}
```

Imagine we have two servers serving up those schemas. The schema that we actually want for our UI team should look like the following:

```graphql
type Query {
  customer(id: ID!): Customer
}

type Customer {
  id: ID!
  name: String!
  consultant: Consultant
  contracts: [Contract!]
}

type Consultant {
  id: ID!
  name: String!
}

interface Contract {
  id: ID!
}

type LifeInsuranceContract implements Contract {
  id: ID!
  premium: Float
}

type SomeOtherContract implements Contract {
  id: ID!
  expiryDate: DateTime
}
```

In order to make that happen you do not have to write actual code, we have create some directives that will tell the stitching layer what to do.

Before we start, we have to give our schemas some names, these names will be used to direct remote queries to the right endpoint.

Let's name the customer schema `customers` and the contract schema `contracts`. With that let's decorate our desired schema.

```graphql
type Query {
  customer(id: ID!): Customer @schema(name: "customer") @delegate
}

type Customer {
  id: ID!
  name: String!
  consultant: Consultant
  contracts: [Contract!]
    @schema(name: "contract")
    @delegate(path: "contracts(customerId:$fields:id)")
}

type Consultant {
  id: ID!
  name: String!
}

interface Contract {
  id: ID!
}

type LifeInsuranceContract implements Contract {
  id: ID!
  premium: Float
}

type SomeOtherContract implements Contract {
  id: ID!
  expiryDate: DateTime
}
```

`@schema` basically points to the source schema, so the stitching middleware will redirect calls to a schema with the name that is specified by this directive.

`@delegate` specifies how the data is fetched. If `@delegate` does not have any path specified than the middleware expects that the field on the target schema has the same specification.

If we look at the `customer` field then the middleware will assume that the source schema has the same customer field as root field as our stitched schema.

The `contracts` field on the other hand specifies a delegation path `contracts(customerId:$fields:id)`. The delegation path specifies the field that is called and where the arguments get their input from.

Let us assume you have a deeper field from which you want to fetch data like the following.

```graphql
foo(id:123) {
  bar {
    baz(top:1) {
      qux
    }
  }
}
```

Since, we did not want to cram a query like this into one string we allow this to be done with a flat path.

```text
foo(id:$arguments:arg1).bar.baz(top:1)
```

The argument assignment in the path can be done with GraphQL literals or with scope variables. The scope variables basically can refer to the fields of the declaring type (in case of our contracts field the declaring type is customer) and to the arguments of the field, in our case contracts has no arguments in the stitched schema.

## Server Configuration

Now that we have configured our schema let's create our server. The fastest way to do that is to use our server template.

Install the server template to your dotnet CLI:

```bash
dotnet new -i HotChocolate.Templates.Server
```

Now let's create our server:

```bash
mkdir stitching
dotnet new graphql-server
```

Open the server in the editor of your choice and upgrade the packages to 0.7.0-preview.35.

Go to the Startup.cs and add the HTTP clients that shall access the remote schema endpoints like the following:

```csharp
services.AddHttpClient("customer", client =>
{
    client.BaseAddress = new Uri("http://127.0.0.1:5050");
});

services.AddHttpClient("contract", client =>
{
    client.BaseAddress = new Uri("http://127.0.0.1:5051");
});
```

Note that this is also the place where you would add authentication and header properties in order to access your remote schema endpoint.

The clients must be named clients and have to use the schema name that we used in our schema directive earlier.

Next let's setup our remote schemas. Remote schemas are actually local schemas representing the remote schemas and allowing us to treat the remote schema as if it were a usual schema written with Hot Chocolate.

This also allows us to create middleware components and other things on such a schema although the schema does not actually live in our process.

So let us start with the customer schema, the customer schema does only use scalars defined in the spec. This means we do not have to declare any extra scalars to our stitching layer.

```csharp
serviceCollection.AddRemoteQueryExecutor(b => b
    .SetSchemaName("customer")
    .SetSchema(File.ReadAllText("Customer.graphql")));
```

Again we use our schema name that we used earlier and we are loading a schema file describing the remote schema into the remote executor. We are basically building with that a schema the way you would with the schema-first approach.

Next, let's setup our contracts schema. The contracts schema uses a `DateTime` scalar, this one is not specified in the spec so we have to tell our schema to use this one. Since Hot Chocolate specified a bunch of extended scalars we can import one of those. If we do not have a scalar matching the one of the remote schema we would need to implement this one by extending the class `ScalarType`.

```csharp
serviceCollection.AddRemoteQueryExecutor(b => b
    .SetSchemaName("contract")
    .SetSchema(FileResource.Open("Contract.graphql"))
    .AddScalarType<DateTimeType>());
```

Now that we have setup our remote schema let's stitch everything together by providing our prepared stitched schema file:

```csharp
serviceCollection.AddStitchedSchema(
    FileResource.Open("Stitching.graphql"),
    c => c.RegisterType<DateTimeType>());
```

Again like before we have to provide the extended scalar type that we used for the contracts schema.

Now, we are basically done and can fire up our server.

## Further Thoughts

Since, remote schemas have a local schema representation in our process and the stitching layer is working on those local schemas we can also use native Hot Chocolate schemas to further extend a stitched schema.

So, all what I have described so far is included in the current preview release. We are still not done and are heavy at work getting our schema stitching even better.

With the next view preview builds we will introduce a batching layer to the schema stitching.

Think _DataLoader_. We will basically batch all request to a schema in one go. Imagine we had two delegated query for one remote schema:

Query A:

```graphql
{
  a {
    b
  }
}
```

Query B:

```graphql
{
  c {
    d
  }
}
```

The batching layer will rewrite those queries into one and send just one request to your remote endpoint:

```graphql
{
  __1: a {
    b
  }

  __2: c {
    d
  }
}
```

This way we have just one call and your remote endpoint can better optimize the data fetching with _DataLoader_ and so on.

## Coming with 0.8.0

Furthermore, we will introduce the ability to rename types. This is useful when you either want to make names more clear or if you have naming collisions. So, with the next releases we will introduce '@name' as a way to rename types and fields.

Also, the ability to auto-stitch schemas and auto-fetch the a remote schema via introspection is on our todo list.

In the beginning of this post I talked about stitching SOAP and REST, we are currently working on a feature that is called HTTP directives.

HTTP directives let you decorate a schema SDL and thus let you map REST services onto a GraphQL schema. This schema can also be included into a stitched schema. We will tell you more about that once we have a stable version ready to go.

Moreover, we will introduce a cast feature to our delegation path. This will basically allow you to use fragments without having to write the code.

```text
foo.bar<baz>(a:1).qux(b:1)
```

This translates basically to:

```graphql
{
  foo {
    bar(a: 1) {
      ... on baz {
        qux(b: 1)
      }
    }
  }
}
```

## Wrapping things up

We have uploaded the above example to the following GitHub repo so you can see a working example of the schema stitching.

[Stitching Example](https://github.com/ChilliCream/hotchocolate-examples)

If you are using the example start the two remote schemas by switching to their respective directory and call `dotnet run`.

After both schemas are running start the stitching layer. The stitching layer has `Apollo Tracing` enabled. Start the stitching layer also with `dotnet run` since the debugger slows the performance significantly down.

The first call on the stitched schema takes a little longer (maybe 300 ~ 500 ms) since we are compiling the resolvers into an in-memory assembly. All further calls are fast (4 ~ 8 ms) in our example. The real life performance depends on how fast your connection to the stitched remote schemas is and how many data you are fetching. With the new batching layer that is coming soon the performance of the schema stitching should further improve.

Open playground on <http://localhost:5000/playground> in order to fire up some requests against our stitched schema and checkout the tracing tab for performance insights.

The following query might be a good starting point since it will expose the ids of our objects.

```graphql
{
  customers {
    id
    contracts {
      id
    }
  }
}
```

If you have further questions or need help you join our slack channel.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Docusaurus - How to redirect requests to /docs to a default url instead of getting a 404 error]]></title>
        <id>https://chillicream.com/blog/2018/11/07/docusaurus-docs-redirect</id>
        <link href="https://chillicream.com/blog/2018/11/07/docusaurus-docs-redirect"/>
        <updated>2018-11-07T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
I recently run into an HTTP 404 error when calling /docs on my _Docusaurus_ websites. This isn't
actually nice, because I expected to land on my documentation entry page e.g. introduction. First I
thought, perhaps this is an issue with my setup. But I found out that even the _Docusaurus_ website
itself is suffering from this issue as well. So I tried to find a solution on the internet. But
I couldn't find anything except an issue on github describing the same behavior. So, with this article
I try to help everyone saving their time and making the experience with _Docusaurus_ even better.

So here is my solution.

1. Go to your `website\siteConfig.js` file and update the entry doc link in the `headerLinks`
   section by adding `href: "/docs"` to it.

**Before**

```javascript
{
  // code omitted for brevity
  headerLinks: [
    {
      doc: "your-entry-doc",
      label: "Docs",
    },
  ];
}
```

**After**

```javascript
{
  // code omitted for brevity
  headerLinks: [
    {
      doc: "your-entry-doc",
      href: "/docs",
      label: "Docs",
    },
  ];
}
```

2. Create a new file called `docs.js` under the `website\pages\en` path and insert the following
   code.

```javascript
/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const React = require("react");
const Redirect = require("../../core/Redirect.js");

const siteConfig = require(process.cwd() + "/siteConfig.js");

function docUrl(doc, language) {
  return (
    siteConfig.baseUrl +
    "docs/" +
    (language ? language + "/" : "") +
    doc +
    ".html"
  );
}

class Docs extends React.Component {
  render() {
    return (
      <Redirect
        redirect={docUrl("your-entry-doc", this.props.language)}
        config={siteConfig}
      />
    );
  }
}

module.exports = Docs;
```

This code is just doing a redirect to `/docs/your-entry-doc`. Don't forget to replace
`your-entry-doc` with your own value.

Perfect! With this little change, our _Docusaurus_ website is now able to handle requests to the
`/docs` root path.

One little thing: I have tested it with _Docusaurus_ version `1.5.1`. However, just try it!
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 0.4.5]]></title>
        <id>https://chillicream.com/blog/2018/09/02/hot-chocolate-0.4.5</id>
        <link href="https://chillicream.com/blog/2018/09/02/hot-chocolate-0.4.5"/>
        <updated>2018-09-02T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
With version 0.4.5 we closed a lot of spec gaps and refined the schema configuration API.

We now are finished with implementing the query validation rules. The following rules were added since version 0.4.0:

- Argument Names [111](https://github.com/ChilliCream/graphql-platform/issues/111)
- Fragments Must Be Used [116](https://github.com/ChilliCream/graphql-platform/issues/116)
- Fragment Name Uniqueness [113](https://github.com/ChilliCream/graphql-platform/issues/113)
- Leaf Field Selections [110](https://github.com/ChilliCream/graphql-platform/issues/110)
- Fragments On Composite Types [115](https://github.com/ChilliCream/graphql-platform/issues/115)
- Fragment spreads must not form cycles [118](https://github.com/ChilliCream/graphql-platform/issues/118)
- Fragment spread target defined [117](https://github.com/ChilliCream/graphql-platform/issues/117)
- Fragment spread is possible [119](https://github.com/ChilliCream/graphql-platform/issues/119)
- Fragment Spread Type Existence [114](https://github.com/ChilliCream/graphql-platform/issues/114)
- Input Object Field Names [121](https://github.com/ChilliCream/graphql-platform/issues/121)
- Input Object Required Fields [123](https://github.com/ChilliCream/graphql-platform/issues/123)
- Input Object Field Uniqueness [122](https://github.com/ChilliCream/graphql-platform/issues/122)
- Directives Are Defined [124](https://github.com/ChilliCream/graphql-platform/issues/124)
- Values of Correct Type [120](https://github.com/ChilliCream/graphql-platform/issues/120)

We now also support the `@deprecated` directive when using schema-first.

Furthermore, we fixed a lot of bugs around schema-first. So, at the moment code-first is still the most viable way to create a schema,but we are working hard to get both flavours on par.

Apart from that we now allow for non-terminating errors within a field-resolver.

```csharp
public IEnumerable<ICharacter> GetCharacter(string[] characterIds, IResolverContext context)
{
    foreach (string characterId in characterIds)
    {
        ICharacter character = _repository.GetCharacter(characterId);
        if (character == null)
        {
            context.ReportError(
                "Could not resolve a character for the " +
                $"character-id {characterId}.");
        }
        else
        {
            yield return character;
        }
    }
}
```

If you want to share resolver logic between types in your schema you can now do that with shared resolvers which can be bound to fields:

```csharp
public class PersonResolvers
{
    public Task<IEnumerable<Person>> GetFriends(Person person, [Service]IPersonRepository repository)
    {
        return repository.GetFriendsAsync(person.FriendIds);
    }
}

public class PersonType : ObjectType<Person>
{
    protected override void Configure(IObjectDescriptor<Person> desc)
    {
        desc.Field(t => t.FriendIds).Ignore();
        desc.Field<PersonResolver>(t => t.GetFriends(default, default));
    }
}
```

## What Comes Next

With version 0.5 we will focus on subscriptions and custom directives.

Custom will allow for writing field resolver middlewares that alter or replace the default execution behavior.

Subscriptions is one of our last spec gaps.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL - Hot Chocolate 0.4.0]]></title>
        <id>https://chillicream.com/blog/2018/07/31/hot-chocolate-0.4.0</id>
        <link href="https://chillicream.com/blog/2018/07/31/hot-chocolate-0.4.0"/>
        <updated>2018-07-31T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
With this version we introduce support for _DataLoaders_ and custom context objects.

## Data Loaders

Here is a short introduction to _DataLoaders_.

> A DataLoader is a generic utility to be used as part of your application's data fetching layer to
> provide a consistent API over various backends and reduce requests to those backends via batching
> and caching. -- facebook

If you want to read more about _DataLoaders_ in general, you can head over to Facebook's [GitHub repository](https://github.com/facebook/dataloader).

GraphQL is very flexible in the way you can request data. This flexibility also introduces new classes of problems called _n+1_ issues for the GraphQL server developer.

In order to depict the issue that DataLoaders solve in this context, let me introduce a little GraphQL schema:

```graphql
type Query {
  person(id: ID): Person
}

type Person {
  id: ID
  name: String
  friends: [Person]
}
```

The above schema allows to fetch a person by its internal identifier and each person has a list of friends that is represented by a list of persons.

Since GraphQL requests are not fixed requests like REST requests, the developer really defines what data he/she wants. This avoids over-fetching data that you do not need and also saves you unnecessary round-trips to the GraphQL backend.

So, a query against the above schema could look like the following:

```graphql
{
  a: person(id: "a") {
    name
  }

  b: person(id: "b") {
    name
  }
}
```

The above request fetches two persons in one go without the need to call the backend twice. The problem for the GraphQL backend is that field resolvers are atomic and do not have any knowledge about the query as a whole. So, a field resolver does not know that it will be called multiple times in parallel to fetch similar or equal data from the same data source.

This basically represents the first case where _DataLoaders_ help us by batching requests against our database or backend service. Currently, we allow _DataLoaders_ per request and globally.

So, let's look at some code in order to understand what they are doing. First, let's have a look at how we would write our field resolver without _DataLoaders_:

```csharp
public async Task<Person> GetPerson(string id, [Service]IPersonRepository repository)
{
    return await repository.GetPersonById(id);
}
```

The above example would result in two calls to the person repository that would than fetch the persons one by one from our data source.

If you think that through you can see that each GraphQL request would cause multiple requests to our data source resulting in sluggish performance and unnecessary round-trips to our data source.

This, means that we reduced the round-trips from our client to our server with GraphQL but multiplied the round-trips between the data sources and the service layer.

With _DataLoaders_ we can now centralize our person fetching and reduce the number of round trips to our data source.

First, we have to create a _DataLoader_ that now acts as intermediary between a field resolver and the data source.

```csharp
public class PersonDataLoader
    : DataLoaderBase<string, Person>
{
    private readonly IPersonRepository _repository;

    public PersonDataLoader(IPersonRepository repository)
        : base(new DataLoaderOptions<string>())
    {
        _repository = repository;
    }

    protected override Task<IReadOnlyList<Result<string>>> Fetch(
        IReadOnlyList<string> keys)
    {
        return _repository.GetPersonBatch(keys);
    }
}
```

The _DataLoader_ is now injected by the execution engine as a field resolver argument.

_DataLoaders_ have to be injected at field resolver argument level and **NOT** as constructor arguments since the lifetime of a _DataLoader_ is in many cases shorter than the class containing the field resolvers.

```csharp
public Task<Person> GetPerson(string id, [DataLoader]PersonDataLoader personLoader)
{
    return personLoader.LoadAsync(id);
}
```

Next, we have to register our _DataLoader_ with the schema. By default, _DataLoaders_ are registered as per-request meaning that the execution engine will create one instance of each _DataLoader_ per-request **if** a field resolver has requested a _DataLoader_. This ensures that, _DataLoaders_ that are not being requested are not instantiated unnecessarily.

```csharp
Schema.Create(c =>
{
    // your other code...

    c.RegisterDataLoader<PersonDataLoader>();
});
```

Now, person requests in a single execution batch will be batched to the data source.

But there are still some more issues ahead that _DataLoaders_ will help us with. For that we should amend our query a little bit.

```graphql
{
  a: person(id: "a") {
    name
    friends {
      name
    }
  }

  b: person(id: "b") {
    name
    friends {
      name
    }
  }
}
```

The above query now drills down into the friends property, which again yields persons.

Let's, say our person object is located in a mongo database and the document would look something like the following:

```json
{
  "id":"a"
  "name":"Foo"
  "friends": [
    "b",
    "c",
    "d"
  ]
}

{
  "id":"b"
  "name":"Bar"
  "friends": [
    "a",
    "c",
    "e"
  ]
}
```

The person with ID `a` is also friends with person `b`. Moreover, `a` is also friends with `c` and `d`. Furthermore, `b` is friends with `a` and also friends with `c` and `e`.
The best case now would be that we only fetch `c`, `d` and `e` since we have already fetched `a` and `b`.

This is the second problem class the _DataLoader_ utility helps us with since the _DataLoader_ contains a cache and holds the resolved instances by default for the duration of your request.

For more information about our _DataLoader_ implementation head over to our _DataLoader_ [GitHub repository](https://github.com/ChilliCream/greendonut).

As a side note, you are not bound to our _DataLoader_ implementation. If you want to create your own implementation of _DataLoaders_ or if you already have a _DataLoader_ implementation then you can hook this up to our execution engine as well. I will explain this in the _DataLoader_ documentation once I have finalized it.

## Custom Context Objects

Custom context objects are basically custom .net objects that you can declare with the GraphQL engine and access throughout your request execution. Custom context objects can use dependency injection and have the same scoping as the _DataLoaders_.

For example you could declare a class that handles authorization for your service like an IPrincipal and access this in each resolver.

```csharp
public Task<ResolverResult<Person>> GetPerson(string id, [State]MyPrincipal principal)
{
    if(principal.IsInRole("foo"))
    {
      return new ResolverResult<Person>(personLoader.LoadAsync(id));
    }
    return new ResolverResult<Person>(
      "You do not have the access role to access this person.");
}
```

Moreover, you can use this custom context to store states in or caches during execution time. This will become especially useful with our next version when we allow the writing of custom schema directives and field resolver middlewares.

Custom context objects are registered like _DataLoaders_:

```csharp
Schema.Create(c =>
{
    // your other code...

    c.RegisterCustomContext<MyPrincipal>();
});
```

Like with _DataLoaders_ we have multiple `RegisterCustomContext` overloads that allow for more control over how the object is created.

## Query Validation

With this release we have also implemented the following query validation rules:

- [All Variables Used](http://facebook.github.io/graphql/June2018/#sec-All-Variables-Used)
- [All Variable Uses Defined](http://facebook.github.io/graphql/June2018/#sec-All-Variable-Uses-Defined)
- [Directives Are In Valid Locations](http://facebook.github.io/graphql/June2018/#sec-Directives-Are-In-Valid-Locations)
- [Directives Are Unique Per Location](http://facebook.github.io/graphql/June2018/#sec-Directives-Are-Unique-Per-Location)
- [Variables Are Input Types](http://facebook.github.io/graphql/June2018/#sec-Variables-Are-Input-Types)
- [Field Selection Merging](http://facebook.github.io/graphql/June2018/#sec-Field-Selection-Merging)

You can follow our progress on which rule is implemented [here](https://github.com/ChilliCream/graphql-platform/projects/3).

We plan for full compliance with the June 2018 spec version with version 0.6.0.

## Dependency Injection

We reworked out dependency injection approach and have now integrated the request services during request execution. Meaning you are now able to access HttpContext directly as a field resolver argument.

This was already possible with the old version through the accessor as a constructor injection.

Generally speaking, you can now let the execution engine inject any service as a field resolver argument.

```csharp
public async Task<Person> Example1(string id, [Service]IPersonRepository repository)
{
    return await repository.GetPersonById(id);
}

public async Task<Person> Example2(string id, [Service]HttpContext context)
{
    return await repository.GetPersonById(id);
}
```

It is important to know that http related services are only available if the execution engine runs integrated into ASP.net core. So, basically if you are using our middleware.

From a design standpoint you should avoid accessing this directly and think about a custom context object which would provide some abstraction.

I will write some more on dependency injection sometime later this week.
]]></content>
        <author>
            <name>Michael Staib</name>
            <uri>https://github.com/michaelstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Green Donut 0.2.0]]></title>
        <id>https://chillicream.com/blog/2018/07/30/green-donut-0.2.0</id>
        <link href="https://chillicream.com/blog/2018/07/30/green-donut-0.2.0"/>
        <updated>2018-07-30T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we proudly released the first version of _Green Donut_ -- a _DataLoader_ implementation for _.net core_ and _classic_.

**Additional Features**

- _Sliding Expiration_ for caching (default is set to zero which means that the entries in the cache will never expire)
- _Manual Dispatching_ for dispatching programmatically
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Rasta 1.0.0]]></title>
        <id>https://chillicream.com/blog/2018/05/03/react-rasta-1.0.0</id>
        <link href="https://chillicream.com/blog/2018/05/03/react-rasta-1.0.0"/>
        <updated>2018-05-03T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
Today we proudly released the first version of _React Rasta_.

_React Rasta_ is a responsive 12 column grid system which offers a lot of features and flexibility.
Its _API_ is clean and simple to ease development. _React Rasta_ is also well tested to guarantee
high quality. We hope _React Rasta_ will support you by creating great application. Have fun!
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[How to create a Form Wizard using jQuery Steps]]></title>
        <id>https://chillicream.com/blog/2013/09/12/jquery-steps-form-wizard</id>
        <link href="https://chillicream.com/blog/2013/09/12/jquery-steps-form-wizard"/>
        <updated>2013-09-12T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
This blog article was previously published on <http://www.rafaelstaib.com/post/How-to-create-a-Form-Wizard-using-jQuery-Steps>.

## Motivation

Sometimes it's better to separate a large or complex form into different sections. It’s because your form looks much cleaner and less difficult. Despite that fact people want to be guided through complex processes without understanding those deeply.

## Situation

There are many options to realize such a form wizard. You could use for example just static HTML files for each step one and link them together. But this, actually, could be really frustrating for you and the people visiting your site. Think of maintaining an existing wizard (e.g. adding a new step or changing links) then you have to touch in worst case all the existing steps that are involved. On the other hand your visitors get frustrated because of the many page requests and their accompanying latency time. However, all this isn’t probably new for you. Therefore, let’s step over!

## Solution

Let me explain you how I usually solve this problem. I prefer using **jQuery Steps** a jQuery UI plugin because of its simplicity and feature-richness. And most important it’s free (open source). Just grab and use it!

But for now enough words - let’s get our hands dirty!

First of all, we will download **jQuery Steps** from [here](http://www.jquery-steps.com) and take the basic example markup from [there](http://www.jquery-steps.com/GettingStarted#basic) – done. Not really but it isn’t far away from being done.

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Demo</title>
    <meta charset="utf-8" />
    <script src="jquery.js"></script>
    <script src="jquery.steps.js"></script>
    <link href="jquery.steps.css" rel="stylesheet" />
  </head>
  <body>
    <script>
      $("#wizard").steps();
    </script>
    <div id="wizard"></div>
  </body>
</html>
```

What else? We have to replace this `<div id="wizard"></div>` part by our own form markup and override the bodyTag property on initialization.

```html
<form id="form-3" action="#">
  <h1>Account</h1>
  <fieldset>
    <legend>Account Information</legend>

    <label for="userName">User name *</label>
    <input id="userName" name="userName" type="text" class="required" />
    <label for="password">Password *</label>
    <input id="password" name="password" type="text" class="required" />
    <label for="confirm">Confirm Password *</label>
    <input id="confirm" name="confirm" type="text" class="required" />
    <p>(*) Mandatory</p>
  </fieldset>

  <h1>Profile</h1>
  <fieldset>
    <legend>Profile Information</legend>

    <label for="name">First name *</label>
    <input id="name" name="name" type="text" class="required" />
    <label for="surname">Last name *</label>
    <input id="surname" name="surname" type="text" class="required" />
    <label for="email">Email *</label>
    <input id="email" name="email" type="text" class="required email" />
    <label for="address">Address</label>
    <input id="address" name="address" type="text" />
    <label for="age"
      >Age (The warning step will show up if age is less than 18) *</label
    >
    <input id="age" name="age" type="text" class="required number" />
    <p>(*) Mandatory</p>
  </fieldset>

  <h1>Warning</h1>
  <fieldset>
    <legend>You are to young</legend>

    <p>Please go away ;-)</p>
  </fieldset>

  <h1>Finish</h1>
  <fieldset>
    <legend>Terms and Conditions</legend>

    <input
      id="acceptTerms"
      name="acceptTerms"
      type="checkbox"
      class="required"
    />
    <label for="acceptTerms">I agree with the Terms and Conditions.</label>
  </fieldset>
</form>
```

This is just a normal form which you should be familiar with. The small difference [here](http://www.jquery-steps.com/Examples#advanced-form) is that we use a h1 tag on top of each fieldset tag. **jQuery Steps** needs that to build the wizard navigation. I grabbed that from here and there you can also see how it works in action.

The following code shows how to override the bodyTag property in order to tell **jQuery Steps** to use the fieldset tag as body container instead of div.

```javascript
$("#wizard").steps({
  bodyTag: "fieldset",
});
```

Actually, we are done but to offer users a rich and intuitive experience we will add an additional jQuery plugin which all of you very probably already know; **jQuery Validation** (for more Information see [here](http://jqueryvalidation.org/)). It's a plugin for doing form input validation. Furthermore, we will attach four event handler functions containing some extra magic. Finally, we will initialize **jQuery Validation**. Since both plugins are built on top of **jQuery**, we can make use of chaining (e.g. `$("#form").steps().validate()`). Okay, before we start adding more code take a brief look on the following table that explains the four events we will shortly add.

| Event            | Description                                                                                                                                             |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onStepChanging` | Fires before the step changes and can be used to prevent step changing by returning `false`. Very useful for form validation or checking preconditions. |
| `onStepChanged`  | Fires after the step has change.                                                                                                                        |
| `onFinishing`    | Fires before finishing and can be used to prevent completion by returning `false`. Very useful for form validation or checking preconditions.           |
| `onFinished`     | Fires after completion.                                                                                                                                 |

These useful events will help us realizing pretty neat functionality. So the events ending on -ing will be invoked right after a user interaction but before any internal logic gets executed. Those events will be very helpful to prevent step changing and submission. The events ending with -ed will happen after everything is executed and let us execute custom logic (e.g. skipping a step and submitting a form via AJAX).

Internally, it's implemented like this:

```javascript
if (wizard.triggerHandler("stepChanging", [state.currentIndex, index])) {
  // Internal logic

  wizard.triggerHandler("stepChanged", [index, oldIndex]);
}
```

With that in mind you know how it works. The first event function we are going to add to the settings is `onStepChanging`. This Implementation allows us to react before things are going to change.

```javascript
onStepChanging: function (event, currentIndex, newIndex)
{
    // Always allow going backward even if the current step contains invalid fields!
    if (currentIndex > newIndex)
    {
        return true;
    }

    // Forbid suppressing "Warning" step if the user is to young
    if (newIndex === 3 && Number($("#age").val()) < 18)
    {
        return false;
    }

    var form = $(this);

    // Clean up if user went backward before
    if (currentIndex < newIndex)
    {
        // To remove error styles
        $(".body:eq(" + newIndex + ") label.error", form).remove();
        $(".body:eq(" + newIndex + ") .error", form).removeClass("error");
    }

    // Disable validation on fields that are disabled or hidden.
    form.validate().settings.ignore = ":disabled,:hidden";

    // Start validation; Prevent going forward if false
    return form.valid();
}
```

The second event function contains some logic to skip the warning step we added before.

```javascript
onStepChanged: function (event, currentIndex, priorIndex)
{
    // Suppress (skip) "Warning" step if the user is old enough and wants to the previous step.
    if (currentIndex === 2 && priorIndex === 3)
    {
        $(this).steps("previous");
        return;
    }

    // Suppress (skip) "Warning" step if the user is old enough.
    if (currentIndex === 2 && Number($("#age").val()) >= 18)
    {
        $(this).steps("next");
    }
}
```

The next two event functions allow us to handle submission and submission prevention.

```javascript
onFinishing: function (event, currentIndex)
{
    var form = $(this);

    // Disable validation on fields that are disabled.
    // At this point it's recommended to do an overall check (mean ignoring only disabled fields)
    form.validate().settings.ignore = ":disabled";

    // Start validation; Prevent form submission if false
    return form.valid();
}
```

The latter event function is required for form submission.

```javascript
onFinished: function (event, currentIndex)
{
    var form = $(this);

    // Submit form input
    form.submit();
}
```

The final JavaScript code looks like this after we stick everything together.

```javascript
$("#form")
  .steps({
    bodyTag: "fieldset",
    onStepChanging: function (event, currentIndex, newIndex) {
      // Always allow going backward even if the current step contains invalid fields!
      if (currentIndex > newIndex) {
        return true;
      }

      // Forbid suppressing "Warning" step if the user is to young
      if (newIndex === 3 && Number($("#age").val()) < 18) {
        return false;
      }

      var form = $(this);

      // Clean up if user went backward before
      if (currentIndex < newIndex) {
        // To remove error styles
        $(".body:eq(" + newIndex + ") label.error", form).remove();
        $(".body:eq(" + newIndex + ") .error", form).removeClass("error");
      }

      // Disable validation on fields that are disabled or hidden.
      form.validate().settings.ignore = ":disabled,:hidden";

      // Start validation; Prevent going forward if false
      return form.valid();
    },
    onStepChanged: function (event, currentIndex, priorIndex) {
      // Suppress (skip) "Warning" step if the user is old enough and wants to the previous step.
      if (currentIndex === 2 && priorIndex === 3) {
        $(this).steps("previous");
        return;
      }

      // Suppress (skip) "Warning" step if the user is old enough.
      if (currentIndex === 2 && Number($("#age").val()) >= 18) {
        $(this).steps("next");
      }
    },
    onFinishing: function (event, currentIndex) {
      var form = $(this);

      // Disable validation on fields that are disabled.
      // At this point it's recommended to do an overall check (mean ignoring only disabled fields)
      form.validate().settings.ignore = ":disabled";

      // Start validation; Prevent form submission if false
      return form.valid();
    },
    onFinished: function (event, currentIndex) {
      var form = $(this);

      // Submit form input
      form.submit();
    },
  })
  .validate({
    errorPlacement: function (error, element) {
      element.before(error);
    },
    rules: {
      confirm: {
        equalTo: "#password",
      },
    },
  });
```

Any questions or comments are very welcome!
]]></content>
        <author>
            <name>Rafael Staib</name>
            <uri>https://github.com/rstaib</uri>
        </author>
    </entry>
</feed>