Location>code7788 >text

NET Demo using Graphql

Popularity:993 ℃/2024-10-17 12:56:33
What is Graphql? Let's start with a snippet of the answer given by AI:
GraphQL is a query language designed for APIs that provides a more efficient, powerful and flexible way to interact with data compared to REST.GraphQL was developed by Facebook in 2012 and open sourced in 2015. Its main advantage is its ability to allow clients to specify exactly what data they need, thus avoiding the problem of over-fetching or under-data.
Main characteristics
  1. Get exactly the data you need:
  1. Single endpoint:
  1. Type system:
  1. Queries and modifications:
  1. Real-time data (Subscription):
Strengths and limitations
Advantage:
  • Reduced data transfer: only the data requested by the client is returned.
  • Reduce the number of requests: multiple data requirements can be resolved in a single query.
  • Flexibility: the client is free to construct queries without the need for frequent server updates to the API.
Limitations:
  • Complex Query Performance Issues: Unrestricted deep queries or large-scale data nesting may have an impact on server performance.
  • Caching Policy: GraphQL requires a more sophisticated caching policy to optimize performance than REST's URL-level caching.
  • Learning curve: for developers to learn the new query syntax and its underlying implementation.
 
The rest of the content will not be too much to introduce, you can be interested in their own search for the theory or description. Next, I will directly provide a real-world introductory demonstration.
 
The main body of the formal presentation begins below:
First create a webapi project as a server and a console project as a client for test use. and the corresponding reference packages, as shown below:
0
 
Create a new Quries folder to store classes and methods used for queries. As well as adding a new class for testing and a method Hello() with a return value of type string.
 
0
Inside the startup item or Program, add the Graphql service and add the type registration for Query:
 
0
 
And finally remember to map the endpoints:
0
Then run the program, for example if I run up port 5264 by default, open the url (change the url address as you see fit):http://localhost:5264/graphql/
Then enter the query statement: query:{hello} to find out the corresponding return content.
0
Inside the client, create a client request for graphql and enter a query statement with the method of the query being hello and the output as shown below. The result is the same as above, except that I only output the data inside the data, and the data inside the data is the result we need.
0
 
Moving on to an extended demo, create a nested entity class that can be used to model multiple situations:
0
 
Create a service for test use to simulate specific query business use.
0
 
After registering the service and interface, run the program and run a test inside graphql. The current test is outputting all fields.
0
 
Now, for example, if I remove the subcollection don't, then the query won't come out with anything from the subcollection:
0
 
Or just the other fields specified, deleting the description, subcollection of the city field:
0
 
Similarly, dropping the query statement into the client program and querying it will find out the contents of the specified field:
0
 
The above demonstrates the effect of the query, you can also do other operations such as add, delete and change.
Add a new business operation to the test service class to simulate that a business operation has been performed after receiving a parameter and ultimately returns a data representing success. Example:
0
 
Create a new Mutations folder, used to store add, delete and modify the operation of the class and so on. For example, the tests here use TestMutation. Then create a method that simulates the operation of the incoming parameters, which returns the test method inside the service class above.
0
 
Need to add registration for operations related to modifications:
0
 
Then start it up and do a test. Use mutation statement for operation, operation of the specified method, method inside the specified parameters and field data. You can see that the server side into the previous business method, and the return of true was successfully received by the client.
0
 
In the console client, perform a mutation operation as well, and it can also be called successfully:
0
 
The above are examples of query and modify operations. graphql can also do data push and subscription for websocket effect.
Create a new subscriptions folder to hold all the message push and subscription related definition classes. For example, TestSub, which defines a push method OnTestPublish.
0
 
Inside the previous test service, there is a new injection of the ITopicEventSender event interface, as well as a new method to trigger the push function. And the push topic, using the OnTestPublish defined just now.
0
 
It then needs to provide registration to the push service, as well as persistence options.
0
Using the default persistence, that persistence choice is not recommended for production. I'll go to AI for the exact reason:
  1. Scalability issue: AddInMemorySubscriptions Storing subscription information is done in memory. This means that subscription data only exists in a single process. If your application needs to scale across multiple server instances, each instance will have separate subscription state in memory, resulting in inconsistent state. As a result, this approach does not scale well in large applications or high-load environments.
  2. Lack of Persistence: Another major issue with using in-memory storage is data persistence. Upon server restart or failure, all subscription data in memory will be lost. This is unacceptable for production environments where service stability and data persistence need to be ensured.
  3. Resource Usage Efficiency: As the number of subscriptions increases, memory usage rises. In environments with limited memory resources, this can affect the overall performance and responsiveness of an application.
  4. Failure recovery: In-memory subscription management lacks an effective failure recovery mechanism. If the system crashes or requires maintenance, restoring the subscription state will be very difficult and may require re-establishing the subscription from the client.
To solve these problems, it is often recommended in production environments to use a persistent and scalable subscription storage solution, such as the Redis-based AddRedisSubscriptions method. If you're interested, you can expand on this yourself.
 
Now there is a lack of a trigger condition, because we created a webapi project, comes with a controller, then I will do a transformation of the controller, through the swagger to call for triggering data push, directly in the request, call the push method:
0
 
Finally, since push uses websocket, you need to add registration for websocket as well:
0
 
Then start the program and subscribe to the onTestPublish topic message using subscription. After it runs, it will keep listening unless we cancel it.
0
 
Open swagger, call it directly and test it, you can see that the panel receives the data pushed by the test.
0
 
To implement subscription on the client side, some changes need to be made. The subscribed event is of string type, so you need to create a property of string type to receive the data:
0
 
Then when the client is created, it needs to use a websocket endpoint. Then the subscription statement is created
0
 
Next is a demonstration of the specific implementation of subscription:
0
 
Allow, and call the test twice via swagger, both can be listened to.
0
 
At the same time, the previously opened graphql demo panel, can also be seen to be able to receive follow-up messages, indicating support for multi-client reception, in line with the websocket push effect.
0
 
Core code about the implementation. Server-side registration related:
 // Adding GraphQL Services
 
     .AddGraphQLServer()
     .AddQueryType<TestQuery>()
     .AddMutationType<TestMutation>()
     .AddSubscriptionType<TestSub>()
     .AddInMemorySubscriptions(); // Default message persistence (replacement recommended for production situations)

 var app = ();

 ();

 // Mapping GraphQL Endpoints
 ();

 

 
Client-side implementation:
 var option = new GraphQLHttpClientOptions
 {
     EndPoint = new Uri("http://localhost:5264/graphql"),
     // Setting up WebSocket endpoints to support subscriptions
     WebSocketEndPoint = new Uri("ws://localhost:5264/graphql")
 };

 using var client = new GraphQLHttpClient(/*"http://localhost:5264/graphql"*/ option , new NewtonsoftJsonSerializer());
 //            var request = new GraphQLRequest
 //            {
 //                Query = @"mutation{
 //  otherOperation(info:{address:""Longgang District Baolong Street"",city:""Dada Da Shenzhen"",phone:""10100011""})
//}"
 //            };

 //            var response = await <object>(request);
 //            ();

 // Defining a subscription request
 var subscriptionRequest = new GraphQLRequest
 {
     Query = @"
     subscription {
         onTestPublish
     }"
 };

 // Creating a Subscription Stream
 var subscriptionStream = <OnTestPublishResponse>(subscriptionRequest);

 // Subscribe to the message stream
 var subscription = (
     response =>
     {
         if ( != null)
         {
             ("Error occurred: " + );
         }
         else
         {
             ($"Received message: {}");
         }
     },
     error => ($"Subscription error: {}"),
     () => ("Subscription completed."));

 // Simulate other logic (e.g., unsubscribe at a certain point, where cancellation and release are triggered by typing any key).
 ("Press any key to exit...");
 ();

 // Unsubscribe and close the WebSocket connection
 ();
 ();

 

If you need my local demo code project, you can find it in my public number [Dotnet Dancer]Response.Code Demo You can get the address of the open source project.

 

If the above is helpful to you, welcome the big boys to like, follow the public or retweet. Thank you all!