Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix graphql api with parameters #15529

Merged
merged 24 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
92a21cd
fix_graphql_api_with_parameters
hyzx86 Mar 16, 2024
eb63194
fix graphql query
hyzx86 Mar 17, 2024
04d062a
Update src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Json/GraphQLN…
hyzx86 Mar 18, 2024
ec62d6c
Update src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Json/GraphQLN…
hyzx86 Mar 18, 2024
580659f
fix code style
hyzx86 Mar 18, 2024
99592bd
add contentSerializerJsonOptions to graphql serializer
hyzx86 Mar 18, 2024
fdb3efb
fix option action
hyzx86 Mar 18, 2024
f11752c
update options
hyzx86 Mar 18, 2024
9dbe55d
remove var bodyText
hyzx86 Mar 18, 2024
fe6bbb6
restore method name
hyzx86 Mar 18, 2024
34877f5
Merge branch 'main' into fix_graphql_api_with_parameters
hyzx86 Mar 18, 2024
1571457
update code
Mar 19, 2024
8d4a0e5
Update src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Json/GraphQLN…
hyzx86 Mar 19, 2024
e1969c1
Update code format
Mar 19, 2024
aad8219
Merge branch 'fix_graphql_api_with_parameters' of https://github.com/…
Mar 19, 2024
caeb071
update doc
Mar 19, 2024
1e07566
update
Mar 19, 2024
d802d82
Update GraphQLNamedQueryRequestJsonConverter.cs
MikeAlhayek Mar 19, 2024
48db275
Update GraphQLNamedQueryRequestJsonConverter.cs
MikeAlhayek Mar 19, 2024
3c64803
clear code
Mar 19, 2024
cf2d07c
Merge remote-tracking branch 'origin/main' into fix_graphql_api_with_…
Mar 19, 2024
502396c
Merge branch 'main' into fix_graphql_api_with_parameters
hyzx86 Mar 21, 2024
7cdfe70
Merge branch 'main' into fix_graphql_api_with_parameters
hyzx86 Mar 21, 2024
bab5e9c
Merge branch 'main' into fix_graphql_api_with_parameters
hyzx86 Mar 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Net;
using System.Net.Mime;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using GraphQL;
using GraphQL.Execution;
Expand All @@ -28,6 +27,7 @@ namespace OrchardCore.Apis.GraphQL
public class GraphQLMiddleware : IMiddleware
{
private readonly GraphQLSettings _settings;
private readonly IGraphQLTextSerializer _graphQLTextSerializer;
private readonly IGraphQLSerializer _serializer;
private readonly IDocumentExecuter _executer;
internal static readonly Encoding _utf8Encoding = new UTF8Encoding(false);
Expand All @@ -37,11 +37,13 @@ public class GraphQLMiddleware : IMiddleware
public GraphQLMiddleware(
IOptions<GraphQLSettings> settingsOption,
IDocumentExecuter executer,
IGraphQLSerializer serializer)
IGraphQLSerializer serializer,
IGraphQLTextSerializer graphQLTextSerializer)
{
_settings = settingsOption.Value;
_executer = executer;
_serializer = serializer;
_graphQLTextSerializer = graphQLTextSerializer;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
Expand Down Expand Up @@ -89,19 +91,17 @@ private async Task ExecuteAsync(HttpContext context)

if (mediaType.IsSubsetOf(_jsonMediaType) || mediaType.IsSubsetOf(_graphQlMediaType))
{

using var sr = new StreamReader(context.Request.Body);
if (mediaType.IsSubsetOf(_graphQlMediaType))
{
using var sr = new StreamReader(context.Request.Body);

request = new GraphQLNamedQueryRequest
{
Query = await sr.ReadToEndAsync()
};
}
else
{
request = await JsonSerializer.DeserializeAsync<GraphQLNamedQueryRequest>(context.Request.Body, JOptions.CamelCase);
request = _graphQLTextSerializer.Deserialize<GraphQLNamedQueryRequest>(await sr.ReadToEndAsync());
}
}
else
Expand Down Expand Up @@ -171,7 +171,7 @@ private async Task ExecuteAsync(HttpContext context)
await _serializer.WriteAsync(context.Response.Body, result);
}

private static GraphQLNamedQueryRequest CreateRequestFromQueryString(HttpContext context, bool validateQueryKey = false)
private GraphQLNamedQueryRequest CreateRequestFromQueryString(HttpContext context, bool validateQueryKey = false)
{
if (!context.Request.Query.ContainsKey("query"))
{
Expand All @@ -190,7 +190,7 @@ private static GraphQLNamedQueryRequest CreateRequestFromQueryString(HttpContext

if (context.Request.Query.ContainsKey("variables"))
{
request.Variables = JsonSerializer.Deserialize<Inputs>(context.Request.Query["variables"], JOptions.CamelCase);
request.Variables = _graphQLTextSerializer.Deserialize<Inputs>(context.Request.Query["variables"]);
}

if (context.Request.Query.ContainsKey("operationName"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using GraphQL;

namespace OrchardCore.Apis.GraphQL.Json;
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved

public class GraphQLNamedQueryRequestJsonConverter : JsonConverter<GraphQLNamedQueryRequest>
{
public static readonly GraphQLNamedQueryRequestJsonConverter Instance = new();

/// <summary>
/// Name for the operation name parameter.
/// See https://github.com/graphql/graphql-over-http/blob/master/spec/GraphQLOverHTTP.md#request-parameters
/// </summary>
private const string _operationNameKey = "operationName";

/// <summary>
/// Name for the query parameter.
/// See https://github.com/graphql/graphql-over-http/blob/master/spec/GraphQLOverHTTP.md#request-parameters
/// </summary>
private const string _queryKey = "query";

/// <summary>
/// Name for the variables parameter.
/// See https://github.com/graphql/graphql-over-http/blob/master/spec/GraphQLOverHTTP.md#request-parameters
/// </summary>
private const string _variablesKey = "variables";

/// <summary>
/// Name for the extensions parameter.
/// See https://github.com/graphql/graphql-over-http/blob/master/spec/GraphQLOverHTTP.md#request-parameters
/// </summary>
private const string _extensionsKey = "extensions";

hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
private const string _namedQueryKey = "namedQuery";

MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved

public override void Write(Utf8JsonWriter writer, GraphQLNamedQueryRequest value, JsonSerializerOptions options)
{
writer.WriteStartObject();
if (value.Query != null)
{
writer.WritePropertyName(_queryKey);
writer.WriteStringValue(value.Query);
}
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
if (value.OperationName != null)
{
writer.WritePropertyName(_operationNameKey);
writer.WriteStringValue(value.OperationName);
}
if (value.Variables != null)
{
writer.WritePropertyName(_variablesKey);
JsonSerializer.Serialize(writer, value.Variables, options);
}
if (value.Extensions != null)
{
writer.WritePropertyName(_extensionsKey);
JsonSerializer.Serialize(writer, value.Extensions, options);
}
if (value.NamedQuery != null)
{
writer.WritePropertyName(_namedQueryKey);
JsonSerializer.Serialize(writer, value.NamedQuery, options);
}
writer.WriteEndObject();
}

public override GraphQLNamedQueryRequest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
throw new JsonException();

var request = new GraphQLNamedQueryRequest();

while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
{
return request;
}

if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}

string key = reader.GetString()!;
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved

//unexpected end of data
MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved
if (!reader.Read())
throw new JsonException();

switch (key)
{
case _queryKey:
request.Query = reader.GetString()!;
break;
case _operationNameKey:
request.OperationName = reader.GetString()!;
break;
case _namedQueryKey:
request.NamedQuery = reader.GetString();
break;
case _variablesKey:
request.Variables = JsonSerializer.Deserialize<Inputs>(ref reader, options);
break;
case _extensionsKey:
request.Extensions = JsonSerializer.Deserialize<Inputs>(ref reader, options);
break;
default:
reader.Skip();
break;
}
}

//unexpected end of data
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
throw new JsonException();
}
}
18 changes: 17 additions & 1 deletion src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using OrchardCore.Apis.GraphQL.Json;
using OrchardCore.Apis.GraphQL.Services;
using OrchardCore.Apis.GraphQL.ValidationRules;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.Extensions;
using OrchardCore.Json;
using OrchardCore.Json.Extensions;
using OrchardCore.Modules;
using OrchardCore.Navigation;
using OrchardCore.Security.Permissions;
Expand Down Expand Up @@ -46,7 +50,19 @@ public override void ConfigureServices(IServiceCollection services)
services.AddScoped<IPermissionProvider, Permissions>();
services.AddTransient<INavigationProvider, AdminMenu>();
services.AddSingleton<GraphQLMiddleware>();
services.AddGraphQL(builder => builder.AddSystemTextJson());
services.Configure<ContentSerializerJsonOptionsConfiguration>(options =>
{

});

services.AddGraphQL(builder => builder.AddSystemTextJson((options, sp) =>
{
// Common types of converters are already configured in the assembly "GraphQL.SystemTextJson".
options.Converters.Add(GraphQLNamedQueryRequestJsonConverter.Instance);
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved

var contentSerializerJsonOptions = sp.GetRequiredService<IOptions<ContentSerializerJsonOptions>>().Value;
options.Merge(contentSerializerJsonOptions.SerializerOptions);
}));

services.AddOptions<GraphQLSettings>().Configure<IShellConfiguration>((c, configuration) =>
{
Expand Down
Loading