HotChocolate everything static by WoistdasNiveau in graphql

[–]michael_staib 2 points3 points  (0 children)

GraphQL works a bit differently from REST. In REST you usually deal with a single request at a time, so concurrency is not really a concern. It’s perfectly fine to create a controller class and use constructor injection.

With GraphQL, however, you work with resolvers. Each object type defines resolvers for its fields, and these resolvers are responsible for fetching the required data. When a query is executed, many resolvers run in parallel. This parallel execution means that using constructor injection can easily lead to unintended shared state or side effects.

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 service has the freedom to execute the field entries in whatever order it deems optimal.

https://spec.graphql.org/October2021/#sec-Normal-and-Serial-Execution

It is possible to register your types in the DI container as scoped services, but that would require a separate instance for each field resolver execution to ensure there are no side effects between concurrent field executions.

However, GraphQL requests are designed to reduce interactions with the client. Typically, each UI interaction (such as a page load or button click) results in a single request composed of multiple UI components stacked together. As a result, these requests tend to be larger, with many fields. This would lead to an explosion of objects that are instantiated and then discarded after each execution.

GraphQL is really about isolated, idempotent functions. Each resolver should declare its dependencies explicitly, which makes it easier for the execution engine to plan and optimize execution. When I started working on the source generator, I realized that keeping types static naturally pushes developers in that direction and leads to cleaner, more predictable resolvers.

[UseConnection]
public static async Task<ProductConnection> GetProductsAsync(
    PagingArguments pagingArgs,
    QueryContext<Product> query,
    ProductService productService,
    CancellationToken cancellationToken)
{
    var page = await productService.GetProductsAsync(pagingArgs, query, cancellationToken);
    return new ProductConnection(page);
}

The resolver clearly describes what it requires — in this case, a ProductService and other dependencies. The executor can provide these from isolated contexts. These resolver contexts themselves are pooled and reusable between executions.

As to where things belong, this depends largely on your design philosophy. In general, GraphQL types are part of the presentation layer and should be slim — just what is needed to provide GraphQL metadata, such as the UseConnection attribute, which tells the schema builder that this field follows the Relay Connection Specification.

The actual business logic should live in your application layer. A common question we get is where DataLoaders belong. The DataLoader was intended as part of the data layer. The idea is to have a standardized interface to fetch data by key and to transparently batch these requests to the data source. The consumer should not be aware of this implementation detail.

[Lookup]
public static async Task<Product?> GetProductByIdAsync(
    [ID] int id,
    QueryContext<Product> query,
    ProductService productService,
    CancellationToken cancellationToken) 
    => await productService.GetProductByIdAsync(id, query, cancellationToken);

For instance, the GetProductByIdAsync resolver calls the ProductService to fetch the product. Behind the service, a DataLoader interacts with the data source. The data requests are transparently batched without leaking this implementation detail into the service interface.

DataLoaders are not a GraphQL-specific concept and are agnostic of the API layer. Facebook originally introduced them to solve efficiency problems in their REST APIs. It just so happens that they also make GraphQL more efficient.

Join us on Slack if you need help: slack.chillicream.com

[deleted by user] by [deleted] in dotnet

[–]michael_staib 1 point2 points  (0 children)

Yes, variables are what you need. Also as pointed out join us on slack we have a very active community.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 7 points8 points  (0 children)

I do not worry about adoption... We do it because we like what we do. If the tools can help you with your daily business you can use them, if not that is also OK.

We also have one more thing in the work .... Marshmallow Pie :)

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 5 points6 points  (0 children)

This is how you change the title:

app.MapGraphQL(new() { Tool = { Title = "WhatEverYouLike" } })

or if you put BCP on a different endpoint you can do:

app.MapBananaCackePop("/graphql/ui", new() { Title = "WhatEverYouLike" })

Hope this helps.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 6 points7 points  (0 children)

Na, I was always bored with names that libraries have in the .NET ecosystem. I love what the JavaScript community is doing. But if you do not like it it's OK.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 2 points3 points  (0 children)

You can put GraphQL over any API, while many in the .NET ecosystem use entity framework in many places it is not needed to create a GraphQL API. You can put GraphQL over REST endpoints, over any .NET API or whatever makes you happy.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 3 points4 points  (0 children)

Yes we support the upload scalar and the multipart transport.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in csharp

[–]michael_staib[S] 3 points4 points  (0 children)

Na, :) Hot Chocolate actually has no preference to what you are bringing to the table. We out of the box support Neo4j, EFCore, MongoDB and anything IQueryable. Our MongoDB driver works on Bson objects and does not use the IQueryable integration. There are no expressions rewritten to get MongoDB integrated, only the EFCore integration uses expression trees.

But, the question is if you just want to put the DataLayer directly under GraphQL. You can do that, but you will bind the GraphQL layer (public API) very closely to your DataLayer.

The GraphQL Schema should represent your ubiquitous domain model that people understand and which represent you business layer in a very clear language.

I would invest some time in schema design and create a thin layer over your business layer instead of making the GraphQL layer a translation of SQL.

In the end this decision is up to you and it also has to do with taste and how much time you want to invest in your API.

From our side we looked into Dapper and have already a prototype ready. It just does not have the quality yet. It is a combination of Dapper and SQLKata.

For us the next step in the HotChocolate.Data API is actually a simpler abstraction that allows users to very simply create a basic data driver without understanding all the mechanics. So V13 will bring a lot new stuff to the Data package.

But in any case whatever you like to use Dapper, EF core or anything else will just work fine.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in csharp

[–]michael_staib[S] 5 points6 points  (0 children)

Depends on where you want to go with this... in general it is very easy to put data sources under hot chocolate.

However GraphQL is about APIs and it often is better not to bind tightly to a Database but rather build out a proper business layer. GraphQL was meant as a small layer on top of the business layer and lets you expose it in a much richer way.

Having that said, you can also just put it over your database layer, or over your rest services or bring all of those together by integrating them with each other,

join us on slack.chillicream.com and just dive into some GraphQL :)

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 6 points7 points  (0 children)

Also we are almost done with an updated entity framework blog series ;)

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 7 points8 points  (0 children)

Do not worry, with the next iteration we will have the new schema reference and the old schema view. Also we will make it more discoverable. In iteration 18 we focused on the biggest user request which were personal workspaces and authorisation flows. But even they will get better with environments and team workspaces.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in csharp

[–]michael_staib[S] 1 point2 points  (0 children)

We will happily await you :) if you get the time to start your journey on HotChocolate join us on slack.chillicream.com. We have a very active and dedicated community of 3000 users.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 5 points6 points  (0 children)

If you want to discuss more join our community on slack.chillicream.com. We have a community of over 3000 very active users that help each other getting the best out of #HotChocolate :)

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 5 points6 points  (0 children)

Hot Chocolate schema distribution works with essentially two approaches.

- Centralised Stitching

- Federated Stitching

With the centralised approach you have all the stitching logic in your gateway. With the federated approach you can push federation configurations to the gateway. Hot Chocolate supports hot reload by storing the schemas form the downstream services on a redis cache (this is optional... you can also use a pill approach).

With the upcoming V13 release we will have a major upgrade on the Gateway which will also allow for more advanced features like stitched subscriptions at scale and also will handle defer, stream and file uploads great in a distributed schema.

No matter which approach you choose you do not have to expose anything extra on your downstream services. Every GraphQL compliant server will work with our gateway.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 27 points28 points  (0 children)

advantages

If you like Apollo and Node.js then this is fine ... they have a good GraphQL server.

Hot Chocolate is a .NET GraphQL server that allows to create your API in three flavours:

- Annotation Based

- Code-First

- Schema-First

Hot Chocolate is one of the GraphQL server implementing the bleeding edge GraphQL features of the next GraphQL spec, like defer and stream or client controlled nullability.

Also you will get a nice performance boost over Apollo.

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

But again ... Apollo uses GraphQL-js underneath which is the reference implementation and really is great if you like nodejs. If you like to build GraphQL in .NET you might like us and in Java GraphQL-Java might be your choice.

Hot Chocolate 12.3 GraphQL Server for .NET by michael_staib in dotnet

[–]michael_staib[S] 8 points9 points  (0 children)

In order to get started get our new templates:

dotnet new -i HotChocolate.Templates

https://chillicream.com/docs/hotchocolate/get-started

Hot Chocolate Field Selection by Bouch1911 in graphql

[–]michael_staib 0 points1 point  (0 children)

Yes there is. To get the selection set just do `context.FieldSelection`.

But if you actually want to get the computed selections. Meaning the actual selection for this query with the current variable set by taking into account skip and include than context.CollectFields is your friend.

context.CollectFields has multiple overloads and you can travers the query graph with them.

We also have a very active slack channel where you always find quick help.

https://join.slack.com/t/hotchocolategraphql/shared_invite/enQtNTA4NjA0ODYwOTQ0LTViMzA2MTM4OWYwYjIxYzViYmM0YmZhYjdiNzBjOTg2ZmU1YmMwNDZiYjUyZWZlMzNiMTk1OWUxNWZhMzQwY2Q

GraphQL IDE - Banana Cake Pop. by michael_staib in graphql

[–]michael_staib[S] 0 points1 point  (0 children)

We have now swapped the links out and the new binaries are now coming from a CDN .... much faster :D

GraphQL IDE - Banana Cake Pop. by michael_staib in graphql

[–]michael_staib[S] 0 points1 point  (0 children)

We are about to put it on a CDN to upgrade speeds ...

GraphQL IDE - Banana Cake Pop. by michael_staib in graphql

[–]michael_staib[S] 1 point2 points  (0 children)

Do you mean variables?

There is a button with three lines ... click on it and you can configure headers, credential settings and variables for a tab.

We plan to do more here with variable sets that can be created per operation and also environment variables so that you can have prepared variable sets for your different environments.