Skip to main content

Posts

Showing posts with the label GraphQL

HotChocolate 13 - Schema comparison

One of the main design principles we follow when building a GraphQL API is to maximize backwards compatibility. To avoid unexpected breaking changes, we have integrated GraphQL Inspector into our build pipeline. After upgrading to HotChocolate 13, the schema comparison started to fail: It complains that the defer and stream directive are no longer there. And indeed if we open up the schema before the upgrade: And compare it to the schema after the upgrade: We can see that the 2 directives are no longer there. We can easily fix this by re-enabling both directives in our GraphQL configuration code: Remark: If you are paying attention, you can see that there was another breaking change regarding the cost directive. More about that in the following post . More information GraphQL Inspector (bartwullems.blogspot.com) Migrate Hot Chocolate from 12 to 13 - Hot Chocolate - ChilliCream GraphQL Platform

HotChocolate 13 - Unable to infer or resolve a schema type from the type reference `@CostDirective`

Yesterday I talked about measuring and monitoring the operational complexity of your GraphQL operations. I talked specifically about the custom HotChocolate cost directive as a way to assign a complexity to a field. However after upgrading an ASP.NET Core GraphQL api to HotChocolate 13, the GraphQL schema could no longer be loaded. Instead I got the following error message back: HotChocolate.SchemaException: For more details look at the `Errors` property. Unable to infer or resolve a schema type from the type reference `@CostDirective`. (IRD3.API.GraphQL.LandbouwerType) at HotChocolate.Configuration.TypeInitializer.DiscoverTypes() at HotChocolate.Configuration.TypeInitializer.Initialize() at HotChocolate.SchemaBuilder.Setup.InitializeTypes(SchemaBuilder builder, IDescriptorContext context, IReadOnlyList`1 types) at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilder builder, LazySchema lazySchema, IDescriptorContext context) at HotChocolate.SchemaBuild...

GraphQL–Always monitor the operational complexity

Today GraphQL is a mature alternative for building API's. Many developers have discovering its flexibility, expressiveness, and efficiency. However, with this flexibility comes the challenge of managing and tracking operational complexity, especially as APIs scale. Without proper monitoring and optimization, GraphQL queries can become performance bottlenecks, leading to slow response times, server overload, and a suboptimal user experience. Therefore it is important to monitor the Operational Complexity of the queries send to your API endpoint. What is Operational Complexity in GraphQL? Operational complexity in GraphQL refers to the computational and resource costs associated with executing a query. Unlike REST, where each endpoint is typically associated with a fixed cost, GraphQL's flexible nature means that the cost can vary dramatically depending on the structure of the query. For instance, a simple query fetching a list of users might be relatively cheap. However, i...

GraphQL–Application Insights integration for HotChocolate 13

If you are a regular reader of my blog, you've certainly seen my earlier post on how to integrate Application Insights telemetry in your HotChocolate based GraphQL backend. IMPORTANT: Although the code below will still work, I would recommend to switch to the integrated OpenTelemetry functionality and send the information to Application Insights in this way. Today I had to upgrade an application to HotChocolate 13 and (again) I noticed that the application no longer compiled. So for people who are using the ApplicationInsightsDiagnosticsListener I shared, here is an updated version that works for HotChocolate 13: As I wanted to track the full operation I have overwritten the ExecuteRequest method, however if you only want to log any exception, I would recommend to override the RequestError and ResolverError methods: More information HotChocolate OpenTelemetry (bartwullems.blogspot.com) GraphQL HotChocolate 11 - Updated Application Insights monitoring (bartwullem...

Azure Static Web App–Data API Builder

As a follow-up on the presentation I did at CloudBrew about Azure Static Web Apps I want to write a series of blog posts. Part I - Using the VS Code Extension Part II - Using the Astro Static Site Generator Part III  – Deploying to multiple environments Part IV – Password protect your environments Part V – Traffic splitting Part VI – Authentication using pre-configured providers Part VII – Application configuration using staticwebapp.config.json Part VIII – API Configuration Part IX – Injecting snippets Part X – Custom authentication Part XI – Authorization Part XII -  Assign roles through an Azure function Part XIII -  API integration Part XIV – Bring your own API Part XV – Pass authentication info to your linked API Part XVI – Distributed Functions Part XVII(this post) – Data API Builder So far I have shown you 2 different possibilities to integrate an API inside your Azure Static Web App: You...

GraphQL OWASP Cheat Sheet

I’m a big fan of GraphQL but as with every technology it comes with it's own set of (security) challenges. To properly secure your GraphQL API, I can recommend to check the GraphQL Cheat Sheet . It handles common attack vectors and best practices to avoid them.   If you have never heard about the OWASP Cheat Sheet Series , also have a look at all the other sheets in the series. A must read for every developer!

GraphQL Conf 2023

The 2023 edition of GraphQLConf is over. In case you had to miss this great experience, you can still watch all session recordings and get the speaker slides by going to the event schedule .   It is great to see how the GraphQL ecosystem keeps growing and what new innovations and tools are appearing. Start by watching Uri Goldshtein's keynote on the state of GraphQL focused on highlighting the biggest open source innovations from the last year. Then have a look at the GraphQL Fusion presentation given by Michael Staib , introducing a new open spec for remote execution and federation of services that challenges the existing patterns of specification-less Federation protocols with a fresh approach. Learn how GrapQL and CQRS can be combined , how AI is also finding its way in GraphQL land and much more….

Strawberry Shake–Method not found error

When trying to build an application using the Strawberry Shake GraphQL client on our build server, it failed with the following error message: IAM.Core -> D:\b\3\_work\210\s\IAM.Core\bin\Release\netstandard2.0\IAM.Core.dll ##[error]CSC(0,0): Error SS0006: Method not found: 'Void StrawberryShake.CodeGeneration.CSharp.CSharpGeneratorSettings.set_RequestStrategy(StrawberryShake.Tools.Configuration.RequestStrategy)'. CSC : error SS0006: Method not found: 'Void StrawberryShake.CodeGeneration.CSharp.CSharpGeneratorSettings.set_RequestStrategy(StrawberryShake.Tools.Configuration.RequestStrategy)'. [D:\b\3\_work\210\s\Mestbank.Core\Mestbank.Core.csproj] ##[error]Mestbank.Core\Repositories\IRD3Repository.cs(14,26): Error CS0246: The type or namespace name 'IIrd3Client' could not be found (are you missing a using directive or an assembly reference?) D:\b\3\_work\210\s\Mestbank.Core\Repositories\IRD3Repository.cs(14,26): error CS0246: The type or namesp...

GraphQL–HotChocolate - The object type `Object` has to at least define one field in order to be valid.

A colleague contacted me last week asking help with a specific HotChocolate issue they got. He shared the code and the error message with me. Here is the error he got: 1. The object type `Object` has to at least define one field in order to be valid. (HotChocolate.Types.ObjectType<System.Object>)       HotChocolate.SchemaException: For more details look at the `Errors` property.       1. The object type `Object` has to at least define one field in order to be valid. (HotChocolate.Types.ObjectType<System.Object>)          at HotChocolate.Configuration.TypeInitializer.Initialize()          at HotChocolate.SchemaBuilder.Setup.InitializeTypes(SchemaBuilder builder, IDescriptorContext context, IReadOnlyList`1 types)          at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilde...

GraphQL–HotChocolate–Exclude specific fields when using the code first approach

HotChocolate tries to help you as much as possible to automatically generate the GraphQL schema for you when using the Code First approach. It will scan through all the types to look for public properties and methods and adds them as GraphQL fields to the schema object type. But what if you want to exclude a specific field? Here are 2 possible ways to do this. Ignoring a field A first option is to ignore specific fields: This is most useful when there is a limited number of fields that need to be excluded. Binding fields explicitly A second option you have is to disable the automatic scanning for a type and bind all fields explicitly. Therefore call the BindFieldsExplicitly method and then start to add fields manually: More information: Object Types - Hot Chocolate - ChilliCream GraphQL Platform

Improve the security of your GraphQL API’s - Part 5–Introspection

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. Nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. I already talked about Assigning a complexity budget . Limiting the query depth . Adding authorization Persisted queries In this last post I focus on a small but important attack vector; introspection. What is introspection? GraphQL has a built-in introspection system that allows you to ask a GraphQL schema for information. This is one of the things that makes GraphQL so powerful and enables rich tooling integration. If you against the following query against your GraphQL AP...

Improve the security of your GraphQL API’s - Part 4–Persisted queries

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. Nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. I already talked about Assigning a complexity budget . Limiting the query depth . Adding authorization In this post I want to focus on a specific feature supported by most GraphQL api’s: persisted queries.  When using persisted queries, a client only sends a query identifier (and optionally variables) to the server instead of the full query text. This approach provides several benefits, such as reducing bandwidth usage, makes caching a lot easier and allows extra optimizations o...

Improve the security of your GraphQL API’s - Part 3–Authorization

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. Nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. I already talked about Assigning a complexity budget . Limiting the query depth . Today I will focus on authorization. Remark: I expect that you already have a kind of authentication built into your GraphQL API. So I'll ignore that part. Doing an authorization check for a REST API is easy. As every REST call maps to a specific invocation requesting specific data, you have all the information you need to check if a user is allowed to fetch a specific set of data. In ASP.NET Core...

Improve the security of your GraphQL API’s - Part 2–Depth checks

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. Nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. In a first post I introduced the concept of a complexity budget . Today we have a look at query depth. What is query depth? The depth is the number of nesting levels of the query. The following query has a depth of 3: By setting a query depth, you can protect yourself against cycles in your graph leading to infinite recursive queries: How to limit the query depth? To limit the query depth, we need to update our GraphQL server configuration and set a MaxExecutionDepthRule:

Improve the security of your GraphQL API’s - Part 1 - Complexity budget

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. For example, you have build some client applications consuming your GraphQL API. These applications are using a range of queries that you carefully created to implement the client functionality. These queries are well tested, optimized and don't stretch your datasource too much. But nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. In this blog series I want to share some ways on how you can improve the security of your GraphQL API's. In first post I'll focus on the concept of a complexity budget. A single GraphQL query can poten...

GraphQL Code Generator–Avoid generating types that are not needed

If you are using GraphQL in your frontend(or even backend) applications I hope you are not creating all the types yourself. Thanks to the built-in schema introspection functionality, tooling can do all the heavy-lifting for you. For frontend apps I typically use the GraphQL Code Generator created and maintained by The Guild . I don’t want to use this post to explain how to use the GraphQL Code Generator; there are multiple guides available. For example here is the one for Angular. Instead I want to focus on how you can manipulate the code generation. By default, the GraphQL Code Generator will generate types for your complete schema AND specific operation types based on the provided GraphQL queries/mutations/subscriptions. How does this looks like? Here is the codegen.ts file we are using: And here is on the GraphQL query files we are using: If we execute the codegeneration, we get types for the full schema: AND types for the specific operation: Generate only ope...

HotChocolate–GraphQL Caching

Caching in GraphQL can be quite challenging. Due to the flexible and dynamic nature of GraphQL queries, caching can become very complex, especially when dealing with mutations or queries with different variables or arguments. Cache invalidation becomes crucial to ensure that clients receive up-to-date data when it changes on the server. This is an area where REST api’s shine. Due to the static nature of the endpoints, caching can be based on the HTTP specification. In HotChocolate caching can be done at the entity level. Therefore you need to add the HotChocolate.Caching nuget package: dotnet add package HotChocolate.Caching We also have to update the GraphQL configuration: Now we can set a [CacheControl] attribute on our queries: Or if you are using a code first approach: If we now run our query, a cache control header is emitted in the response that can be used by the browser or a CDN to cache the data accordingly:  

How Microsoft is using GraphQL in their new Teams architecture

Microsoft has made a significant investment in the re-architecture of its Microsoft teams desktop client, which is available in preview at the moment of writing this post. Although there are a lot of great improvements in the new Teams I want to focus on the new technical architecture which they shared in this post: Microsoft Teams: Advantages of the new architecture . What I found really interesting is how they brought GraphQL into the mix: If you look at the schema above, notice the Client Data Layer on the right. This layer is hosted inside a Web Worker and used to overcome the single-threaded nature of JavaScript. It enables functionality like data fetch, data storage, push notifications, and offline functionality(through Index DB) and all this running on parallel threads. The Teams window(using WebView2 ) is abstracted from the client data layer through GraphQL. I think this is a use case where I wouldn’t have thought about this technology myself but it is a great examp...

HotChocolate GraphQL–Include Exception details

By default the HotChocolate GraphQL server does not expose any exception details when an errors occurs. The only information you get back is the following: This is of course a good idea from a security endpoint but not very helpful when you want to investigate a problem. In order to automatically add exception details to your GraphQL error you can switch the execution option to include exception details: Remark: When a debugger is attached this behavior is changed automatically and exception details are included. More information: Error Filter - Hot Chocolate - ChilliCream GraphQL Platform

Upgrading to HotChocolate 13 - There was no argument with the name `…` found on the field `…`.

I spent some time trying to upgrade the HotChocolate workshop from version 11 to 13. If you are interested in the end result, check out my blog post here . Most things still worked and a few things were marked as obsolete and easy to replace. However there was also some stuff that was less obvious. One error I got was when I tried to fetch a related object through a resolver. Here is the GraphQL query I tried to execute: And here is the error I got: Let’s have a look at the resolver we were using: And here is how it is used: A look at the migration docs explained the problem.Starting from HotChocolate 12 the ParentAttribute is required when a resolver argument is referring to the parent object. So to fix the problem we have to update our resolver and introduce the ParentAttribute :