hotchoc schema stitching example (without hot reload)

In this setup, we will be setting up centralize hotchoc grapql federation that resolves schema residing in another services. The gateway does not import or contains subgraph schema. It does not require developer to copy schema from subgraph over as part of this integration. 

It is abit confusing as there are 2 ways to implement federation. 

1. Schema stitching which is what this blog talks about. 

Will there be manual work to stich schema into a global schema? 

What if schema conflict occurs and what would happened? 

2. Federated schema - where we are using tech stack such as redis to pull schema changes from different subgraphs into a global schema. 

The subgraph needs to know about the global supergraph. 

What if schema conflict occurs and what would happened? 

In a centralize approach, gateway reference subgraph schemas. Stitching generally happens when we would like to extend our subgraphs for example, introducing another query name. We will see more of this. Inline with the federation intention,  if a request for product info, the product subgraph would return product info while leaving reviews to be resolved by another subgraph service. 

We will be creating 5 projects 

- the gateway - this main graphql allows us to query other subgraph define below.

- product subgraph - a simple subgraph that shows product info

- review subgraph - a slightly more complicated subgraph that provides review information

- account subgraph 

- inventory subgraph 

Github repository 

https://github.com/mitzenjeremywoo/hotchoc-federation-centralize

To run, clone this repo above. Then run all the projects above using dotnet run. 

The entry point for us would be the gateway. Gateway does not have method that returns data to us. When we start the app and go into http://localhost:5050/graphql you will noticed that we have all the subgraph schema accessible to us. 

For example, we can have reviews that the review subgraph. Then we also have user from the user subgraph (red) and our reviews comes from review subgraph. 

Also note that gateway do not hold or contain references of these subgraph schema. As your specify the query, you would be able to retrieve data from different subgraphs.



The gateway schema contains the following code only. Basically load schema from subgraphs.




using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;

var builder = WebApplication.CreateBuilder(args);

const string Accounts = "accounts";
const string Inventory = "inventory";
const string Products = "products";
const string Reviews = "reviews";

builder.Services.AddHttpClient(Accounts, c => c.BaseAddress = new Uri("http://localhost:5051/graphql"));
builder.Services.AddHttpClient(Inventory, c => c.BaseAddress = new Uri("http://localhost:5052/graphql"));
builder.Services.AddHttpClient(Products, c => c.BaseAddress = new Uri("http://localhost:5053/graphql"));
builder.Services.AddHttpClient(Reviews, c => c.BaseAddress = new Uri("http://localhost:5054/graphql"));

builder.Services
    .AddGraphQLServer()
                .AddRemoteSchema(Accounts)
                .AddRemoteSchema(Inventory)
                .AddRemoteSchema(Products)
                .AddRemoteSchema(Reviews)
                .AddTypeExtensionsFromFile("./Stitching.graphql");

var app = builder.Build();
app.MapGraphQL();
app.RunWithGraphQLCommands(args);


The structure of the code above, is pretty much the same with subgraphs. 

Does query that goes into a subgraph for example review subgraphs that returns a user type, will it resolve to account subgraph (the subgraph that contains user information) 
Yes it does. In the schemas here 




You can clearly see that Reviews return author which is of user type. Then if we specify the following in our query, it will return the actual author details.


Also note in our code base we do not store Author names. It only return author id which was looked with account subgraph and pulls out other relevant info such as names. 

From query (in red) we query the reviews info together with product info. You can see the output results in yellow. And what is the content of our graphql  query defined in the gateway - you can see that in the far right of our screen (in red). 





We specify review type extension and under it, it returns product type which should be resolve by product subgraph. 


extend type Review {
  author: User @delegate(schema: "accounts", path: "user(id: $fields:authorId)")
  product: Product @delegate(schema: "products", path: "product(upc: $fields:upc)")
}












Comments

Popular posts from this blog

gemini cli getting file not defined error

NodeJS: Error: spawn EINVAL in window for node version 20.20 and 18.20

vllm : Failed to infer device type