使用记录在案的RequiresAuthValidationRule实现;
https://github.com/graphql-dotnet/graphql-dotnet/blob/master/docs/learn.md
这里有一个检查字段是否具有特定权限以及用户是否可以访问该字段的示例。
_.Match(fieldAst =>{...})
看起来GraphQL引擎正在遍历一棵树并调用IValidationRule.Validate(...)在每个节点上。
了解字段的完整路径的最佳方法是什么。
星球大战的例子;
https://github.com/graphql-dotnet/graphql-dotnet/blob/master/docs/getting-started.md
即,当我在'name‘节点时,我想知道该字段是human->friends->name。
从我所看到的情况来看,我只能看到当前字段节点及其子节点,而不能看到它的父节点。
发布于 2017-03-22 02:17:15
根据您的需要,ValidationContext.TypeInfo.GetLastType()和/或ValidationContext.TypeInfo.GetParentType()应该是您所需要的。对于你在图中所处的位置,ValidationContext.TypeInfo有很多上下文。
下面是一个来自ScalarLeafs验证规则的示例:
public class ScalarLeafs : IValidationRule
{
public INodeVisitor Validate(ValidationContext context)
{
return new EnterLeaveListener(_ =>
{
_.Match<Field>(f => Field(context.TypeInfo.GetLastType(), f, context));
});
}
private void Field(IGraphType type, Field field, ValidationContext context)
{
...
}
}发布于 2017-03-24 23:12:18
为了提高效率,在Joe McBride的提示下,我选择基于GraphQL-dotnet EnterLeaveListener源代码创建自己的MyEnterLeaveListener。
public class EnterLeaveListenerState
{
public OperationType OperationType { get; private set; }
public string CurrentFieldPath { get; private set; }
}
public class MyEnterLeaveListener : INodeVisitor, IEventSource<IEnterLeaveListenerEventSink>
{
....
public void Enter(INode node)
{
var isField = TypeHelper<Field>.IsType(node.GetType());
var isOperation = TypeHelper<Operation>.IsType(node.GetType());
if (isOperation)
{
var operation = node as Operation;
OperationType = operation.OperationType;
RunningPath.Clear();
FireEnterLeaveListenerState(new EnterLeaveListenerState(OperationType, CurrentFieldPath));
}
if (isField)
{
var field = node as Field;
var next = CurrentFieldPath + "/" + field.Name;
RunningPath.Push(next);
FireEnterLeaveListenerState(new EnterLeaveListenerState(OperationType, CurrentFieldPath));
}
_listeners
.Where(l => l.Enter != null && l.Matches(node))
.Apply(l => l.Enter(node));
}
public void Leave(INode node)
{
var isField = TypeHelper<Field>.IsType(node.GetType());
if (isField)
{
var field = node as Field;
RunningPath.Pop();
FireEnterLeaveListenerState(new EnterLeaveListenerState(OperationType, CurrentFieldPath));
}
_listeners
.Where(l => l.Leave != null && l.Matches(node))
.Apply(l => l.Leave(node));
}
....
}我边走边构建操作和路径,并对任何更改进行事件处理。
https://stackoverflow.com/questions/42931516
复制相似问题