Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Various documentation changes #4294

Merged
merged 7 commits into from
Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions website/src/docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@
"title": "Introspection"
},
{
"path": "uploading-files",
"title": "Uploading files"
"path": "files",
"title": "Files"
},
{
"path": "instrumentation",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@ title: Migrate from Hot Chocolate GraphQL server 11 to 12

This guide will walk you through the manual migration steps to get your Hot Chocolate GraphQL server to version 12.

# Resolvers

We have reworked the resolver compiler and are now demanding that the `ParentAttribute` is used when an argument is referring to the parent object.
This is done since in some cases people want to get the parent object which is the same runtime type as an argument value.

**v11**

```csharp
public string MyResolver(Person parent, string additionalInput)
{
// Code omitted for brevity
}
```

**v12**

```csharp
public string MyResolver([Parent] Person parent, string additionalInput)
{
// Code omitted for brevity
}
```

# Scalars

We changed some defaults around scalars. These new defaults can break your existing schema but are, in general, better for newcomers and align better with the overall GraphQL ecosystem. Of course, you can naturally opt out of these new defaults to preserve your current schema's integrity.
Expand Down Expand Up @@ -52,23 +75,23 @@ services

We have changed the way we infer the name for the connection type when using cursor-based pagination. By default, the connection name is now inferred from the field name instead of the type name.

```SDL
```sdl
type Person {
friends: [Person]
}
```

In version 11, we would have created a connection named `PersonConnection`.

```SDL
```sdl
type Person {
friends(first: Int, last: Int, after: String, before: String): PersonConnection
}
```

In version 12, we now will infer the connection name as `FriendsConnection`.

```SDL
```sdl
type Person {
friends(first: Int, last: Int, after: String, before: String): FriendsConnection
}
Expand Down Expand Up @@ -132,15 +155,15 @@ Therefore we introduced two separate APIs to give you more explicit control over

## Global Object Identification

**OLD**
**v11**

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

**NEW**
**v12**

```csharp
services
Expand All @@ -152,7 +175,7 @@ services

## Query field in Mutation payloads

**OLD**
**v11**

```csharp
services
Expand All @@ -165,7 +188,7 @@ services
});
```

**NEW**
**v12**

```csharp
sevices
Expand All @@ -190,7 +213,7 @@ We have consolidated the DataLoader base classes into the GreenDonut package whi

Second, we optimized memory usage of DataLoader and it is now best practice to let the DI inject the DataLoaderOptions into the DataLoader.

**Hot Chocolate 11**
**v11**

```csharp
public class CustomBatchDataLoader : BatchDataLoader<string, string?>
Expand All @@ -205,7 +228,7 @@ public class CustomBatchDataLoader : BatchDataLoader<string, string?>
}
```

**Hot Chocolate 12**
**v12**

```csharp
public class CustomBatchDataLoader : BatchDataLoader<string, string?>
Expand All @@ -221,15 +244,3 @@ public class CustomBatchDataLoader : BatchDataLoader<string, string?>
```

Allowing the DI to inject the options will allow the DataLoader to use the new shared pooled cache objects.

# Resolvers

We have reworked the resolver compiler and are now demanding that the `ParentAttribute` is used when an argument is referring to the parent object.
This is done since in some cases people want to get the parent object which is the same runtime type as an argument value.

```csharp
public async Task<string> MyResolver([Parent] Person parent, Person input)
{
// code omitted for brevity.
}
```
46 changes: 43 additions & 3 deletions website/src/docs/hotchocolate/defining-a-schema/non-null.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,49 @@ public class BookType : ObjectType<Book>
<ExampleTabs.Schema>

```sdl
type User {
name: String!
nullableName: String
type Book {
title: String!
nullableTitle: String
}
```

</ExampleTabs.Schema>
</ExampleTabs>

The inner type of a list can be made non-null like the following.

<ExampleTabs>
<ExampleTabs.Annotation>

```csharp
public class Book
{
[GraphQLType(typeof(ListType<NonNullType<StringType>>))]
public List<string> Genres { get; set; }
}
```

</ExampleTabs.Annotation>
<ExampleTabs.Code>

```csharp
public class BookType : ObjectType<Book>
{
protected override void Configure(IObjectTypeDescriptor<Book> descriptor)
{
descriptor
.Field(f => f.Genres)
.Type<ListType<NonNullType<StringType>>>();
}
}
```

</ExampleTabs.Code>
<ExampleTabs.Schema>

```sdl
type Book {
genres: [String!]
}
```

Expand Down
34 changes: 28 additions & 6 deletions website/src/docs/hotchocolate/performance/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,48 @@
title: "Overview"
---

**Improve performance by sending smaller requests and pre-compile queries**
In this section we will look at some ways of how we can improve the performance of our Hot Chocolate GraphQL server.

The size of individual GraphQL requests can become a major pain point. This is not only true for the transport but also introduces inefficiencies for the server since large requests need to be parsed and validated. To solve this problem, Hot Chocolate has implemented persisted queries. With persisted queries, we can store queries on the server in a key-value store. When we want to execute a persisted query, we can send the key under which the query is stored instead of the query itself. This saves precious bandwidth and also improves execution time since the server will validate, parse, and compile persisted queries just once.
# Startup performance

The first GraphQL request issued against a Hot Chocolate server will most of the time take a little longer than subsequent requests. This is because Hot Chocolate has to build up the GraphQL schema and prepare for the execution of requests.

We can however delegate this task to the startup of the application instead of the first request, by call `InitializeOnStartup()` on the `IRequestExecutorBuilder`.

```csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddGraphQLServer()
.InitializeOnStartup()
}
}
```

This will create the schema and warmup the request executor as soon as the app starts. This also brings the added benefit that schema errors are surfaced at app startup and not on the first request.

# Persisted queries

The size of individual GraphQL requests can become a major pain point. This is not only true for the transport but also the server, since large requests need to be parsed and validated often. To solve this problem, Hot Chocolate implements persisted queries. With persisted queries, we can store queries on the server in a key-value store. When we want to execute a persisted query, we can send the key under which the query is stored instead of the query itself. This saves precious bandwidth and also improves execution time since the server will validate, parse, and compile persisted queries just once.

Hot Chocolate supports two flavors of persisted queries.

## Persisted queries
## Regular persisted queries

The first approach is to store queries ahead of time (ahead of deployment).
This can be done by extracting the queries from your client application at build time. This will reduce the size of the requests and the bundle size of your application since queries can be removed from the client code at build time and are replaced with query hashes. Apart from performance, persisted queries can also be used for security by configuring Hot Chocolate to only accept persisted queries on production.
This can be done by extracting the queries from our client applications at build time. This will reduce the size of the requests and the bundle size of our application since queries can be removed from the client code at build time and are replaced with query hashes.

Strawberry Shake, [Relay](https://relay.dev/docs/guides/persisted-queries/), and [Apollo](https://www.apollographql.com/docs/react/api/link/persisted-queries/) client all support this approach.

[Learn more about persisted queries](/docs/hotchocolate/performance/persisted-queries)

## Automatic persisted queries

Automatic persisted queries allow us to store queries dynamically on the server at runtime. With this approach, we can give our application the same performance benefits as with persisted queries without having to opt in to a more complex build process.
Automatic persisted queries allow us to store queries dynamically on the server at runtime. With this approach, we can give our applications the same performance benefits as with persisted queries without having to opt in to a more complex build process.

However, we do not have the option to seal our server from queries that we do not know, so this approach has **no** security benefits. We do not have any bundle size improvements for our application since the query is still needed at runtime.
However, we do not get any bundle size improvements for our applications since the queries are still needed at runtime.

Both Strawberry Shake and [Apollo](https://www.apollographql.com/docs/apollo-server/performance/apq/) client support this approach.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
title: "Persisted queries"
---

Persisted queries allow us to pre-register all required queries of our clients. This can be done by extracting the queries from our client applications at build time and putting them in the server's query storage. Extracting queries is supported by client libraries like [Relay](https://relay.dev/docs/guides/persisted-queries/) and in the case of [Strawberry Shake](/docs/strawberryshake) we do not have to do any additional work.
Persisted queries allow us to pre-register all required queries of our clients. This can be done by extracting the queries of our client applications at build time and placing them in the server's query storage.

> Note: While this is called persisted _queries_ it works for all other GraphQL operations as well.
Extracting queries is supported by client libraries like [Relay](https://relay.dev/docs/guides/persisted-queries/) and in the case of [Strawberry Shake](/docs/strawberryshake) we do not have to do any additional work.

> Note: While this feature is called persisted _queries_ it works for all other GraphQL operations as well.

# How it works

Expand Down
Loading