graphql fluent validation implementation with middleware.

This commit is contained in:
David Lebee
2021-02-03 20:28:56 -05:00
parent afb8b534bb
commit ffcfc60df1
19 changed files with 332 additions and 19 deletions
@@ -0,0 +1,11 @@
using PoweredSoft.CQRS.GraphQL.Abstractions;
using System.Collections.Generic;
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
{
public class GraphQLFieldError : IGraphQLFieldError
{
public string Field { get; set; }
public List<string> Errors { get; set; } = new List<string>();
}
}
@@ -0,0 +1,28 @@
using FluentValidation.Results;
using PoweredSoft.CQRS.GraphQL.Abstractions;
using System.Collections.Generic;
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
{
public class GraphQLFluentValidationResult : IGraphQLValidationResult
{
public bool IsValid => Errors.Count == 0;
public List<IGraphQLFieldError> Errors { get; } = new List<IGraphQLFieldError>();
public static GraphQLFluentValidationResult From(ValidationResult result)
{
var model = new GraphQLFluentValidationResult();
foreach (var error in result.Errors)
{
var fieldError = new GraphQLFieldError
{
Field = error.PropertyName
};
fieldError.Errors.Add(error.ErrorMessage);
model.Errors.Add(fieldError);
}
return model;
}
}
}
@@ -0,0 +1,47 @@
using FluentValidation;
using PoweredSoft.CQRS.GraphQL.Abstractions;
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
{
public class GraphQLFluentValidationService : IGraphQLValidationService
{
private readonly IServiceProvider serviceProvider;
public GraphQLFluentValidationService(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public async Task<IGraphQLValidationResult> ValidateAsync<T>(T subject, CancellationToken cancellationToken = default)
{
var validationService = serviceProvider.GetService(typeof(IValidator<T>)) as IValidator<T>;
if (validationService == null)
return new GraphQLValidResult();
var result = await validationService.ValidateAsync(subject, cancellationToken);
if (!result.IsValid)
return GraphQLFluentValidationResult.From(result);
return new GraphQLValidResult();
}
public async Task<IGraphQLValidationResult> ValidateObjectAsync(object subject, CancellationToken cancellationToken = default)
{
var validatorType = typeof(IValidator<>).MakeGenericType(subject.GetType());
var validationService = serviceProvider.GetService(validatorType) as IValidator;
if (validationService == null)
return new GraphQLValidResult();
var result = await validationService.ValidateAsync(new ValidationContext<object>(subject), cancellationToken);
if (!result.IsValid)
return GraphQLFluentValidationResult.From(result);
return new GraphQLValidResult();
}
}
}
@@ -0,0 +1,11 @@
using PoweredSoft.CQRS.GraphQL.Abstractions;
using System.Collections.Generic;
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
{
public class GraphQLValidResult : IGraphQLValidationResult
{
public bool IsValid => true;
public List<IGraphQLFieldError> Errors { get; } = new List<IGraphQLFieldError>();
}
}
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation" Version="9.5.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.Abstractions\PoweredSoft.CQRS.GraphQL.Abstractions.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using PoweredSoft.CQRS.GraphQL.Abstractions;
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddPoweredSoftGraphQLFluentValidation(this IServiceCollection services)
{
services.AddTransient<IGraphQLValidationService, GraphQLFluentValidationService>();
return services;
}
}
}