使用Hot Chocolate和.NET 6构建GraphQL应用 —— 创建Attribute中间件
需求
在部分接口添加一个机器人校验的功能
思路
读者们可以看下使用Hot Chocolate和.NET 6构建GraphQL应用(5) —— 实现Query过滤功能, 我们可以自定义创建一个类似的特性中间件来对接口进行管理. 添加了该特性的接口即可实现机器人校验功能.
实现
输入对象
/// 用户输入
public class RobotVerifyInput{
// todo fields
public string Verify { get; set; }
}
中间件实现
public class RobotVerifyMiddleware
{
public const string ParamName = "RobotVerify";
public FieldDelegate _next;
public RobotVerifyMiddleware(FieldDelegate next)
{
_next = next;
}
public async Task InvokeAsync(IMiddlewareContext context)
{
// 表示从上下文中获取传入的{ParamName}参数对象
var robotVerify = context.ArgumentValue<RobotVerifyInput>(ParamName);
// 这里如果前端不传会是空对象, 可以判空并抛出异常强制要求传参, 如果后续我知道怎么指定强制传参的话再更新
// 在ArgumentDefinition.Parameter.Attributes看注释是说可以指定是否可选, 但是Parameter是protected的
Console.WriteLine($"{robotVerify?.Verify}");
await _next(context);
}
}
定义特性
public class UseRobotVerifyAttribute: ObjectFieldDescriptorAttribute{
protected override void OnConfigure(IDescriptorContext context, IObjectFieldDescriptor descriptor, MemberInfo member)
{
// Allows to rewrite the type definition before the type is created but after all the users descriptor changes are applied.
// 在创建前扩展
descriptor.Extend().OnBeforeCreate((definition =>
{
// 向参数列表添加已经注册的GraphQLType
definition.Arguments.Add(new ArgumentDefinition(RobotVerifyMiddleware.ParamName,
"Robot Verify",
TypeReference.Create(context.TypeInspector.GetType(
typeof(RobotVerifyInput)),
TypeContext.Input)));
}));
// 使用中间件
descriptor.Use<RobotVerifyMiddleware>();
}
}
在接口上使用Attribute
public class Query
{
[UseRobotVerify]
public string NoAction()
{
return "NoAction";
}
}
这时候我们在接口上就可以看到效果了, 访问http://localhost:{port}/graphql 进入控制台