Skip to content
This repository was archived by the owner on Feb 12, 2023. It is now read-only.

fix(Type): variable values and schema types translation #48

Merged
merged 7 commits into from
Mar 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ public JsonResult Post([FromBody] GraphiQLInput input)

private static dynamic GetVariables(GraphiQLInput input)
{
if (string.IsNullOrWhiteSpace(input.Variables))
var variables = input.Variables?.ToString();

if (string.IsNullOrEmpty(variables))
return new ExpandoObject();

return JsonConvert.DeserializeObject<ExpandoObject>(input.Variables);
return JsonConvert.DeserializeObject<ExpandoObject>(variables);
}
}
}
}
4 changes: 2 additions & 2 deletions examples/GraphQLCore.GraphiQLExample/Models/GraphiQLInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ public class GraphiQLInput
{
public string OperationName { get; set; }
public string Query { get; set; }
public string Variables { get; set; }
public dynamic Variables { get; set; }
}
}
}
8 changes: 4 additions & 4 deletions examples/GraphQLCore.GraphiQLExample/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
height: 100vh;
}
</style>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/graphiql/0.7.3/graphiql.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/graphiql/0.9.3/graphiql.css" />
<script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.0.1/react.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.0.1/react-dom.min.js"></script>
<script src="https://cdn.jsdelivr.net/graphiql/0.7.3/graphiql.js"></script>
<script src="//cdn.jsdelivr.net/react/15.4.2/react.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.jsdelivr.net/graphiql/0.9.3/graphiql.js"></script>
</head>
<body>
<div id="graphiql">Loading...</div>
Expand Down
14 changes: 6 additions & 8 deletions src/GraphQLCore/Execution/FieldScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using GraphQLCore.Type.Directives;
using Language.AST;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
Expand All @@ -12,7 +13,6 @@
using Type.Complex;
using Type.Translation;
using Utils;
using System;

public class FieldScope
{
Expand Down Expand Up @@ -76,11 +76,6 @@ public object GetArgumentValue(IEnumerable<GraphQLArgument> arguments, string ar
if (argument == null)
return null;

if (argument.Value.Kind == ASTNodeKind.Variable)
{
return this.variableResolver.GetValue((GraphQLVariable)argument.Value);
}

return type.GetFromAst(argument.Value, this.schemaRepository);
}

Expand Down Expand Up @@ -118,8 +113,11 @@ private object GetValueForArgument(IList<GraphQLArgument> arguments, ParameterEx
return this.CreateContextObject(e.Type);

return ReflectionUtilities.ChangeValueType(
this.GetArgumentValue(arguments, e.Name,
this.schemaRepository.GetSchemaInputTypeFor(e.Type)), e.Type);
this.GetArgumentValue(
arguments,
e.Name,
this.schemaRepository.GetSchemaInputTypeFor(e.Type)),
e.Type);
}

private bool IsContextType(ParameterExpression e)
Expand Down
25 changes: 22 additions & 3 deletions src/GraphQLCore/Execution/VariableResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace GraphQLCore.Execution
{
Expand Down Expand Up @@ -53,8 +54,8 @@ public object GetValue(string variableName)
object variableValue;
this.variables.TryGetValue(variableName, out variableValue);

if (variableValue != null)
return this.TranslatePerDefinition(variableValue, typeDefinition);
if (variableValue != null)
return this.TranslatePerDefinition(variableValue, typeDefinition);

if (typeDefinition is Type.GraphQLNonNullType)
throw new GraphQLException($"Type \"{typeDefinition.ToString()}\" is non-nullable and cannot be null.");
Expand All @@ -73,7 +74,15 @@ public object TranslatePerDefinition(object inputObject, GraphQLBaseType typeDef
return this.CreateObjectFromDynamic((GraphQLInputObjectType)typeDefinition, (ExpandoObject)inputObject);

if (typeDefinition is GraphQLList)
return this.CreateList((IEnumerable)inputObject, (GraphQLList)typeDefinition);
{
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think you could break this down to smaller methods?

if (inputObject == null)
return null;

if (ReflectionUtilities.IsCollection(inputObject.GetType()))
return this.CreateList((IEnumerable)inputObject, (GraphQLList)typeDefinition);

return this.CreateSingleValueList(inputObject, (GraphQLList)typeDefinition);
}

return inputObject;
}
Expand Down Expand Up @@ -109,6 +118,16 @@ private IEnumerable<object> CreateList(IEnumerable inputObject, GraphQLList type
yield return this.TranslatePerDefinition(item, typeDefinition.MemberType);
}

private IEnumerable CreateSingleValueList(object inputObject, GraphQLList typeDefinition)
{
var systemType = this.schemaRepository.GetInputSystemTypeFor(typeDefinition.MemberType);

var singleValue = this.TranslatePerDefinition(inputObject, typeDefinition.MemberType);
singleValue = ReflectionUtilities.ChangeValueType(singleValue, systemType);

yield return singleValue;
}

private GraphQLBaseType GetTypeDefinition(GraphQLType typeDefinition)
{
if (typeDefinition is GraphQLNamedType)
Expand Down
1 change: 1 addition & 0 deletions src/GraphQLCore/Language/AST/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public enum ASTNodeKind
FloatValue,
StringValue,
BooleanValue,
NullValue,
EnumValue,
ListValue,
ObjectValue,
Expand Down
13 changes: 13 additions & 0 deletions src/GraphQLCore/Language/AST/GraphQLNullValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace GraphQLCore.Language.AST
{
public class GraphQLNullValue : GraphQLValue
{
public override ASTNodeKind Kind
{
get
{
return ASTNodeKind.NullValue;
}
}
}
}
2 changes: 1 addition & 1 deletion src/GraphQLCore/Language/GraphQLAstVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ public virtual GraphQLListValue EndVisitListValue(GraphQLListValue node)
return node;
}

private ASTNode BeginVisitListValue(GraphQLListValue node)
public virtual GraphQLListValue BeginVisitListValue(GraphQLListValue node)
{
foreach (var value in node.Values)
this.BeginVisitNode(value);
Expand Down
15 changes: 13 additions & 2 deletions src/GraphQLCore/Language/ParserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ private GraphQLValue ParseBooleanValue(Token token)
};
}

private GraphQLValue ParseNullValue(Token token)
{
this.Advance();
return new GraphQLNullValue()
{
Location = this.GetLocation(token.Start)
};
}

private GraphQLValue ParseConstantValue()
{
return this.ParseValueLiteral(true);
Expand Down Expand Up @@ -615,11 +624,13 @@ private GraphQLValue ParseNameValue(bool isConstant)

if (token.Value.Equals("true") || token.Value.Equals("false"))
return this.ParseBooleanValue(token);
else if (token.Value != null && !token.Value.Equals("null"))
else if (token.Value.Equals("null"))
return this.ParseNullValue(token);
else if (token != null)
return this.ParseEnumValue(token);

throw new GraphQLSyntaxErrorException(
$"Unexpected {this.currentToken}", this.source, this.currentToken.Start);
$"Unexpected {this.currentToken}", this.source, this.currentToken.Start);
}

private GraphQLValue ParseObject(bool isConstant)
Expand Down
22 changes: 2 additions & 20 deletions src/GraphQLCore/Type/Complex/GraphQLFieldInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,9 @@ public abstract class GraphQLFieldInfo

public GraphQLBaseType GetGraphQLType(ISchemaRepository schemaRepository)
{
return this.GetGraphQLType(this.SystemType, schemaRepository);
return this.GetSchemaType(this.SystemType, schemaRepository);
}

protected abstract GraphQLBaseType GetSchemaType(Type type, ISchemaRepository schemaRepository);

private GraphQLBaseType GetGraphQLType(Type type, ISchemaRepository schemaRepository)
{
if (ReflectionUtilities.IsCollection(type))
{
return new GraphQLList(this.GetGraphQLType(
ReflectionUtilities.GetCollectionMemberType(type),
schemaRepository));
}

if (ReflectionUtilities.IsNullable(type))
return this.GetSchemaType(Nullable.GetUnderlyingType(type), schemaRepository);

if (ReflectionUtilities.IsValueType(type))
return new GraphQLNonNullType(this.GetSchemaType(type, schemaRepository));

return this.GetSchemaType(type, schemaRepository);
}
}
}
}
19 changes: 9 additions & 10 deletions src/GraphQLCore/Type/Complex/GraphQLInputObjectType`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Exceptions;
using Language.AST;
using System;
using System.Collections;
using System.Linq;
using System.Linq.Expressions;
using Translation;
Expand Down Expand Up @@ -32,7 +33,7 @@ public void Field<TProperty>(string fieldName, Expression<Func<T, TProperty>> ac
this.Fields.Add(fieldName, GraphQLInputObjectTypeFieldInfo.CreateAccessorFieldInfo(fieldName, accessor));
}

public override object GetFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
public override object GetValueFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
{
if (!(astValue is GraphQLObjectValue))
return null;
Expand All @@ -47,13 +48,7 @@ public override object GetFromAst(GraphQLValue astValue, ISchemaRepository schem
if (astField == null)
continue;

object value = this.GetValueFromField(schemaRepository, field.Value, astField);

if (value == null && astField.Value.Kind == ASTNodeKind.Variable)
{
value = schemaRepository.VariableResolver.GetValue((GraphQLVariable)astField.Value);
value = ReflectionUtilities.ChangeValueType(value, field.Value.SystemType);
}
var value = this.GetField(astField, field.Value, schemaRepository);

this.AssignValueToObjectField(result, field.Value, value);
}
Expand All @@ -66,10 +61,14 @@ private static GraphQLObjectField GetFieldFromAstObjectValue(GraphQLObjectValue
return objectAstValue.Fields.FirstOrDefault(e => e.Name.Value == fieldName);
}

private object GetField(GraphQLObjectField astField, GraphQLInputObjectTypeFieldInfo fieldInfo, ISchemaRepository schemaRepository)
{
return this.GetValueFromField(schemaRepository, fieldInfo, astField);
}

private void AssignValueToObjectField(T result, GraphQLInputObjectTypeFieldInfo field, object value)
{
if (ReflectionUtilities.IsCollection(field.SystemType))
value = ReflectionUtilities.ChangeToCollection(value, field.SystemType);
value = ReflectionUtilities.ChangeValueType(value, field.SystemType);

ReflectionUtilities.MakeSetterFromLambda(field.Lambda)
.DynamicInvoke(result, value);
Expand Down
4 changes: 2 additions & 2 deletions src/GraphQLCore/Type/Complex/GraphQLObjectType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
{
using Complex;
using Exceptions;
using System.Collections.Generic;
using System.Linq.Expressions;
using Execution;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

public abstract class GraphQLObjectType : GraphQLComplexType
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQLCore/Type/GraphQLEnumType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public GraphQLEnumType(string name, string description, Type enumType) : base(na

public Type SystemType { get; protected set; }

public override object GetFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
public override object GetValueFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
{
if (astValue.Kind != ASTNodeKind.EnumValue)
return null;
Expand Down
19 changes: 17 additions & 2 deletions src/GraphQLCore/Type/GraphQLInputType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
{
using Language.AST;
using Translation;
using Utils;

public abstract class GraphQLInputType : GraphQLBaseType
{
public override bool IsLeafType
Expand All @@ -16,6 +18,19 @@ public GraphQLInputType(string name, string description) : base(name, descriptio
{
}

public abstract object GetFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository);
public abstract object GetValueFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository);

public object GetFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
{
if (astValue.Kind == ASTNodeKind.Variable)
{
var value = schemaRepository.VariableResolver.GetValue((GraphQLVariable)astValue);
value = ReflectionUtilities.ChangeValueType(value, schemaRepository.GetInputSystemTypeFor(this));

return value;
}

return this.GetValueFromAst(astValue, schemaRepository);
}
}
}
}
33 changes: 21 additions & 12 deletions src/GraphQLCore/Type/GraphQLList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,40 @@ public GraphQLList(GraphQLBaseType memberType) : base(null, null)

public GraphQLBaseType MemberType { get; private set; }

public override object GetFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
public static IList CreateOutputList(GraphQLInputType inputType, ISchemaRepository schemaRepository)
{
if (astValue.Kind == ASTNodeKind.Variable)
return null;
IList output = (IList)Activator.CreateInstance(
ReflectionUtilities.CreateListTypeOf(
schemaRepository.GetInputSystemTypeFor(inputType)));

if (!(this.MemberType is GraphQLInputType))
return output;
}

public override object GetValueFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
{
if (!(this.MemberType is GraphQLInputType) || astValue.Kind == ASTNodeKind.NullValue)
return null;

var inputType = this.MemberType as GraphQLInputType;
var singleValue = inputType.GetFromAst(astValue, schemaRepository);
var output = CreateOutputList(inputType, schemaRepository);

IList output = (IList)Activator.CreateInstance(
ReflectionUtilities.CreateListTypeOf(
schemaRepository.GetInputSystemTypeFor(inputType)));

if (singleValue != null)
if (astValue.Kind != ASTNodeKind.ListValue)
{
output.Add(singleValue);
var value = inputType.GetFromAst(astValue, schemaRepository);
output.Add(value);
return output;
}

var list = ((GraphQLListValue)astValue).Values;

foreach (var item in list)
output.Add(inputType.GetFromAst(item, schemaRepository));
{
var value = inputType.GetFromAst(item, schemaRepository);
if (value == null && inputType is GraphQLNonNullType)
return null;

output.Add(value);
}

return output;
}
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQLCore/Type/GraphQLNonNullType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public GraphQLNonNullType(GraphQLBaseType nullableType) : base(null, null)

public GraphQLBaseType UnderlyingNullableType { get; private set; }

public override object GetFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
public override object GetValueFromAst(GraphQLValue astValue, ISchemaRepository schemaRepository)
{
if (this.UnderlyingNullableType is GraphQLInputType)
return ((GraphQLInputType)this.UnderlyingNullableType).GetFromAst(astValue, schemaRepository);
Expand Down
Loading