├── .editorconfig
├── .github
├── dependabot.yml
└── workflows
│ ├── branches.yml
│ ├── master.yml
│ └── publish.yml
├── .gitignore
├── Directory.Build.props
├── Directory.Build.targets
├── GitVersion.yml
├── GraphQL.Client.sln
├── GraphQL.Client.sln.DotSettings
├── LICENSE.txt
├── README.md
├── SubscriptionIntegrationTest.ConsoleClient
├── Program.cs
└── SubscriptionIntegrationTest.ConsoleClient.csproj
├── assets
├── logo.64x64.png
└── logo.svg
├── dotnet-tools.json
├── examples
├── .editorconfig
└── GraphQL.Client.Example
│ ├── GraphQL.Client.Example.csproj
│ ├── PersonAndFilmsResponse.cs
│ └── Program.cs
├── src
├── GraphQL.Client.Abstractions.Websocket
│ ├── GraphQL.Client.Abstractions.Websocket.csproj
│ ├── GraphQLWebSocketMessageType.cs
│ ├── GraphQLWebSocketRequest.cs
│ ├── GraphQLWebSocketResponse.cs
│ ├── GraphQLWebsocketConnectionState.cs
│ ├── IGraphQLWebSocketClient.cs
│ ├── IGraphQLWebsocketJsonSerializer.cs
│ └── WebsocketMessageWrapper.cs
├── GraphQL.Client.Abstractions
│ ├── GraphQL.Client.Abstractions.csproj
│ ├── GraphQLClientExtensions.cs
│ ├── GraphQLJsonSerializerExtensions.cs
│ ├── IGraphQLClient.cs
│ ├── IGraphQLJsonSerializer.cs
│ └── Utilities
│ │ ├── StringExtensions.cs
│ │ └── StringUtils.cs
├── GraphQL.Client.LocalExecution
│ ├── GraphQL.Client.LocalExecution.csproj
│ ├── GraphQLLocalExecutionClient.cs
│ └── ServiceCollectionExtensions.cs
├── GraphQL.Client.Serializer.Newtonsoft
│ ├── ConstantCaseEnumConverter.cs
│ ├── GraphQL.Client.Serializer.Newtonsoft.csproj
│ ├── MapConverter.cs
│ └── NewtonsoftJsonSerializer.cs
├── GraphQL.Client.Serializer.SystemTextJson
│ ├── ConstantCaseJsonNamingPolicy.cs
│ ├── ConverterHelperExtensions.cs
│ ├── ErrorPathConverter.cs
│ ├── GraphQL.Client.Serializer.SystemTextJson.csproj
│ ├── ImmutableConverter.cs
│ ├── JsonSerializerOptionsExtensions.cs
│ ├── MapConverter.cs
│ └── SystemTextJsonSerializer.cs
├── GraphQL.Client
│ ├── GraphQL.Client.csproj
│ ├── GraphQLHttpClient.cs
│ ├── GraphQLHttpClientExtensions.cs
│ ├── GraphQLHttpClientOptions.cs
│ ├── GraphQLHttpRequest.cs
│ ├── GraphQLHttpRequestException.cs
│ ├── GraphQLHttpResponse.cs
│ ├── GraphQLSubscriptionException.cs
│ ├── UriExtensions.cs
│ └── Websocket
│ │ ├── GraphQLHttpWebSocket.cs
│ │ ├── GraphQLTransportWSProtocolHandler.cs
│ │ ├── GraphQLWSProtocolHandler.cs
│ │ ├── GraphQLWebsocketConnectionException.cs
│ │ ├── IWebsocketProtocolHandler.cs
│ │ └── WebSocketProtocols.cs
└── GraphQL.Primitives
│ ├── ErrorPath.cs
│ ├── GraphQL.Primitives.csproj
│ ├── GraphQLError.cs
│ ├── GraphQLLocation.cs
│ ├── GraphQLQuery.cs
│ ├── GraphQLRequest.cs
│ ├── GraphQLResponse.cs
│ ├── Hash.cs
│ ├── IGraphQLResponse.cs
│ ├── Map.cs
│ └── StringSyntaxAttribute.cs
└── tests
├── .editorconfig
├── GraphQL.Client.Serializer.Tests
├── BaseSerializeNoCamelCaseTest.cs
├── BaseSerializerTest.cs
├── ConsistencyTests.cs
├── DefaultValidationTest.cs
├── GraphQL.Client.Serializer.Tests.csproj
├── NewtonsoftSerializerTest.cs
├── SystemTextJsonSerializerTests.cs
└── TestData
│ ├── DeserializeResponseTestData.cs
│ ├── SerializeToBytesTestData.cs
│ └── SerializeToStringTestData.cs
├── GraphQL.Client.Tests.Common
├── Chat
│ ├── AddMessageMutationResult.cs
│ ├── AddMessageVariables.cs
│ ├── GraphQLClientChatExtensions.cs
│ ├── JoinDeveloperMutationResult.cs
│ └── Schema
│ │ ├── CapitalizedFieldsGraphType.cs
│ │ ├── ChatMutation.cs
│ │ ├── ChatQuery.cs
│ │ ├── ChatSchema.cs
│ │ ├── ChatSubscriptions.cs
│ │ ├── IChat.cs
│ │ ├── Message.cs
│ │ ├── MessageFrom.cs
│ │ ├── MessageFromType.cs
│ │ ├── MessageType.cs
│ │ └── ReceivedMessage.cs
├── Common.cs
├── GraphQL.Client.Tests.Common.csproj
├── Helpers
│ ├── AvailableJsonSerializers.cs
│ ├── CallbackMonitor.cs
│ ├── ConcurrentTaskWrapper.cs
│ ├── MiscellaneousExtensions.cs
│ └── NetworkHelpers.cs
├── Properties
│ └── launchSettings.json
└── StarWars
│ ├── Extensions
│ └── ResolveFieldContextExtensions.cs
│ ├── StarWarsData.cs
│ ├── StarWarsMutation.cs
│ ├── StarWarsQuery.cs
│ ├── StarWarsSchema.cs
│ ├── TestData
│ └── StarWarsHumans.cs
│ └── Types
│ ├── CharacterInterface.cs
│ ├── DroidType.cs
│ ├── EpisodeEnum.cs
│ ├── HumanInputType.cs
│ ├── HumanType.cs
│ └── StarWarsCharacter.cs
├── GraphQL.Integration.Tests
├── APQ
│ └── AutomaticPersistentQueriesTest.cs
├── GraphQL.Integration.Tests.csproj
├── Helpers
│ ├── IntegrationServerTestFixture.cs
│ └── WebHostHelpers.cs
├── Properties
│ └── launchSettings.json
├── QueryAndMutationTests
│ ├── Base.cs
│ ├── Newtonsoft.cs
│ └── SystemTextJson.cs
├── UriExtensionTests.cs
├── UserAgentHeaderTests.cs
└── WebsocketTests
│ ├── Base.cs
│ ├── NewtonsoftGraphQLTransportWs.cs
│ ├── NewtonsoftGraphQLWs.cs
│ ├── SystemTextJsonAutoNegotiate.cs
│ ├── SystemTextJsonGraphQLTransportWs.cs
│ └── SystemTextJsonGraphQLWs.cs
├── GraphQL.Primitives.Tests
├── GraphQL.Primitives.Tests.csproj
├── GraphQLLocationTest.cs
├── GraphQLRequestTest.cs
├── GraphQLResponseTest.cs
└── JsonSerializationTests.cs
├── GraphQL.Server.Test
├── GraphQL.Server.Test.csproj
├── GraphQL
│ ├── Models
│ │ └── Repository.cs
│ ├── Storage.cs
│ ├── TestMutation.cs
│ ├── TestQuery.cs
│ ├── TestSchema.cs
│ └── TestSubscription.cs
├── Program.cs
├── Properties
│ └── launchSettings.json
├── Startup.cs
├── appsettings.Development.json
├── appsettings.json
└── libman.json
├── IntegrationTestServer
├── IntegrationTestServer.csproj
├── Program.cs
├── Properties
│ └── launchSettings.json
└── Startup.cs
└── tests.props
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "nuget"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 | - package-ecosystem: "github-actions"
8 | directory: "/"
9 | schedule:
10 | interval: "daily"
11 |
--------------------------------------------------------------------------------
/.github/workflows/branches.yml:
--------------------------------------------------------------------------------
1 | name: Branch workflow
2 | on:
3 | push:
4 | branches-ignore:
5 | - master
6 | - 'release/**'
7 | - 'releases/**'
8 | pull_request:
9 |
10 | env:
11 | DOTNET_NOLOGO: true
12 | DOTNET_CLI_TELEMETRY_OPTOUT: true
13 | MSBUILDSINGLELOADCONTEXT: 1
14 |
15 | jobs:
16 | build:
17 | name: Build and Test
18 | runs-on: ubuntu-latest
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v4
22 | with:
23 | fetch-depth: 0
24 | - name: Setup .NET SDK
25 | uses: actions/setup-dotnet@v4
26 | with:
27 | dotnet-version: |
28 | 8.0.x
29 | - name: Restore dotnet tools
30 | run: dotnet tool restore
31 | - name: Fetch complete repository including tags
32 | run: git fetch --tags --force --prune && git describe
33 | - name: Generate version info from git history
34 | run: dotnet gitversion /output json | jq -r 'to_entries|map("GitVersion_\(.key)=\(.value|tostring)")|.[]' >> $GITHUB_ENV
35 | - name: Fail if the version number has not been resolved
36 | if: ${{ !env.GitVersion_SemVer }}
37 | run: |
38 | echo Error! Version number not resolved!
39 | exit 1
40 | - name: Print current version
41 | run: echo "Current version is \"$GitVersion_SemVer\""
42 | - name: Install dependencies
43 | run: dotnet restore
44 | - name: Build solution
45 | run: dotnet build --no-restore -c Release
46 | - name: Run Tests
47 | run: dotnet test -c Release --no-restore --no-build
48 | - name: Create NuGet packages
49 | run: dotnet pack -c Release --no-restore --no-build -o nupkg
50 | - name: Upload nuget packages
51 | uses: actions/upload-artifact@v4
52 | with:
53 | name: nupkg
54 | path: nupkg
55 |
--------------------------------------------------------------------------------
/.github/workflows/master.yml:
--------------------------------------------------------------------------------
1 | name: Master workflow
2 | on:
3 | push:
4 | branches:
5 | - master
6 | - 'release/**'
7 | - 'releases/**'
8 |
9 | env:
10 | DOTNET_NOLOGO: true
11 | DOTNET_CLI_TELEMETRY_OPTOUT: true
12 | MSBUILDSINGLELOADCONTEXT: 1
13 |
14 | jobs:
15 | build:
16 | name: Build and Test
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 | with:
22 | fetch-depth: 0
23 | - name: Setup .NET SDK
24 | uses: actions/setup-dotnet@v4
25 | with:
26 | dotnet-version: "8.0.x"
27 | source-url: https://nuget.pkg.github.com/graphql-dotnet/index.json
28 | env:
29 | NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
30 | - name: Restore dotnet tools
31 | run: dotnet tool restore
32 | - name: Fetch complete repository including tags
33 | run: git fetch --tags --force --prune && git describe
34 | - name: Generate version info from git history
35 | run: dotnet gitversion /output json | jq -r 'to_entries|map("GitVersion_\(.key)=\(.value|tostring)")|.[]' >> $GITHUB_ENV
36 | - name: Fail if the version number has not been resolved
37 | if: ${{ !env.GitVersion_SemVer }}
38 | run: |
39 | echo Error! Version number not resolved!
40 | exit 1
41 | - name: Print current version
42 | run: echo "Current version is \"$GitVersion_SemVer\""
43 | - name: Install dependencies
44 | run: dotnet restore
45 | - name: Build solution
46 | run: dotnet build --no-restore -c Release
47 | - name: Run Tests
48 | run: dotnet test -c Release --no-restore --no-build
49 | - name: Create NuGet packages
50 | run: dotnet pack -c Release --no-restore --no-build -o nupkg
51 | - name: Upload nuget packages as artifacts
52 | uses: actions/upload-artifact@v4
53 | with:
54 | name: nupkg
55 | path: nupkg
56 | - name: Publish Nuget packages to GitHub registry
57 | run: dotnet nuget push "nupkg/*" -k ${{secrets.GITHUB_TOKEN}}
58 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 | on:
3 | release:
4 | types:
5 | - published
6 |
7 | env:
8 | DOTNET_NOLOGO: true
9 | DOTNET_CLI_TELEMETRY_OPTOUT: true
10 | MSBUILDSINGLELOADCONTEXT: 1
11 |
12 | jobs:
13 | build:
14 | name: Build and Test
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v4
19 | with:
20 | fetch-depth: 0
21 | - name: Check github.ref starts with 'refs/tags/'
22 | if: ${{ !startsWith(github.ref, 'refs/tags/') }}
23 | run: |
24 | echo Error! github.ref does not start with 'refs/tags'
25 | echo github.ref: ${{ github.ref }}
26 | exit 1
27 | - name: Setup .NET SDK
28 | uses: actions/setup-dotnet@v4
29 | with:
30 | dotnet-version: "8.0.x"
31 | source-url: https://api.nuget.org/v3/index.json
32 | env:
33 | NUGET_AUTH_TOKEN: ${{secrets.NUGET_API_KEY}}
34 | - name: Restore dotnet tools
35 | run: dotnet tool restore
36 | - name: Fetch complete repository including tags
37 | run: git fetch --tags --force --prune && git describe
38 | - name: Generate version info from git history
39 | run: dotnet gitversion /output json | jq -r 'to_entries|map("GitVersion_\(.key)=\(.value|tostring)")|.[]' >> $GITHUB_ENV
40 | - name: Fail if the version number has not been resolved
41 | if: ${{ !env.GitVersion_SemVer }}
42 | run: |
43 | echo Error! Version number not resolved!
44 | exit 1
45 | - name: Print current version
46 | run: echo "Current version is \"$GitVersion_SemVer\""
47 | - name: Install dependencies
48 | run: dotnet restore
49 | - name: Build solution
50 | run: dotnet build --no-restore -c Release
51 | - name: Create NuGet packages
52 | run: dotnet pack -c Release --no-restore --no-build -o nupkg
53 | - name: Upload nuget packages as artifacts
54 | uses: actions/upload-artifact@v4
55 | with:
56 | name: nupkg
57 | path: nupkg
58 | - name: Publish Nuget packages to Nuget registry
59 | run: dotnet nuget push "nupkg/*" -k ${{secrets.NUGET_API_KEY}}
60 | - name: Upload Nuget packages as release artifacts
61 | uses: actions/github-script@v7
62 | with:
63 | github-token: ${{secrets.GITHUB_TOKEN}}
64 | script: |
65 | console.log('environment', process.versions);
66 | const fs = require('fs').promises;
67 | const { repo: { owner, repo }, sha } = context;
68 | for (let file of await fs.readdir('nupkg')) {
69 | console.log('uploading', file);
70 | await github.rest.repos.uploadReleaseAsset({
71 | owner,
72 | repo,
73 | release_id: ${{ github.event.release.id }},
74 | name: file,
75 | data: await fs.readFile(`nupkg/${file}`)
76 | });
77 | }
78 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vs/
3 | .vscode/
4 | bin/
5 | obj/
6 | *.user
7 | nuget/
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Deinok,Alexander Rose,graphql-dotnet
5 | A GraphQL Client for .NET Standard
6 | true
7 | true
8 | latest
9 | en-US
10 | $(NoWarn);NU5105
11 | $(NoWarn);1591
12 | annotations
13 | logo.64x64.png
14 | MIT
15 | https://github.com/graphql-dotnet/graphql-client
16 | true
17 | GraphQL
18 | git
19 | true
20 | true
21 |
22 |
23 | true
24 | embedded
25 | enable
26 | true
27 | true
28 | True
29 | 4
30 | true
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | README.md
5 |
6 | true
7 |
8 |
9 |
27 |
28 |
29 | $(NoWarn);1591
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | all
39 | runtime; build; native; contentfiles; analyzers
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/GitVersion.yml:
--------------------------------------------------------------------------------
1 | mode: ContinuousDeployment
2 | branches:
3 | master:
4 | tag: alpha
5 |
--------------------------------------------------------------------------------
/GraphQL.Client.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | APQ
3 | QL
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 graphql-dotnet
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/SubscriptionIntegrationTest.ConsoleClient/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.WebSockets;
3 | using System.Reactive.Disposables;
4 | using System.Reactive.Linq;
5 | using System.Threading.Tasks;
6 | using GraphQL.Client.Http;
7 | using GraphQL.Common.Request;
8 |
9 | namespace SubsccriptionIntegrationTest.ConsoleClient
10 | {
11 | class Program
12 | {
13 | static async Task Main(string[] args)
14 | {
15 | Console.WriteLine("configuring client ...");
16 | using (var client = new GraphQLHttpClient("http://localhost:5000/graphql/", new GraphQLHttpClientOptions{ UseWebSocketForQueriesAndMutations = true }))
17 | {
18 |
19 | Console.WriteLine("subscribing to message stream ...");
20 |
21 | var subscriptions = new CompositeDisposable();
22 |
23 | subscriptions.Add(client.WebSocketReceiveErrors.Subscribe(e => {
24 | if(e is WebSocketException we)
25 | Console.WriteLine($"WebSocketException: {we.Message} (WebSocketError {we.WebSocketErrorCode}, ErrorCode {we.ErrorCode}, NativeErrorCode {we.NativeErrorCode}");
26 | else
27 | Console.WriteLine($"Exception in websocket receive stream: {e.ToString()}");
28 | }));
29 |
30 | subscriptions.Add(CreateSubscription("1", client));
31 | await Task.Delay(200);
32 | subscriptions.Add(CreateSubscription2("2", client));
33 | await Task.Delay(200);
34 | subscriptions.Add(CreateSubscription("3", client));
35 | await Task.Delay(200);
36 | subscriptions.Add(CreateSubscription("4", client));
37 | await Task.Delay(200);
38 | subscriptions.Add(CreateSubscription("5", client));
39 | await Task.Delay(200);
40 | subscriptions.Add(CreateSubscription("6", client));
41 | await Task.Delay(200);
42 | subscriptions.Add(CreateSubscription("7", client));
43 |
44 | using (subscriptions)
45 | {
46 | Console.WriteLine("client setup complete");
47 | var quit = false;
48 | do
49 | {
50 | Console.WriteLine("write message and press enter...");
51 | var message = Console.ReadLine();
52 | var graphQLRequest = new GraphQLRequest(@"
53 | mutation($input: MessageInputType){
54 | addMessage(message: $input){
55 | content
56 | }
57 | }")
58 | {
59 | Variables = new
60 | {
61 | input = new
62 | {
63 | fromId = "2",
64 | content = message,
65 | sentAt = DateTime.Now
66 | }
67 | }
68 | };
69 | var result = await client.SendMutationAsync(graphQLRequest).ConfigureAwait(false);
70 |
71 | if(result.Errors != null && result.Errors.Length > 0)
72 | {
73 | Console.WriteLine($"request returned {result.Errors.Length} errors:");
74 | foreach (var item in result.Errors)
75 | {
76 | Console.WriteLine($"{item.Message}");
77 | }
78 | }
79 | }
80 | while(!quit);
81 | Console.WriteLine("shutting down ...");
82 | }
83 | Console.WriteLine("subscriptions disposed ...");
84 | }
85 | Console.WriteLine("client disposed ...");
86 | }
87 |
88 | private static IDisposable CreateSubscription(string id, GraphQLHttpClient client)
89 | {
90 | #pragma warning disable 618
91 | var stream = client.CreateSubscriptionStream(new GraphQLRequest(@"
92 | subscription {
93 | messageAdded{
94 | content
95 | from {
96 | displayName
97 | }
98 | }
99 | }"
100 | )
101 | { Variables = new { id } });
102 | #pragma warning restore 618
103 |
104 | return stream.Subscribe(
105 | response => Console.WriteLine($"{id}: new message from \"{response.Data.messageAdded.from.displayName.Value}\": {response.Data.messageAdded.content.Value}"),
106 | exception => Console.WriteLine($"{id}: message subscription stream failed: {exception}"),
107 | () => Console.WriteLine($"{id}: message subscription stream completed"));
108 |
109 | }
110 |
111 |
112 | private static IDisposable CreateSubscription2(string id, GraphQLHttpClient client)
113 | {
114 | #pragma warning disable 618
115 | var stream = client.CreateSubscriptionStream(new GraphQLRequest(@"
116 | subscription {
117 | contentAdded{
118 | content
119 | from {
120 | displayName
121 | }
122 | }
123 | }"
124 | )
125 | { Variables = new { id } });
126 | #pragma warning restore 618
127 |
128 | return stream.Subscribe(
129 | response => Console.WriteLine($"{id}: new content from \"{response.Data.contentAdded.from.displayName.Value}\": {response.Data.contentAdded.content.Value}"),
130 | exception => Console.WriteLine($"{id}: content subscription stream failed: {exception}"),
131 | () => Console.WriteLine($"{id}: content subscription stream completed"));
132 |
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/SubscriptionIntegrationTest.ConsoleClient/SubscriptionIntegrationTest.ConsoleClient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.0;net461
6 | 8.0
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/assets/logo.64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/graphql-dotnet/graphql-client/6236c9b2c6f3568f96a9f8e12aa6fb367321c068/assets/logo.64x64.png
--------------------------------------------------------------------------------
/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/dotnet-tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "isRoot": true,
3 | "tools": {
4 | "dotnet-format": {
5 | "version": "3.2.107702",
6 | "commands": [
7 | "dotnet-format"
8 | ]
9 | },
10 | "gitversion.tool": {
11 | "version": "5.12.0",
12 | "commands": [
13 | "dotnet-gitversion"
14 | ]
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/examples/.editorconfig:
--------------------------------------------------------------------------------
1 | # Configure await
2 | configure_await_analysis_mode = disabled
3 |
--------------------------------------------------------------------------------
/examples/GraphQL.Client.Example/GraphQL.Client.Example.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/GraphQL.Client.Example/PersonAndFilmsResponse.cs:
--------------------------------------------------------------------------------
1 | namespace GraphQL.Client.Example;
2 |
3 | public class PersonAndFilmsResponse
4 | {
5 | public PersonContent Person { get; set; }
6 |
7 | public class PersonContent
8 | {
9 | public string Name { get; set; }
10 |
11 | public FilmConnectionContent FilmConnection { get; set; }
12 |
13 | public class FilmConnectionContent
14 | {
15 | public List Films { get; set; }
16 |
17 | public class FilmContent
18 | {
19 | public string Title { get; set; }
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/GraphQL.Client.Example/Program.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using GraphQL.Client.Http;
3 | using GraphQL.Client.Serializer.Newtonsoft;
4 |
5 | namespace GraphQL.Client.Example;
6 |
7 | public static class Program
8 | {
9 | public static async Task Main()
10 | {
11 | using var graphQLClient = new GraphQLHttpClient("https://swapi.apis.guru/", new NewtonsoftJsonSerializer());
12 |
13 | var personAndFilmsRequest = new GraphQLRequest
14 | {
15 | Query = @"
16 | query PersonAndFilms($id: ID) {
17 | person(id: $id) {
18 | name
19 | filmConnection {
20 | films {
21 | title
22 | }
23 | }
24 | }
25 | }",
26 | OperationName = "PersonAndFilms",
27 | Variables = new
28 | {
29 | id = "cGVvcGxlOjE="
30 | }
31 | };
32 |
33 | var graphQLResponse = await graphQLClient.SendQueryAsync(personAndFilmsRequest);
34 | Console.WriteLine("raw response:");
35 | Console.WriteLine(JsonSerializer.Serialize(graphQLResponse, new JsonSerializerOptions { WriteIndented = true }));
36 |
37 | Console.WriteLine();
38 | Console.WriteLine($"Name: {graphQLResponse.Data.Person.Name}");
39 | var films = string.Join(", ", graphQLResponse.Data.Person.FilmConnection.Films.Select(f => f.Title));
40 | Console.WriteLine($"Films: {films}");
41 |
42 | Console.WriteLine();
43 | Console.WriteLine("Press any key to quit...");
44 | Console.ReadKey();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/GraphQL.Client.Abstractions.Websocket/GraphQL.Client.Abstractions.Websocket.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Abstractions for the Websocket transport used in GraphQL.Client
5 | netstandard2.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/GraphQL.Client.Abstractions.Websocket/GraphQLWebSocketRequest.cs:
--------------------------------------------------------------------------------
1 | namespace GraphQL.Client.Abstractions.Websocket;
2 |
3 | ///
4 | /// A Subscription Request
5 | ///
6 | public class GraphQLWebSocketRequest : Dictionary, IEquatable
7 | {
8 | public const string ID_KEY = "id";
9 | public const string TYPE_KEY = "type";
10 | public const string PAYLOAD_KEY = "payload";
11 |
12 | ///
13 | /// The Identifier of the request
14 | ///
15 | public string Id
16 | {
17 | get => TryGetValue(ID_KEY, out object value) ? (string)value : null;
18 | set => this[ID_KEY] = value;
19 | }
20 |
21 | ///
22 | /// The Type of the Request
23 | ///
24 | public string Type
25 | {
26 | get => TryGetValue(TYPE_KEY, out object value) ? (string)value : null;
27 | set => this[TYPE_KEY] = value;
28 | }
29 |
30 | ///
31 | /// The payload of the websocket request
32 | ///
33 | public object? Payload
34 | {
35 | get => TryGetValue(PAYLOAD_KEY, out object value) ? value : null;
36 | set => this[PAYLOAD_KEY] = value;
37 | }
38 |
39 | private readonly TaskCompletionSource _tcs = new TaskCompletionSource();
40 |
41 | ///
42 | /// Task used to await the actual send operation and to convey potential exceptions
43 | ///
44 | ///
45 | public Task SendTask() => _tcs.Task;
46 |
47 | ///
48 | /// gets called when the send operation for this request has completed successfully
49 | ///
50 | public void SendCompleted() => _tcs.SetResult(true);
51 |
52 | ///
53 | /// gets called when an exception occurs during the send operation
54 | ///
55 | ///
56 | public void SendFailed(Exception e) => _tcs.SetException(e);
57 |
58 | ///
59 | /// gets called when the GraphQLHttpWebSocket has been disposed before the send operation for this request has started
60 | ///
61 | public void SendCanceled() => _tcs.SetCanceled();
62 |
63 | ///
64 | public override bool Equals(object obj) => Equals(obj as GraphQLWebSocketRequest);
65 |
66 | ///
67 | public bool Equals(GraphQLWebSocketRequest other)
68 | {
69 | if (other == null)
70 | {
71 | return false;
72 | }
73 | if (ReferenceEquals(this, other))
74 | {
75 | return true;
76 | }
77 | if (!Equals(Id, other.Id))
78 | {
79 | return false;
80 | }
81 | if (!Equals(Type, other.Type))
82 | {
83 | return false;
84 | }
85 | if (!Equals(Payload, other.Payload))
86 | {
87 | return false;
88 | }
89 | return true;
90 | }
91 |
92 | ///
93 | public override int GetHashCode()
94 | {
95 | var hashCode = 9958074;
96 | hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Id);
97 | hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Type);
98 | hashCode = hashCode * -1521134295 + EqualityComparer