Skip to content

Commit

Permalink
Fixed ability to override GraphQLRequestHandler<'Root>
Browse files Browse the repository at this point in the history
  • Loading branch information
xperiandri committed Sep 12, 2024
1 parent f42e3d7 commit 4155692
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 14 deletions.
19 changes: 13 additions & 6 deletions src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLRequestHandler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ open FsToolkit.ErrorHandling

open FSharp.Data.GraphQL.Server

type DefaultGraphQLRequestHandler<'Root> (
httpContextAccessor : IHttpContextAccessor,
options : IOptionsMonitor<GraphQLOptions<'Root>>,
logger : ILogger<DefaultGraphQLRequestHandler<'Root>>
) =
inherit GraphQLRequestHandler<'Root> (httpContextAccessor, options, logger)

/// Provides logic to parse and execute GraphQL request
type GraphQLRequestHandler<'Root> (
and [<AbstractClass>] GraphQLRequestHandler<'Root> (
httpContextAccessor : IHttpContextAccessor,
options : IOptionsMonitor<GraphQLOptions<'Root>>,
logger : ILogger<GraphQLRequestHandler<'Root>>
logger : ILogger
) =

let ctx = httpContextAccessor.HttpContext
Expand Down Expand Up @@ -213,10 +220,10 @@ type GraphQLRequestHandler<'Root> (
return! checkAnonymousFieldsOnly ctx
}

abstract ExecuteOperation<'Root> : Executor<'Root> -> ParsedGQLQueryRequestContent -> Task<IResult>
abstract ExecuteOperation<'Root> : executor:Executor<'Root> * content:ParsedGQLQueryRequestContent -> Task<IResult>

/// Execute the operation for given request
default _.ExecuteOperation<'Root> (executor: Executor<'Root>) content = task {
default _.ExecuteOperation<'Root> (executor: Executor<'Root>, content) = task {

let operationName = content.OperationName |> Skippable.filter (not << isNull) |> Skippable.toOption
let variables = content.Variables |> Skippable.filter (not << isNull) |> Skippable.toOption
Expand All @@ -241,12 +248,12 @@ type GraphQLRequestHandler<'Root> (
return (TypedResults.Ok response) :> IResult
}

member request.HandleAsync () : Task<Result<IResult, IResult>> = taskResult {
member handler.HandleAsync () : Task<Result<IResult, IResult>> = taskResult {
if ctx.RequestAborted.IsCancellationRequested then
return TypedResults.Empty
else
let executor = options.CurrentValue.SchemaExecutor
match! checkOperationType () with
| IntrospectionQuery optionalAstDocument -> return! executeIntrospectionQuery executor optionalAstDocument
| OperationQuery content -> return! request.ExecuteOperation executor content
| OperationQuery content -> return! handler.ExecuteOperation (executor, content)
}
143 changes: 135 additions & 8 deletions src/FSharp.Data.GraphQL.Server.AspNetCore/StartupExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ module ServiceCollectionExtensions =
/// </para>
/// </summary>
[<Extension; CompiledName "AddGraphQL">]
member internal services.AddGraphQL<'Root>
member internal services.AddGraphQL<'Root, 'Handler when 'Handler :> GraphQLRequestHandler<'Root> and 'Handler : not struct>
(
executorFactory : Func<IServiceProvider, Executor<'Root>>,
rootFactory : HttpContext -> 'Root,
Expand Down Expand Up @@ -84,7 +84,41 @@ module ServiceCollectionExtensions =
}
)
.AddHttpContextAccessor()
.AddScoped<GraphQLRequestHandler<'Root>>()
.AddScoped<GraphQLRequestHandler<'Root>, 'Handler>()

/// <summary>
/// Adds GraphQL options and services to the service collection.
/// <para>
/// It also adds converters to <see href="Microsoft.AspNetCore.Http.Json.JsonOptions" />
/// to support serialization of GraphQL responses.
/// </para>
/// </summary>
[<Extension; CompiledName "AddGraphQL">]
member internal services.AddGraphQL<'Root>
(
executorFactory : Func<IServiceProvider, Executor<'Root>>,
rootFactory : HttpContext -> 'Root,
[<Optional>] additionalConverters : JsonConverter seq,
[<Optional; DefaultParameterValue (GraphQLOptionsDefaults.WebSocketEndpoint)>] webSocketEndpointUrl : string,
[<Optional>] configure : Func<GraphQLOptions<'Root>, GraphQLOptions<'Root>>
) =
services.AddGraphQL<'Root, DefaultGraphQLRequestHandler<'Root>> (executorFactory, rootFactory, additionalConverters, webSocketEndpointUrl, configure)

/// <summary>
/// Adds GraphQL options and services to the service collection. Requires an executor instance to be provided.
/// <para>
/// It also adds converters to <see href="Microsoft.AspNetCore.Http.Json.JsonOptions" />
/// to support serialization of GraphQL responses.
/// </para>
/// </summary>
[<Extension; CompiledName "AddGraphQL">]
member services.AddGraphQL<'Root, 'Handler when 'Handler :> GraphQLRequestHandler<'Root> and 'Handler : not struct>
(
executor : Executor<'Root>,
rootFactory : HttpContext -> 'Root,
[<Optional>] additionalConverters : JsonConverter seq
) =
services.AddGraphQL<'Root, 'Handler> ((fun _ -> executor), rootFactory, additionalConverters, null, null)

/// <summary>
/// Adds GraphQL options and services to the service collection. Requires an executor instance to be provided.
Expand All @@ -100,7 +134,24 @@ module ServiceCollectionExtensions =
rootFactory : HttpContext -> 'Root,
[<Optional>] additionalConverters : JsonConverter seq
) =
services.AddGraphQL ((fun _ -> executor), rootFactory, additionalConverters, null, null)
services.AddGraphQL<'Root> ((fun _ -> executor), rootFactory, additionalConverters, null, null)

/// <summary>
/// Adds GraphQL options and services to the service collection. Requires an executor instance to be provided.
/// <para>
/// It also adds converters to <see href="Microsoft.AspNetCore.Http.Json.JsonOptions" />
/// to support serialization of GraphQL responses.
/// </para>
/// </summary>
[<Extension; CompiledName "AddGraphQL">]
member services.AddGraphQL<'Root, 'Handler when 'Handler :> GraphQLRequestHandler<'Root> and 'Handler : not struct>
(
executor : Executor<'Root>,
rootFactory : HttpContext -> 'Root,
webSocketEndpointUrl : string,
[<Optional>] additionalConverters : JsonConverter seq
) =
services.AddGraphQL<'Root, 'Handler> ((fun _ -> executor), rootFactory, additionalConverters, webSocketEndpointUrl, null)

/// <summary>
/// Adds GraphQL options and services to the service collection. Requires an executor instance to be provided.
Expand All @@ -117,7 +168,24 @@ module ServiceCollectionExtensions =
webSocketEndpointUrl : string,
[<Optional>] additionalConverters : JsonConverter seq
) =
services.AddGraphQL ((fun _ -> executor), rootFactory, additionalConverters, webSocketEndpointUrl, null)
services.AddGraphQL<'Root> ((fun _ -> executor), rootFactory, additionalConverters, webSocketEndpointUrl, null)

/// <summary>
/// Adds GraphQL options and services to the service collection. Requires an executor instance to be provided.
/// <para>
/// It also adds converters to <see href="Microsoft.AspNetCore.Http.Json.JsonOptions" />
/// to support serialization of GraphQL responses.
/// </para>
/// </summary>
[<Extension; CompiledName "AddGraphQL">]
member services.AddGraphQL<'Root, 'Handler when 'Handler :> GraphQLRequestHandler<'Root> and 'Handler : not struct>
(
executor : Executor<'Root>,
rootFactory : HttpContext -> 'Root,
configure : Func<GraphQLOptions<'Root>, GraphQLOptions<'Root>>,
[<Optional>] additionalConverters : JsonConverter seq
) =
services.AddGraphQL<'Root, 'Handler> ((fun _ -> executor), rootFactory, additionalConverters, null, configure)

/// <summary>
/// Adds GraphQL options and services to the service collection. Requires an executor instance to be provided.
Expand All @@ -134,7 +202,26 @@ module ServiceCollectionExtensions =
configure : Func<GraphQLOptions<'Root>, GraphQLOptions<'Root>>,
[<Optional>] additionalConverters : JsonConverter seq
) =
services.AddGraphQL ((fun _ -> executor), rootFactory, additionalConverters, null, configure)
services.AddGraphQL<'Root> ((fun _ -> executor), rootFactory, additionalConverters, null, configure)

/// <summary>
/// Adds GraphQL options and services to the service collection. It gets the executor from the service provider.
/// <para>
/// It also adds converters to <see href="Microsoft.AspNetCore.Http.Json.JsonOptions" />
/// to support serialization of GraphQL responses.
/// </para>
/// </summary>
/// <remarks>
/// The executor must be registered as a singleton service.
/// </remarks>
[<Extension; CompiledName "AddGraphQL">]
member services.AddGraphQL<'Root, 'Handler when 'Handler :> GraphQLRequestHandler<'Root> and 'Handler : not struct>
(
rootFactory : HttpContext -> 'Root,
[<Optional>] additionalConverters : JsonConverter seq
) =
let getExecutorService (sp : IServiceProvider) = sp.GetRequiredService<Executor<'Root>>()
services.AddGraphQL<'Root, 'Handler> (getExecutorService, rootFactory, additionalConverters, null, null)

/// <summary>
/// Adds GraphQL options and services to the service collection. It gets the executor from the service provider.
Expand All @@ -153,7 +240,27 @@ module ServiceCollectionExtensions =
[<Optional>] additionalConverters : JsonConverter seq
) =
let getExecutorService (sp : IServiceProvider) = sp.GetRequiredService<Executor<'Root>>()
services.AddGraphQL (getExecutorService, rootFactory, additionalConverters, null, null)
services.AddGraphQL<'Root> (getExecutorService, rootFactory, additionalConverters, null, null)

/// <summary>
/// Adds GraphQL options and services to the service collection. It gets the executor from the service provider.
/// <para>
/// It also adds converters to <see href="Microsoft.AspNetCore.Http.Json.JsonOptions" />
/// to support serialization of GraphQL responses.
/// </para>
/// </summary>
/// <remarks>
/// The executor must be registered as a singleton service.
/// </remarks>
[<Extension; CompiledName "AddGraphQL">]
member services.AddGraphQL<'Root, 'Handler when 'Handler :> GraphQLRequestHandler<'Root> and 'Handler : not struct>
(
rootFactory : HttpContext -> 'Root,
[<Optional; DefaultParameterValue (GraphQLOptionsDefaults.WebSocketEndpoint)>] webSocketEndpointUrl : string,
[<Optional>] additionalConverters : JsonConverter seq
) =
let getExecutorService (sp : IServiceProvider) = sp.GetRequiredService<Executor<'Root>>()
services.AddGraphQL<'Root, 'Handler> (getExecutorService, rootFactory, additionalConverters, webSocketEndpointUrl, null)

/// <summary>
/// Adds GraphQL options and services to the service collection. It gets the executor from the service provider.
Expand All @@ -173,7 +280,27 @@ module ServiceCollectionExtensions =
[<Optional>] additionalConverters : JsonConverter seq
) =
let getExecutorService (sp : IServiceProvider) = sp.GetRequiredService<Executor<'Root>>()
services.AddGraphQL (getExecutorService, rootFactory, additionalConverters, webSocketEndpointUrl, null)
services.AddGraphQL<'Root> (getExecutorService, rootFactory, additionalConverters, webSocketEndpointUrl, null)

/// <summary>
/// Adds GraphQL options and services to the service collection. It gets the executor from the service provider.
/// <para>
/// It also adds converters to <see href="Microsoft.AspNetCore.Http.Json.JsonOptions" />
/// to support serialization of GraphQL responses.
/// </para>
/// </summary>
/// <remarks>
/// The executor must be registered as a singleton service.
/// </remarks>
[<Extension; CompiledName "AddGraphQL">]
member services.AddGraphQL<'Root, 'Handler when 'Handler :> GraphQLRequestHandler<'Root> and 'Handler : not struct>
(
rootFactory : HttpContext -> 'Root,
configure : Func<GraphQLOptions<'Root>, GraphQLOptions<'Root>>,
[<Optional>] additionalConverters : JsonConverter seq
) =
let getExecutorService (sp : IServiceProvider) = sp.GetRequiredService<Executor<'Root>>()
services.AddGraphQL<'Root, 'Handler> (getExecutorService, rootFactory, additionalConverters, null, configure)

/// <summary>
/// Adds GraphQL options and services to the service collection. It gets the executor from the service provider.
Expand All @@ -193,7 +320,7 @@ module ServiceCollectionExtensions =
[<Optional>] additionalConverters : JsonConverter seq
) =
let getExecutorService (sp : IServiceProvider) = sp.GetRequiredService<Executor<'Root>>()
services.AddGraphQL (getExecutorService, rootFactory, additionalConverters, null, configure)
services.AddGraphQL<'Root> (getExecutorService, rootFactory, additionalConverters, null, configure)


[<AutoOpen; Extension>]
Expand Down

0 comments on commit 4155692

Please sign in to comment.