Skip to content

Commit

Permalink
Various documentation changes (#4294)
Browse files Browse the repository at this point in the history
  • Loading branch information
tobias-tengler authored Oct 28, 2021
1 parent 74644b3 commit 76e90b4
Show file tree
Hide file tree
Showing 9 changed files with 420 additions and 101 deletions.
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

0 comments on commit 76e90b4

Please sign in to comment.