-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Read schema from SDL file. #118
Comments
To achieve this you have to convert SDL schema into the JSON metadata format. SDL schema can be simply read using |
Hi @Husqvik, This is for creating the server side models from a GraphQL Schema. Thanks |
Ok, I never thought about this usage. Here is a very rough idea how to convert SDL into the JSON format. I would almost bet there should be some one line helper to do so but I didn't find anything void Main()
{
var schema = Schema.For(File.ReadAllText(@"d:\schema.gql"));
schema.Initialize();
var generatorSchema =
new GraphQlSchema
{
QueryType = schema.Query is null ? null : new GraphQlRequestType { Name = schema.Query.Name },
MutationType = schema.Mutation is null ? null : new GraphQlRequestType { Name = schema.Mutation.Name },
SubscriptionType = schema.Subscription is null ? null : new GraphQlRequestType { Name = schema.Subscription.Name },
Directives =
schema.Directives?.Select(d =>
new GraphQlDirective
{
Name = d.Name,
Description = d.Description,
Locations = d.Locations.Select(l => Enum.Parse<GraphQlDirectiveLocation>(l.ToString())).ToList(),
Args = d.Arguments.Select(a => new GraphQlArgument { Name = a.Name, Description = a.Description, Type = GetGraphQlTypeFromClrType(a.Type), DefaultValue = a.DefaultValue }).ToList()
}).ToList(),
Types =
schema.AdditionalTypeInstances.Select(t =>
PopulateSchemaProperties(
new GraphQlType
{
Name = t.Name,
Description = t.Description,
},
t))
.Where(t => t is not null)
.ToList()
}
;
}
private static GraphQlType PopulateSchemaProperties(GraphQlType targetType, IGraphType sourceType)
{
switch (sourceType)
{
case EnumerationGraphType enumType:
targetType.Kind = GraphQlTypeKind.Enum;
targetType.EnumValues = enumType.Values.Select(v => new GraphQlEnumValue { Name = v.Name, Description = v.Description, DeprecationReason = v.DeprecationReason, IsDeprecated = !String.IsNullOrEmpty(v.DeprecationReason) }).ToList();
break;
case ObjectGraphType objectType:
targetType.Kind = GraphQlTypeKind.Object;
targetType.Fields = objectType.Fields.Select(f => new GraphQlField { Name = f.Name, Description = f.Description, DeprecationReason = f.DeprecationReason, IsDeprecated = !String.IsNullOrEmpty(f.DeprecationReason), Type = GetGraphQlType(f.ResolvedType) }).ToList();
//targetType.Interfaces = objectType.Interfaces.Select(i => i.); // TODO
break;
case InputObjectGraphType inputObjectType:
targetType.Kind = GraphQlTypeKind.InputObject;
targetType.InputFields = inputObjectType.Fields.Select(f => new GraphQlArgument { Name = f.Name, Description = f.Description, DefaultValue = f.DefaultValue, Type = GetGraphQlType(f.ResolvedType) }).ToList();
break;
case UnionGraphType unionType:
targetType.Kind = GraphQlTypeKind.Union;
targetType.PossibleTypes = unionType.PossibleTypes.Select(t => new GraphQlFieldType { Name = t.Name, Kind = GraphQlTypeKind.Object }).ToList();
break;
default:
targetType = null;
break;
}
return targetType;
}
private static GraphQlFieldType GetGraphQlTypeFromClrType(Type clrType)
{
if (clrType.IsGenericType && clrType.GetGenericTypeDefinition() == typeof(NonNullGraphType<>))
{
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.NonNull,
OfType = GetGraphQlTypeFromClrType(clrType.GetGenericArguments()[0])
};
}
if (clrType == typeof(BooleanGraphType))
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "Boolean"
};
if (clrType == typeof(FloatGraphType))
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "Float"
};
if (clrType == typeof(IdGraphType))
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "ID"
};
if (clrType == typeof(IntGraphType))
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "Int"
};
if (clrType == typeof(StringGraphType))
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "String"
};
return null;
}
private static GraphQlFieldType GetGraphQlType(IGraphType graphType)
{
switch (graphType)
{
case null: return null;
case NonNullGraphType nonNullType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.NonNull,
OfType = GetGraphQlType(nonNullType.ResolvedType)
};
case ListGraphType listType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.List,
OfType = GetGraphQlType(listType.ResolvedType)
};
case BooleanGraphType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "Boolean"
};
case FloatGraphType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "Float"
};
case IdGraphType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "ID"
};
case IntGraphType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "Int"
};
case StringGraphType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Scalar,
Name = "String"
};
case EnumerationGraphType enumType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Enum,
Name = enumType.Name
};
case ObjectGraphType objectType:
return
new GraphQlFieldType
{
Kind = GraphQlTypeKind.Object,
Name = objectType.Name
};
case InterfaceGraphType interfaceType:
return null;
case UnionGraphType unionType:
return null;
default:
throw new NotSupportedException($"type \"{graphType.GetType().FullName}\" mapping not supported");
}
return null;
} |
Hi @Husqvik Sorry for the late reply. Thanks a lot for dedicating time for writing these codes and much appreciated. It will definitely help me this time. Thanks |
@kiranchandran I'll need to think about it a bit more. I've never considered the usage to generate server data model so I need to go through C# server implementation features how they could match such generated class. The quick mapping I've tested is definitely not 100% right, so that would need some polishing too. |
Hi @Husqvik, Sure np. Thanks for your help and directions. |
As of now the code generation works only with the schema in JSON format.
Please provide a feature to load the SDL version too.
Meanwhile the feature is implemented, is there any workaround that I can apply by forking your code?
The text was updated successfully, but these errors were encountered: