diff --git a/src/SAHB.GraphQLClient/Batching/Internal/GraphQLBatch.cs b/src/SAHB.GraphQLClient/Batching/Internal/GraphQLBatch.cs index df2607c..7a0a2dc 100644 --- a/src/SAHB.GraphQLClient/Batching/Internal/GraphQLBatch.cs +++ b/src/SAHB.GraphQLClient/Batching/Internal/GraphQLBatch.cs @@ -14,9 +14,22 @@ internal class GraphQLBatch : IGraphQLBatch { private readonly GraphQLBatchMerger _batch; - internal GraphQLBatch(GraphQLOperationType graphQLOperationType, string url, HttpMethod httpMethod, IDictionary headers, string authorizationToken, string authorizationMethod, IGraphQLHttpExecutor executor, IGraphQLFieldBuilder fieldBuilder, IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization deserialization) + internal GraphQLBatch(GraphQLOperationType graphQLOperationType, string operationName, string url, + HttpMethod httpMethod, IDictionary headers, string authorizationToken, + string authorizationMethod, IGraphQLHttpExecutor executor, IGraphQLFieldBuilder fieldBuilder, + IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization deserialization) + { + _batch = new GraphQLBatchMerger(graphQLOperationType, operationName, url, httpMethod, headers, + authorizationToken, authorizationMethod, executor, fieldBuilder, queryGenerator, deserialization); + } + + internal GraphQLBatch(GraphQLOperationType graphQLOperationType, string url, HttpMethod httpMethod, + IDictionary headers, string authorizationToken, string authorizationMethod, + IGraphQLHttpExecutor executor, IGraphQLFieldBuilder fieldBuilder, + IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization deserialization) : this( + graphQLOperationType, null, url, httpMethod, headers, authorizationToken, authorizationMethod, executor, + fieldBuilder, queryGenerator, deserialization) { - _batch = new GraphQLBatchMerger(graphQLOperationType, url, httpMethod, headers, authorizationToken, authorizationMethod, executor, fieldBuilder, queryGenerator, deserialization); } /// diff --git a/src/SAHB.GraphQLClient/Batching/Internal/GraphQLBatchMerger.cs b/src/SAHB.GraphQLClient/Batching/Internal/GraphQLBatchMerger.cs index 950ca46..56f6f66 100644 --- a/src/SAHB.GraphQLClient/Batching/Internal/GraphQLBatchMerger.cs +++ b/src/SAHB.GraphQLClient/Batching/Internal/GraphQLBatchMerger.cs @@ -18,6 +18,7 @@ namespace SAHB.GraphQLClient.Batching.Internal internal class GraphQLBatchMerger { private readonly GraphQLOperationType _graphQLOperationType; + private readonly string _operationName; private readonly string _url; private readonly HttpMethod _httpMethod; private readonly IDictionary _headers; @@ -34,9 +35,22 @@ internal class GraphQLBatchMerger private GraphQLDataResult _result; private string _executedQuery; - public GraphQLBatchMerger(GraphQLOperationType graphQLOperationType, string url, HttpMethod httpMethod, IDictionary headers, string authorizationToken, string authorizationMethod, IGraphQLHttpExecutor executor, IGraphQLFieldBuilder fieldBuilder, IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization graphQLDeserialization) + public GraphQLBatchMerger(GraphQLOperationType graphQLOperationType, string url, + HttpMethod httpMethod, IDictionary headers, string authorizationToken, + string authorizationMethod, IGraphQLHttpExecutor executor, IGraphQLFieldBuilder fieldBuilder, + IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization graphQLDeserialization) : this( + graphQLOperationType, null, url, httpMethod, headers, authorizationToken, authorizationMethod, executor, + fieldBuilder, queryGenerator, graphQLDeserialization) + { + } + + public GraphQLBatchMerger(GraphQLOperationType graphQLOperationType, string operationName, string url, + HttpMethod httpMethod, IDictionary headers, string authorizationToken, + string authorizationMethod, IGraphQLHttpExecutor executor, IGraphQLFieldBuilder fieldBuilder, + IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization graphQLDeserialization) { _graphQLOperationType = graphQLOperationType; + _operationName = operationName; _url = url; _httpMethod = httpMethod; _headers = headers; @@ -78,16 +92,13 @@ public Task GetValue(string identifier, CancellationToken cancellationToke return GetDeserializedResult(identifier, cancellationToken); } - public async Task> GetDetailedValue(string identifier, CancellationToken cancellationToken) + public async Task> GetDetailedValue(string identifier, + CancellationToken cancellationToken) where T : class { var deserialized = await GetDeserializedResult(identifier, cancellationToken).ConfigureAwait(false); - return new GraphQLDataResult - { - Data = deserialized, - Headers = _result.Headers - }; + return new GraphQLDataResult {Data = deserialized, Headers = _result.Headers}; } public async Task Execute(CancellationToken cancellationToken) @@ -107,11 +118,13 @@ public async Task Execute(CancellationToken cancellationToken) var fields = _fields.SelectMany(e => e.Value).ToList(); // Generate query - _executedQuery = _queryGenerator.GenerateQuery(_graphQLOperationType, fields, + _executedQuery = _queryGenerator.GenerateQuery(_graphQLOperationType, _operationName, fields, _arguments.SelectMany(e => e.Value).ToArray()); // Execute query - var serverResult = await _executor.ExecuteQuery(query: _executedQuery, url: _url, method: _httpMethod, authorizationToken: _authorizationToken, authorizationMethod: _authorizationMethod, headers: _headers, cancellationToken: cancellationToken).ConfigureAwait(false); + var serverResult = await _executor.ExecuteQuery(query: _executedQuery, url: _url, method: _httpMethod, + authorizationToken: _authorizationToken, authorizationMethod: _authorizationMethod, headers: _headers, + cancellationToken: cancellationToken).ConfigureAwait(false); // Deserilize result _result = _graphQLDeserialization.DeserializeResult(serverResult.Response, fields); @@ -178,7 +191,8 @@ private async Task GetDeserializedResult(string identifier, CancellationTo } // Deserialize from - return _graphQLDeserialization.DeserializeResult(jsonObject: deserilizeFrom, fields: _fields[identifier]); + return _graphQLDeserialization.DeserializeResult(jsonObject: deserilizeFrom, + fields: _fields[identifier]); } public bool Executed => _isExecuted; diff --git a/src/SAHB.GraphQLClient/Extentions/GraphQLQueryGeneratorFromFieldsExtentions.cs b/src/SAHB.GraphQLClient/Extentions/GraphQLQueryGeneratorFromFieldsExtentions.cs index af97b61..bc127fc 100644 --- a/src/SAHB.GraphQLClient/Extentions/GraphQLQueryGeneratorFromFieldsExtentions.cs +++ b/src/SAHB.GraphQLClient/Extentions/GraphQLQueryGeneratorFromFieldsExtentions.cs @@ -1,7 +1,9 @@ using System; +using System.Reflection; using SAHB.GraphQLClient.FieldBuilder; using SAHB.GraphQLClient.FieldBuilder.Attributes; using SAHB.GraphQLClient.QueryGenerator; +using SAHB.GraphQLClient.QueryGenerator.Attributes; namespace SAHB.GraphQLClient.Extentions { @@ -24,8 +26,12 @@ public static string GetQuery(this IGraphQLQueryGeneratorFromFields queryGene { if (queryGenerator == null) throw new ArgumentNullException(nameof(queryGenerator)); if (fieldBuilder == null) throw new ArgumentNullException(nameof(fieldBuilder)); - var selectionSet = fieldBuilder.GenerateSelectionSet(typeof(T)); - return queryGenerator.GenerateQuery(GraphQLOperationType.Query, selectionSet, arguments); + + var type = typeof(T); + var selectionSet = fieldBuilder.GenerateSelectionSet(type); + var operationNameAttribute = type.GetTypeInfo().GetCustomAttribute(); + + return queryGenerator.GenerateQuery(GraphQLOperationType.Query, operationNameAttribute?.OperationName, selectionSet, arguments); } /// @@ -41,8 +47,12 @@ public static string GetMutation(this IGraphQLQueryGeneratorFromFields queryG { if (queryGenerator == null) throw new ArgumentNullException(nameof(queryGenerator)); if (fieldBuilder == null) throw new ArgumentNullException(nameof(fieldBuilder)); - var selectionSet = fieldBuilder.GenerateSelectionSet(typeof(T)); - return queryGenerator.GenerateQuery(GraphQLOperationType.Mutation, selectionSet, arguments); + + var type = typeof(T); + var selectionSet = fieldBuilder.GenerateSelectionSet(type); + var operationNameAttribute = type.GetTypeInfo().GetCustomAttribute(); + + return queryGenerator.GenerateQuery(GraphQLOperationType.Mutation, operationNameAttribute?.OperationName, selectionSet, arguments); } } } diff --git a/src/SAHB.GraphQLClient/GraphQLHttpClient.cs b/src/SAHB.GraphQLClient/GraphQLHttpClient.cs index 2f1ac4c..e5b54e9 100644 --- a/src/SAHB.GraphQLClient/GraphQLHttpClient.cs +++ b/src/SAHB.GraphQLClient/GraphQLHttpClient.cs @@ -48,12 +48,15 @@ public class GraphQLHttpClient : IGraphQLHttpClient public IQueryGeneratorFilter FilterGenerator { get; } [Obsolete] - public GraphQLHttpClient(IGraphQLHttpExecutor httpExecutor, IGraphQLFieldBuilder fieldBuilder, IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization deserialization) + public GraphQLHttpClient(IGraphQLHttpExecutor httpExecutor, IGraphQLFieldBuilder fieldBuilder, + IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization deserialization) : this(httpExecutor, fieldBuilder, queryGenerator, deserialization, null) { } - public GraphQLHttpClient(IGraphQLHttpExecutor httpExecutor, IGraphQLFieldBuilder fieldBuilder, IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization deserialization, IQueryGeneratorFilter filterGenerator) + public GraphQLHttpClient(IGraphQLHttpExecutor httpExecutor, IGraphQLFieldBuilder fieldBuilder, + IGraphQLQueryGeneratorFromFields queryGenerator, IGraphQLDeserialization deserialization, + IQueryGeneratorFilter filterGenerator) { HttpExecutor = httpExecutor ?? throw new ArgumentNullException(nameof(httpExecutor)); FieldBuilder = fieldBuilder ?? throw new ArgumentNullException(nameof(fieldBuilder)); @@ -68,7 +71,8 @@ public GraphQLHttpClient(IGraphQLHttpExecutor httpExecutor, IGraphQLFieldBuilder /// Returns a default public static GraphQLHttpClient Default() { - return new GraphQLHttpClient(new GraphQLHttpExecutor(), new GraphQLFieldBuilder(), new GraphQLQueryGeneratorFromFields(), new GraphQLDeserilization(), new QueryGeneratorFilter()); + return new GraphQLHttpClient(new GraphQLHttpExecutor(), new GraphQLFieldBuilder(), + new GraphQLQueryGeneratorFromFields(), new GraphQLDeserilization(), new QueryGeneratorFilter()); } /// @@ -78,21 +82,30 @@ public static GraphQLHttpClient Default() /// Returns a default using the specified public static GraphQLHttpClient Default(HttpClient client) { - return new GraphQLHttpClient(new GraphQLHttpExecutor(client), new GraphQLFieldBuilder(), new GraphQLQueryGeneratorFromFields(), new GraphQLDeserilization(), new QueryGeneratorFilter()); + return new GraphQLHttpClient(new GraphQLHttpExecutor(client), new GraphQLFieldBuilder(), + new GraphQLQueryGeneratorFromFields(), new GraphQLDeserilization(), new QueryGeneratorFilter()); } /// - public Task Execute(GraphQLOperationType operationType, string url = null, HttpMethod httpMethod = null, IDictionary headers = null, Expression> filter = null, string authorizationToken = null, string authorizationMethod = "Bearer", CancellationToken cancellationToken = default, params GraphQLQueryArgument[] arguments) where T : class + public Task Execute(GraphQLOperationType operationType, string url = null, HttpMethod httpMethod = null, + IDictionary headers = null, Expression> filter = null, + string authorizationToken = null, string authorizationMethod = "Bearer", + CancellationToken cancellationToken = default, params GraphQLQueryArgument[] arguments) where T : class { // Generate selectionSet var selectionSet = FieldBuilder.GenerateSelectionSet(typeof(T)); // Execute - return Execute(operationType, selectionSet, arguments, url: url, httpMethod: httpMethod, headers: headers, filter: filter, authorizationMethod: authorizationMethod, authorizationToken: authorizationToken, cancellationToken: cancellationToken); + return Execute(operationType, selectionSet, arguments, url: url, httpMethod: httpMethod, + headers: headers, filter: filter, authorizationMethod: authorizationMethod, + authorizationToken: authorizationToken, cancellationToken: cancellationToken); } /// - public Task Execute(GraphQLOperationType operationType, Action builder, string url = null, HttpMethod httpMethod = null, IDictionary headers = null, string authorizationToken = null, string authorizationMethod = "Bearer", CancellationToken cancellationToken = default, params GraphQLQueryArgument[] arguments) + public Task Execute(GraphQLOperationType operationType, Action builder, + string url = null, HttpMethod httpMethod = null, IDictionary headers = null, + string authorizationToken = null, string authorizationMethod = "Bearer", + CancellationToken cancellationToken = default, params GraphQLQueryArgument[] arguments) { // Get builder var build = new GraphQLBuilder(); @@ -102,83 +115,122 @@ public Task Execute(GraphQLOperationType operationType, Action(operationType, selectionSet, arguments, url: url, httpMethod: httpMethod, headers: headers, filter: null, authorizationMethod: authorizationMethod, authorizationToken: authorizationToken, cancellationToken: cancellationToken); + return Execute(operationType, selectionSet, arguments, url: url, httpMethod: httpMethod, + headers: headers, filter: null, authorizationMethod: authorizationMethod, + authorizationToken: authorizationToken, cancellationToken: cancellationToken); + } + + public IGraphQLBatch CreateBatch(GraphQLOperationType operationType, string url, + HttpMethod httpMethod = null, + IDictionary headers = null, string authorizationToken = null, + string authorizationMethod = "Bearer") + { + return new GraphQLBatch(operationType, url, httpMethod, headers, authorizationToken: authorizationToken, + authorizationMethod: authorizationMethod, HttpExecutor, FieldBuilder, QueryGenerator, Deserialization); } /// - public IGraphQLBatch CreateBatch(GraphQLOperationType operationType, string url = null, HttpMethod httpMethod = null, IDictionary headers = null, string authorizationToken = null, string authorizationMethod = "Bearer") + public IGraphQLBatch CreateBatch(GraphQLOperationType operationType, string operationName, string url, + HttpMethod httpMethod = null, IDictionary headers = null, string authorizationToken = null, + string authorizationMethod = "Bearer") { - return new GraphQLBatch(operationType, url, httpMethod, headers, authorizationToken: authorizationToken, authorizationMethod: authorizationMethod, HttpExecutor, FieldBuilder, QueryGenerator, Deserialization); + return new GraphQLBatch(operationType, operationName, url, httpMethod, headers, + authorizationToken: authorizationToken, authorizationMethod: authorizationMethod, HttpExecutor, + FieldBuilder, QueryGenerator, Deserialization); } - private async Task Execute(GraphQLOperationType operationType, IEnumerable selectionSet, GraphQLQueryArgument[] arguments, string url, HttpMethod httpMethod, IDictionary headers, Expression> filter, string authorizationMethod, string authorizationToken, CancellationToken cancellationToken) where T : class + private async Task Execute(GraphQLOperationType operationType, IEnumerable selectionSet, + GraphQLQueryArgument[] arguments, string url, HttpMethod httpMethod, IDictionary headers, + Expression> filter, string authorizationMethod, string authorizationToken, + CancellationToken cancellationToken) where T : class { - var result = await ExecuteQuery(operationType, selectionSet, arguments, url, httpMethod, headers, filter, authorizationMethod: authorizationMethod, authorizationToken: authorizationToken, cancellationToken: cancellationToken).ConfigureAwait(false); + var result = await ExecuteQuery(operationType, selectionSet, arguments, url, httpMethod, headers, filter, + authorizationMethod: authorizationMethod, authorizationToken: authorizationToken, + cancellationToken: cancellationToken).ConfigureAwait(false); return result.Data; } - private Task> ExecuteQuery(GraphQLOperationType operationType, IEnumerable selectionSet, GraphQLQueryArgument[] arguments, string url, HttpMethod httpMethod, IDictionary headers, Expression> filter, string authorizationMethod, string authorizationToken, CancellationToken cancellationToken) where T : class + private Task> ExecuteQuery(GraphQLOperationType operationType, + IEnumerable selectionSet, GraphQLQueryArgument[] arguments, string url, HttpMethod httpMethod, + IDictionary headers, Expression> filter, string authorizationMethod, + string authorizationToken, CancellationToken cancellationToken) where T : class { - var query = GetGraphQLQuery(operationType, selectionSet, arguments, url, httpMethod, headers, GetQueryFilter(filter), authorizationToken: authorizationToken, authorizationMethod: authorizationMethod); + var query = GetGraphQLQuery(operationType, selectionSet, arguments, url, httpMethod, headers, + GetQueryFilter(filter), authorizationToken: authorizationToken, + authorizationMethod: authorizationMethod); return query.ExecuteDetailed(cancellationToken); } /// public IGraphQLQuery CreateQuery(Action builder, string url, string authorizationToken = null, - string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) + string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) { return CreateQuery(builder, url, HttpMethod.Post, authorizationToken, authorizationMethod, arguments); } /// - public IGraphQLQuery CreateQuery(string url, string authorizationToken = null, string authorizationMethod = "Bearer", + public IGraphQLQuery CreateQuery(string url, string authorizationToken = null, + string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) where T : class { return CreateQuery(url, HttpMethod.Post, authorizationToken, authorizationMethod, arguments); } /// - public IGraphQLQuery CreateQuery(string url, Expression> filter, string authorizationToken = null, string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) where T : class + public IGraphQLQuery CreateQuery(string url, Expression> filter, + string authorizationToken = null, string authorizationMethod = "Bearer", + params GraphQLQueryArgument[] arguments) where T : class { return CreateQuery(url, HttpMethod.Post, filter, authorizationToken, authorizationMethod, arguments); } /// - public IGraphQLQuery CreateMutation(string url, Expression> filter, string authorizationToken = null, string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) where T : class + public IGraphQLQuery CreateMutation(string url, Expression> filter, + string authorizationToken = null, string authorizationMethod = "Bearer", + params GraphQLQueryArgument[] arguments) where T : class { return CreateMutation(url, HttpMethod.Post, filter, authorizationToken, authorizationMethod, arguments); } /// - public IGraphQLQuery CreateMutation(string url, HttpMethod httpMethod, Expression> filter, string authorizationToken = null, string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) where T : class + public IGraphQLQuery CreateMutation(string url, HttpMethod httpMethod, Expression> filter, + string authorizationToken = null, string authorizationMethod = "Bearer", + params GraphQLQueryArgument[] arguments) where T : class { var selectionSet = FieldBuilder.GenerateSelectionSet(typeof(T)); - return GetGraphQLQuery(GraphQLOperationType.Mutation, selectionSet, arguments, url, httpMethod, null, GetQueryFilter(filter), authorizationToken, authorizationMethod); + return GetGraphQLQuery(GraphQLOperationType.Mutation, selectionSet, arguments, url, httpMethod, null, + GetQueryFilter(filter), authorizationToken, authorizationMethod); } /// - public IGraphQLQuery CreateQuery(string url, HttpMethod httpMethod, Expression> filter, string authorizationToken = null, string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) where T : class + public IGraphQLQuery CreateQuery(string url, HttpMethod httpMethod, Expression> filter, + string authorizationToken = null, string authorizationMethod = "Bearer", + params GraphQLQueryArgument[] arguments) where T : class { var selectionSet = FieldBuilder.GenerateSelectionSet(typeof(T)); - return GetGraphQLQuery(GraphQLOperationType.Query, selectionSet, arguments, url, httpMethod, null, GetQueryFilter(filter), authorizationToken, authorizationMethod); + return GetGraphQLQuery(GraphQLOperationType.Query, selectionSet, arguments, url, httpMethod, null, + GetQueryFilter(filter), authorizationToken, authorizationMethod); } /// - public IGraphQLQuery CreateMutation(Action builder, string url, string authorizationToken = null, + public IGraphQLQuery CreateMutation(Action builder, string url, + string authorizationToken = null, string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) { return CreateMutation(builder, url, HttpMethod.Post, authorizationToken, authorizationMethod, arguments); } /// - public IGraphQLQuery CreateMutation(string url, string authorizationToken = null, string authorizationMethod = "Bearer", + public IGraphQLQuery CreateMutation(string url, string authorizationToken = null, + string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) where T : class { return CreateMutation(url, HttpMethod.Post, authorizationToken, authorizationMethod, arguments); } /// - public IGraphQLQuery CreateMutation(Action builder, string url, HttpMethod httpMethod, string authorizationToken = null, + public IGraphQLQuery CreateMutation(Action builder, string url, HttpMethod httpMethod, + string authorizationToken = null, string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) { var build = new GraphQLBuilder(); @@ -188,7 +240,8 @@ public IGraphQLQuery CreateMutation(Action builder, string url, var selectionSet = build.GetFields(); // Get query - return GetGraphQLQuery(GraphQLOperationType.Mutation, selectionSet, arguments, url, httpMethod, null, null, authorizationToken, authorizationMethod); + return GetGraphQLQuery(GraphQLOperationType.Mutation, selectionSet, arguments, url, httpMethod, null, null, + authorizationToken, authorizationMethod); } /// @@ -196,11 +249,13 @@ public IGraphQLQuery CreateMutation(string url, HttpMethod httpMethod, str string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) where T : class { var selectionSet = FieldBuilder.GenerateSelectionSet(typeof(T)); - return GetGraphQLQuery(GraphQLOperationType.Mutation, selectionSet, arguments, url, httpMethod, null, null, authorizationToken, authorizationMethod); + return GetGraphQLQuery(GraphQLOperationType.Mutation, selectionSet, arguments, url, httpMethod, null, + null, authorizationToken, authorizationMethod); } /// - public IGraphQLQuery CreateQuery(Action builder, string url, HttpMethod httpMethod, string authorizationToken = null, + public IGraphQLQuery CreateQuery(Action builder, string url, HttpMethod httpMethod, + string authorizationToken = null, string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) { var build = new GraphQLBuilder(); @@ -210,7 +265,8 @@ public IGraphQLQuery CreateQuery(Action builder, string url, Ht var selectionSet = build.GetFields(); // Get query - return GetGraphQLQuery(GraphQLOperationType.Query, selectionSet, arguments, url, httpMethod, null, null, authorizationToken, authorizationMethod); + return GetGraphQLQuery(GraphQLOperationType.Query, selectionSet, arguments, url, httpMethod, null, null, + authorizationToken, authorizationMethod); } /// @@ -218,41 +274,64 @@ public IGraphQLQuery CreateQuery(string url, HttpMethod httpMethod, string string authorizationMethod = "Bearer", params GraphQLQueryArgument[] arguments) where T : class { var selectionSet = FieldBuilder.GenerateSelectionSet(typeof(T)); - return GetGraphQLQuery(GraphQLOperationType.Query, selectionSet, arguments, url, httpMethod, null, null, authorizationToken, authorizationMethod); + return GetGraphQLQuery(GraphQLOperationType.Query, selectionSet, arguments, url, httpMethod, null, null, + authorizationToken, authorizationMethod); } #region Old methods + /// - public IGraphQLBatch CreateBatch(string url, string authorizationToken = null, string authorizationMethod = "Bearer") + public IGraphQLBatch CreateBatch(string url, string authorizationToken = null, + string authorizationMethod = "Bearer") { - return CreateBatch(url, HttpMethod.Post, authorizationToken, authorizationMethod); + return CreateBatch(null, url, HttpMethod.Post, authorizationToken, authorizationMethod); } - /// public IGraphQLBatch CreateBatch(string url, HttpMethod httpMethod, string authorizationToken = null, string authorizationMethod = "Bearer") { - return new GraphQLBatch(GraphQLOperationType.Query, url, httpMethod, null, authorizationToken, authorizationMethod, HttpExecutor, FieldBuilder, QueryGenerator, Deserialization); + return CreateBatch(null, url, httpMethod, authorizationToken, authorizationMethod); + ; + } + + /// + public IGraphQLBatch CreateBatch(string operationName, string url, string authorizationToken = null, + string authorizationMethod = "Bearer") + { + return CreateBatch(operationName, url, HttpMethod.Post, authorizationToken, authorizationMethod); + } + + /// + public IGraphQLBatch CreateBatch(string operationName, string url, HttpMethod httpMethod, + string authorizationToken = null, + string authorizationMethod = "Bearer") + { + return new GraphQLBatch(GraphQLOperationType.Query, operationName, url, httpMethod, null, + authorizationToken, authorizationMethod, HttpExecutor, FieldBuilder, QueryGenerator, Deserialization); } // ReSharper disable once InconsistentNaming - private IGraphQLQuery GetGraphQLQuery(GraphQLOperationType operationType, IEnumerable selectionSet, GraphQLQueryArgument[] arguments, string url, HttpMethod httpMethod, + private IGraphQLQuery GetGraphQLQuery(GraphQLOperationType operationType, + IEnumerable selectionSet, GraphQLQueryArgument[] arguments, string url, HttpMethod httpMethod, IDictionary headers, Func filter, string authorizationToken = null, string authorizationMethod = "Bearer") { - return new GraphQLQuery(operationType, selectionSet, arguments, url, httpMethod, filter, authorizationToken, authorizationMethod, headers, QueryGenerator, HttpExecutor, Deserialization); + return new GraphQLQuery(operationType, selectionSet, arguments, url, httpMethod, filter, authorizationToken, + authorizationMethod, headers, QueryGenerator, HttpExecutor, Deserialization); } // ReSharper disable once InconsistentNaming - private IGraphQLQuery GetGraphQLQuery(GraphQLOperationType operationType, IEnumerable selectionSet, GraphQLQueryArgument[] arguments, string url, HttpMethod httpMethod, + private IGraphQLQuery GetGraphQLQuery(GraphQLOperationType operationType, + IEnumerable selectionSet, GraphQLQueryArgument[] arguments, string url, HttpMethod httpMethod, IDictionary headers, Func filter, string authorizationToken = null, string authorizationMethod = "Bearer") where T : class { - return new GraphQLQuery(operationType, selectionSet, arguments, url, httpMethod, filter, authorizationToken, authorizationMethod, headers, QueryGenerator, HttpExecutor, Deserialization); + return new GraphQLQuery(operationType, selectionSet, arguments, url, httpMethod, filter, + authorizationToken, authorizationMethod, headers, QueryGenerator, HttpExecutor, Deserialization); } private Func GetQueryFilter(Expression> filter) @@ -262,7 +341,8 @@ private Func GetQueryFilter(Expression> filter return null; if (FilterGenerator == null) - throw new NotSupportedException("IQueryGeneratorFilter needs to be specified in constructer if filter is used"); + throw new NotSupportedException( + "IQueryGeneratorFilter needs to be specified in constructer if filter is used"); return FilterGenerator.GetFilter(filter); } diff --git a/src/SAHB.GraphQLClient/IGraphQLHttpClient.cs b/src/SAHB.GraphQLClient/IGraphQLHttpClient.cs index 1123160..34ceb56 100644 --- a/src/SAHB.GraphQLClient/IGraphQLHttpClient.cs +++ b/src/SAHB.GraphQLClient/IGraphQLHttpClient.cs @@ -60,8 +60,21 @@ public interface IGraphQLHttpClient /// The token used to authenticate with the GraphQL server /// The method used for authentication /// - IGraphQLBatch CreateBatch(GraphQLOperationType operationType, string url = null, HttpMethod httpMethod = null, IDictionary headers = null, string authorizationToken = null, string authorizationMethod = "Bearer"); + IGraphQLBatch CreateBatch(GraphQLOperationType operationType, string url, HttpMethod httpMethod = null, IDictionary headers = null, string authorizationToken = null, string authorizationMethod = "Bearer"); + /// + /// Generates a GraphQL batch + /// + /// The GraphQL Operation to execute + /// The operation name for this batch, null if no operation name to be set + /// The endpoint to request the GraphQL server from + /// The httpMethod to use requesting the GraphQL server + /// Headers to add to the request + /// The token used to authenticate with the GraphQL server + /// The method used for authentication + /// + IGraphQLBatch CreateBatch(GraphQLOperationType operationType, string operationName, string url, HttpMethod httpMethod = null, IDictionary headers = null, string authorizationToken = null, string authorizationMethod = "Bearer"); + /// /// Generates a query to a GraphQL server using a query generated by the , the specified URL and the HttpMethod Post /// @@ -235,5 +248,16 @@ public interface IGraphQLHttpClient /// The method used for authentication /// IGraphQLBatch CreateBatch(string url, HttpMethod httpMethod, string authorizationToken = null, string authorizationMethod = "Bearer"); + + /// + /// Generates a GraphQL batch using the specified server , the specified and the specified + /// + /// The operation name for the batch execution, can be null if no operation name to be set + /// The endpoint to request the GraphQL server from + /// The HttpMethod to use to communicate with the server, for example POST + /// The token used to authenticate with the GraphQL server + /// The method used for authentication + /// + IGraphQLBatch CreateBatch(string operationName, string url, HttpMethod httpMethod, string authorizationToken = null, string authorizationMethod = "Bearer"); } } diff --git a/src/SAHB.GraphQLClient/Internal/GraphQLQuery.cs b/src/SAHB.GraphQLClient/Internal/GraphQLQuery.cs index 053f2ad..8e984c2 100644 --- a/src/SAHB.GraphQLClient/Internal/GraphQLQuery.cs +++ b/src/SAHB.GraphQLClient/Internal/GraphQLQuery.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; +using System.Reflection; using System.Threading.Tasks; using SAHB.GraphQLClient.Deserialization; using SAHB.GraphQLClient.FieldBuilder; @@ -10,6 +11,7 @@ using SAHB.GraphQLClient.QueryGenerator; using SAHB.GraphQLClient.Result; using System.Threading; +using SAHB.GraphQLClient.QueryGenerator.Attributes; namespace SAHB.GraphQLClient.Internal { @@ -59,9 +61,13 @@ public GraphQLQuery(GraphQLOperationType operationType, IEnumerable(); + this.OperationName = operationNameAttribute?.OperationName; } private GraphQLOperationType OperationType { get; } + private string OperationName { get; } private IEnumerable SelectionSet { get; } /// @@ -84,7 +90,7 @@ public async Task> ExecuteDetailed(CancellationToken cancel private async Task> GetDataResult(CancellationToken cancellationToken) { // Generate query - var query = _queryGenerator.GenerateQuery(OperationType, SelectionSet, _filter, _arguments); + var query = _queryGenerator.GenerateQuery(OperationType, OperationName, SelectionSet, _filter, _arguments); // Get result var result = await _executor.ExecuteQuery( diff --git a/src/SAHB.GraphQLClient/QueryGenerator/Attributes/GraphQLOperationNameAttribute.cs b/src/SAHB.GraphQLClient/QueryGenerator/Attributes/GraphQLOperationNameAttribute.cs new file mode 100644 index 0000000..a8b898f --- /dev/null +++ b/src/SAHB.GraphQLClient/QueryGenerator/Attributes/GraphQLOperationNameAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace SAHB.GraphQLClient.QueryGenerator.Attributes +{ + [AttributeUsage(AttributeTargets.Class)] + public class GraphQLOperationNameAttribute : Attribute + { + /// + /// Initializes an attribute that describes the corresponding GraphQL operation name for the attributed class + /// + /// The operation name used in the GraphQL query + public GraphQLOperationNameAttribute(string operationName) + { + OperationName = operationName; + } + + public string OperationName { get; set; } + } +} diff --git a/src/SAHB.GraphQLClient/QueryGenerator/GraphQLQueryGeneratorFromFields.cs b/src/SAHB.GraphQLClient/QueryGenerator/GraphQLQueryGeneratorFromFields.cs index 9a7fbff..0419b74 100644 --- a/src/SAHB.GraphQLClient/QueryGenerator/GraphQLQueryGeneratorFromFields.cs +++ b/src/SAHB.GraphQLClient/QueryGenerator/GraphQLQueryGeneratorFromFields.cs @@ -17,21 +17,33 @@ namespace SAHB.GraphQLClient.QueryGenerator /// public class GraphQLQueryGeneratorFromFields : IGraphQLQueryGeneratorFromFields { + public string GenerateQuery(GraphQLOperationType operationType, IEnumerable selectionSet, + params GraphQLQueryArgument[] arguments) + { + return GenerateQuery(operationType, null, selectionSet, null, arguments);; + } + /// - public string GenerateQuery(GraphQLOperationType operationType, IEnumerable selectionSet, params GraphQLQueryArgument[] arguments) + public string GenerateQuery(GraphQLOperationType operationType, string operationName, IEnumerable selectionSet, params GraphQLQueryArgument[] arguments) + { + return GenerateQuery(operationType, operationName, selectionSet, null, arguments); + } + + public string GenerateQuery(GraphQLOperationType operationType, IEnumerable selectionSet, Func filter, + params GraphQLQueryArgument[] arguments) { - return GenerateQuery(operationType, selectionSet, null, arguments); + return GenerateQuery(operationType, null, selectionSet, filter, arguments); } /// - public string GenerateQuery(GraphQLOperationType operationType, IEnumerable selectionSet, Func filter, params GraphQLQueryArgument[] arguments) + public string GenerateQuery(GraphQLOperationType operationType, string operationName, IEnumerable selectionSet, Func filter, params GraphQLQueryArgument[] arguments) { switch (operationType) { case GraphQLOperationType.Query: case GraphQLOperationType.Mutation: case GraphQLOperationType.Subscription: - return GetQuery(operationType, selectionSet.ToList(), filter, arguments); + return GetQuery(operationType, operationName, selectionSet.ToList(), filter, arguments); } throw new NotImplementedException($"Operation {operationType} not implemented"); @@ -39,13 +51,13 @@ public string GenerateQuery(GraphQLOperationType operationType, IEnumerable - public string GetQuery(IEnumerable fields, params GraphQLQueryArgument[] arguments) => GenerateQuery(GraphQLOperationType.Query, fields, arguments); + public string GetQuery(IEnumerable fields, params GraphQLQueryArgument[] arguments) => GenerateQuery(GraphQLOperationType.Query, null, fields, arguments); [Obsolete("Please use GenerateQuery instead")] /// - public string GetMutation(IEnumerable fields, params GraphQLQueryArgument[] arguments) => GenerateQuery(GraphQLOperationType.Mutation, fields, arguments); + public string GetMutation(IEnumerable fields, params GraphQLQueryArgument[] arguments) => GenerateQuery(GraphQLOperationType.Mutation, null, fields, arguments); - private string GetQuery(GraphQLOperationType operationType, ICollection selectionSet, Func filter, params GraphQLQueryArgument[] queryArguments) + private string GetQuery(GraphQLOperationType operationType, string operationName, ICollection selectionSet, Func filter, params GraphQLQueryArgument[] queryArguments) { // Get arguments var readonlyArguments = GetArguments(selectionSet, filter, queryArguments); @@ -79,6 +91,7 @@ private string GetQuery(GraphQLOperationType operationType, ICollection arguments) { diff --git a/src/SAHB.GraphQLClient/QueryGenerator/IGraphQLQueryGeneratorFromFields.cs b/src/SAHB.GraphQLClient/QueryGenerator/IGraphQLQueryGeneratorFromFields.cs index a83fc80..7f84b14 100644 --- a/src/SAHB.GraphQLClient/QueryGenerator/IGraphQLQueryGeneratorFromFields.cs +++ b/src/SAHB.GraphQLClient/QueryGenerator/IGraphQLQueryGeneratorFromFields.cs @@ -37,6 +37,15 @@ public interface IGraphQLQueryGeneratorFromFields /// The generated query string GenerateQuery(GraphQLOperationType operationType, IEnumerable selectionSet, params GraphQLQueryArgument[] arguments); + /// + /// Builds a GraphQL query from the specified s and the s + /// + /// The GraphQL operation to generate the query from + /// The operation name of the query, can be null if no operation name needs to be set + /// The argument values which is inserted using a variable on specified arguments with the + /// The generated query + string GenerateQuery(GraphQLOperationType operationType, string operationName, IEnumerable selectionSet, params GraphQLQueryArgument[] arguments); + /// /// Builds a GraphQL query from the specified s and the s and the specified filter used to select the required fields /// @@ -45,5 +54,15 @@ public interface IGraphQLQueryGeneratorFromFields /// The filter for the fields. If a field is included which has subfields, but no subfields are included all subfields are included /// The generated query string GenerateQuery(GraphQLOperationType operationType, IEnumerable selectionSet, Func filter, params GraphQLQueryArgument[] arguments); + + /// + /// Builds a GraphQL query from the specified s and the s and the specified filter used to select the required fields + /// + /// The GraphQL operation to generate the query from + /// The operation name of the query, can be null if no operation name needs to be set + /// The argument values which is inserted using a variable on specified arguments with the + /// The filter for the fields. If a field is included which has subfields, but no subfields are included all subfields are included + /// The generated query + string GenerateQuery(GraphQLOperationType operationType, string operationName, IEnumerable selectionSet, Func filter, params GraphQLQueryArgument[] arguments); } }