GraphQL.NET:如何使用IValidationRule

时间:2017-03-21 15:31:39

标签: graphql-dotnet

使用记录的RequiresAuthValidationRule实现;

https://github.com/graphql-dotnet/graphql-dotnet/blob/master/docs/learn.md

有一个示例可以检查某个字段是否具有某些权限,以及用户是否可以访问该字段。

_。匹配(fieldAst => {...})

看起来GraphQL引擎正在走树并在每个节点上调用IValidationRule.Validate(...)。

了解该领域的完整路径的最佳方式是什么。

星球大战的例子;
https://github.com/graphql-dotnet/graphql-dotnet/blob/master/docs/getting-started.md

即。我想知道当我在'name'节点时,该字段是人 - > friends->名称。

从我所看到的,我只能看到当前字段节点及其子节点,而不是其父节点。

2 个答案:

答案 0 :(得分:0)

根据您的需要,sed 's/[A-Za-z]*[0-9]*[.] 和/或ValidationContext.TypeInfo.GetLastType()应该是您所需要的。 ValidationContext.TypeInfo.GetParentType()有很多关于你在图表中的位置的上下文。

以下是ScalarLeafs验证规则的示例:

ValidationContext.TypeInfo

答案 1 :(得分:0)

为了提高效率,使用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));
    }
    ....

}

我按照我的方式构建操作和路径,并将任何更改事件发生。