- Fix issue where
FieldNamerwas not being consistently used. Thanks @AnderssonPeter - Make sure we include inner exceptions on errors. Thanks @AnderssonPeter
- Added string and long parsing for DateTime and DateTimeOffset. Thanks @GravlLift
- As per GraphQL spec commas are optional (previously EntityGraphQL expected them in field/mutation arguments)
Breaking changes
- errors property on query result should not be present on the response if there are no errors per the graphQL specification.
- Fix bug with using
WithService()when you require the schema context service again to create a link between services
- When using services other than the schema context in fields (that return a single object not a Enumerable) the methods/services are no longer executed multiple times. (issue #36). Notes below
- When a string matches a date time it will be converted to a
DateTimeobject. Useful when using theArgumentHelper.EntityQueryfor advanced filtering. Regex matches"yyyy-MM-dd HH:mm:ss.fffffffzzz","yyyy-MM-dd HH:mm:ss","yyyy-MM-dd"with the separator between date and time being eitherorT EntityQueryCompiler(used inArgumentHelper.EntityQuery) supports EnumsfieldNamerused in mutations too
Breaking changes
- Cleaning up the API. The optional
isNullableargument is removed from theAddField()methods. UseIsNullable(bool)method on theFieldclass or the[GraphQLNotNull]attribute. - Cleaning up the API.
fieldNamerargument removed from methods inSchemaProviderandSchemaType. Pass in afieldNamerfunc to the constructor ofSchemaProviderwhich will be used when it is auto creating fields. If you pass it in viaSchemaBuilder.FromObjectit will set it on theSchemaProvidercreated.
If you build a field like so
schema.AddField("myField", ctx => WithService((IMyService srv) => srv.DoSomething(ctx)));
// Register the service with DI somewhere
public class MyService: IMyService {
public SomeObject DoSomething(Context ctx)
{
// do something
return data;
}
}With a query like
{
myField { field1 field 2 }
}We use to build an expression like so
srv.DoSomething(ctx) == null ? null : new {
field1 = srv.DoSomething(ctx).field1,
field2 = srv.DoSomething(ctx).field2
}We now wrap this in a method call that only calls DoSomething(ctx) a single time Which looks like this
(ctx, srv) => NullCheckWrapper(srv.DoSomething(ctx), parameterValues, selection); // simplifying here
// Again a simified example of what NullCheckWrapper does
public object NullCheckWrapper(Expression<Func<Context, IMyService>> baseValue, object[] values, LambdaExpression selection)
{
// null check
if (baseValue == null)
return null;
// build the select on the object
var result = selection.Compile().DynamicInvoke(baseValue);
}This works with services used deeper inthe graph too. Example
schema.Type<Person>().AddField("complexField", (person) => DoSomething(person.Id));GraphQL
{
people {
complexField {
field1
field1
}
}
}The wrapped expression looks like this
(ctx, srv) => ctx.People.Select(person => new {
complexField = NullCheckWrapper(srv.DoSomething(person.Id), parameterValues, selection); // simplifying here
})This has been tested with EF Core and works well.
- You can now secure whole types in the schema. Add the
[GraphQLAuthorize("claim-name")]to the class or useschema.AddType(...).RequiresAllClaims("some-claim"),schema.AddType(...).RequiresAnyClaim("some-claim") - Add
GetField(Expression<Func<TBaseType, object>>)overload - operation name is optional for a
queryoperation as per GraphQL spec if it is the only operation in the request - Breaking - removed the
authorizeClaimsargument fromAddField(). Please usefield.RequiresAllClaims("some-claim"),field.RequiresAnyClaim("some-claim")
- Change - descriptions generated for a
.graphqlschema file now use the multiple line triple-quote""" - Fix issue where an
WithService()expression is wrapped in aUnaryExpressionand we fail to get the lambda
- Expose a
SchemaProvider.ExecuteQueryAsync() - Fix #53 support mutations with no arguments
- With the above fix the context and/or the mutation arguments parameters are optional in your mutation method
- the parameters in the mutation methods are no longer required to follow a position
SchemaProvider.AddCustomScalarType()is deprecated, useAddScalarType- Directvies are now included in schema introspection
- Fix #52 - sometimes incorrect types generated for schema intropection or the GraphQL schema file format
- Refactor type information held in the schema. This mean return types etc are evaluated at schema creation time not execution. If you add a field that requires a type as an Arg ument or return type, that type must already be in the schema
- You can now provide a field namer function to name the generated fields when using
SchemaBuilder.FromObject(),ISchemaType.AddAllFields()orSchemaProvider.PopulateFromContext()
Breaking changes
- The class that represents the mutation arguments must be marked with the
MutationArgumentsAttributeeither at the class level or the parameter SchemaProvidernow adds a defaultDatescalar type in the schema that maps to/from the C#DateTimeclass. If you were previously adding that you'll get an error on type existing. UseSchemaProvider.RemoveType<DateTime>()to remove it and add it with a different name- Type mapping information (
AddTypeMapping()) are evaluated at schema creation time. You may need to add mappings before creating the rest of your schema
- Removed the empty
IMutationArgumentsin favor for aMutationArgumentsAttributeon the parameter or the class
- Support async mutation methods
- Add model validation for mutation arguments. See updated readme
- Fix issue with services not correctly being included when the field is used in a fragment
- Add support for directives. Supported by default are
@include(if: Boolean!)and@skip(if: Boolean!). You can add your own that make changes to the expression pre-execution - Added syntax support for subscription queries (they compile/no error but do not execute or work)
- Removed support for older syntax of complex queries that is not GQL standard
- Refactored
GraphQLVistorand friends to make it easier to follow what is happening (I hope). See CONTRIBUTING.md for some notes - From my testing the compiling and expression building is 15-20% faster than before (still network and or the DB calls are the largest)
- Allow
enumvalues in the query schema (e.g. as an argument) - Ignore static properties & fields on the object passed to
SchemaBuilder.FromObject- they were not supported and threw errors anyway
- Name all
ParameterExpressions as EF 3.1 expects a name (can throw an error)
- Fix claims check when required claims are empty
- Fix error message state which claims are required for the given access error
- Sorry about the quick turn around
- Breaking changes
- Using DI inspired design now instead of the
TArg - Use
WithServicehelper to let EntityGraphQL know which services you require e.g. in anAddFielduse(db, p) => WithService<IUserProvider>(users => users.Load(p.id)) - For mutations just add the services as arguments (at the end) as you typically do in dotnet
schema.ExecuteQuery()takes anIServiceProviderwhich it uses to look up required services likeIUserProviderabove
- Using DI inspired design now instead of the
- Breaking changes
- Trying to clean up the interface for careting a schema and allowing an easier way to get services in mutations and field selections
- Rename
MappedSchemaProvidertoSchemaProvider - Remove extension
object.QueryObject()and require a more specific call toSchmeaProvider.ExecuteQuery() SchmeaProvider.ExecuteQuery()takes aTArgtype which is an argument that will be passed to all field selections and mutation methods. This replacesmutationArgsinobject.QueryObject()and lets both mutations and field selections access other services non-statically (e.g. viaTArgbeing anIServiceProvider). See updated readme and demo projectSchemaProvideris now create usingSchemaBuilder.Create<TContext, TArg>()orSchemaBuilder.Create<TContext>()giving you a short cut for not providing aTArgSchemaBuilder.FromObject<TContext, TArg>()now takes second type argument for theTArgvalue. AlsoSchemaBuilder.FromObject<TContext>()shortcut
- Fix bug where EntityQuery arguments were being cached in the schema
- Add
ContextIdto the ignored list inSchemaBuilderfor EF 3.1
- Clean up
LinqExtensions, removing the overloads that takeLambdaExpressions. Use.AsQueryable().Where(someExpressionVar)instead. It works better with EF and other LinqProviders.
- Breaking change - Multiple
[GraphQLAuthorize]mean all polcies are required and supplying multiple in a single[GraphQLAuthorize]mean any - Do not generate an empty mutation type if there are no mutations
- Fix query introspection to output mapped types correctly
- Support multiple queries in a request with the operation name of which one to run - e.g. how GraphiQL handles multiple queries
- Update error messages
- Clean up some APIs -
SchemaType.AddAllFields(),Field.RequiresAllClaims(),Field.RequiresAnyClaim()
- Initial support for Authorization and Security in the schema - see updated readme and provide feedback
- Support
fragmentstatements in other positions in the query
- Fix error with
EntityQueryType<>as a field argument not being defined as aStringin introspection
- Fix issue introduced in 0.28 when using the
RequiredField<>type
- Only convert a string matching a
Guidwhen the arg type is aGuidorGuid?
- Fix issue where a non-required EntityQueryType Filter throw an error if it wasn't supplied
- Better support mutations that return an object, not a list
- Introspection query
__type(name: "")now correctly returns an object not an array [Description("")]attributes onenumfields are now read into the schema- Fix issue where introspection query would have dupelicate types for enum types
ISchemaType.AddAllFieldsrequires a schema as it can add newly discovered types to that schemaISchemaType.AddAllFieldsby default adds newenumtypes to the schema if found as a field typeISchemaType.AddAllFieldscan (off by default) add new complex types to the schema if found as a field typeSchema.Type<TType>()now searches byTTypenottypeof(TType).Name. Allowing you to add a type with a different name but still get the typedSchemaType<T>back
- Add the ability to add enum types to the schema
- The auto schema builder now adds enum types it finds to the schema by default
- Enum values are referenced by the string value, if using JSON.NET you will want to use
[JsonConverter(typeof(StringEnumConverter))]
- Add
GraphQLNotNullAttributeto mark fields as not nullable in the graphql schema - By default when generating a
.schemafileIEnumerable<T>will generate the element type as not nullable. E.g.[T!]. UseGraphQLElementTypeNullableAttributeto mark it that the list can contain null items - Support mapping
decimaltonumber - Better support for defining nullable or non-nullable types
- Allow adding a mapping type to a type that already exists in the schema. E.g. you might add an input type
Pointand want to map the dotnet typePointto it.
- fix issue with required type in an array e.g.
[ID!]
- fix issue with generated required types
- Output fields as required in .graphql schemas
- You can now specify if a field is ignored for queries, mutations or both (if you're sharing DTOs/objects)
- Don't output the meta information of the schema in the schema definition
- Prevent duplicate scalar types in schema generation
- Fix issue where
mutationkeyword could not have any white space before it
- Change, make ENUMs a
Inttype as dotnet serialises them like that - Fix input types missing for the SDL schema generated
- Fix issue where mutation args has repeating
ofTypedata in introspection - Fix issue where InputTypes would be duplicated in introspection query results
- Fix issue where
ToList()was being called deep in expressions causing issues with EF
- Add the ability to add custom scalar types to the schema
- Fix a bug where introspection queries were in correct if you have a List/Array in your mutation type
- Fix a bug where mutation arg objects retained values from previous mutation - i.e if the next call to that mutation didn't provide some optional arguments
QueryObject()callsToList()on any lists so if you are using something like EF all queries will be evaluated onQueryObject(), not just the ones that return a single object (as they callFirstOrDefault()). This is more consistent, the result contains all your data (regardless of underlying ORM or not) and not a miz of evaluated and non-evaluated.- Add
RemoveTypeAndAllFields()onMappedSchemaProviderto more easily clean up a schema that was auto created bySchemaBuilder.FromObject<T>()
- Fix case matching of arguments in mutations. EntityGraphQL defaults to turning dotnet
UpperCaseFieldsAndPropertiestocamelCaseFieldsAndPropertiesas this was the intention with the change in 0.18.0 - Enum values are as defined. E.g. if you have an enum
Meteryou can use"Meter"not"meter"
- map Int16 and UInt16 to Int
- Fix issue where argument names were not case sensitive (the Breaking change introduced in 0.18)
- Fix
kindin schema introspection query to not have!
- Update dependences (JSON.NET)
- Fix some small casing issues
- Support for schema introspection. Top two fields (
__schemaand__type(name: String!)) are implemented. There are some things missing where we currently don't support the feature (directives). GraphiQL introspection query executes and you can naviagte the example. Big thanks to @JTravis76 for starting the work. - Implement #18 default argument values in GQL operations
mutation MyMutation($arg: String = "hey defaults") { ... } - Breaking change - If you purely use
SchemaBuilder.FromObject()it now creates all field nameslowerCaseCameland type namesUpperCamelCaselike the GraphQL defaults. Also since GraphQL is case sensitive I have enforced that. You may need to update some queries to match casing
- Add the option to have other parameters passed into a mutation method. Very useful for IServiceProvider or other services your mutations require
- Fix issue where duplicate fields (say from a query and a fragment) would cause an error
- Bring inner exception details up
- Fix issue where fields that require arguments fail (See Paging example in Demo)
- Add support for full queries on a mutation result. See readme for more details (you return an Expression)
- Initial support for GraphQL fragments. fix #2
- Fix issues with using field arguments deeper in the graph schema
- Add support for
operationNamein theGraphQLRequest - Add support for graphql comments
- Add GraphiQL web interface to the demo app
- Add
GraphQLIgnoreattribute to ignore a field on a Type for the automatic schema builder - fix bug where it would sometimes try to give an
UInt64to an argument that required anInt32 - (beta) Add
dotnet gqlcommand to generate a schema from your current DBContext. See readme for more info
- Add
WhereWhen()to the extension helpers
- Fix bug in handling converting a string into an enum
- Fix issue looking up types internally when working with anonymous types
- Fix issue with incorrectly checking for generic types
- Fix issue with array types in the dynamically generated type for lambdas
- Fix issue where the generated GraphQL schema had the incorrect type for arrays (e.g. double[])
- Fix issue with
SchemaBuilder.FromObjectbuilding invalid types from arrays.
- Fix an issue where it would generate an invalid field name if we couldn't singularize the name
- Move the query results into a
QueryResultclass so it is easier to work with
- Fix #11 - failure to use
RequiredFieldwith types likeuint- it would try to initialise it with anint
- Remove old code that supported multiple fields with the same name and different arguments. GrpahQL doesn't support that and it caused a bug where it would sometimes not find the field you want. You can implment optional arguments and build a complex field like
schemaProvider.AddField("myField", new {name = (string)null, id = (Guid?)null}, (db, param) => param.id.HasValue ? db.MyEntities.Where(l => l.Id == param.id).FirstOrDefault() : db.MyEntities.Where(l => l.Name == param.name).FirstOrDefault(), "Returns an Entity object by ID or a match on the name argument");
- Allow user to supply a type mapping for the generated GraphQL schema
- Fix an issue where we would some time identify a type as IEnumerable when it shouldn't have been
- Allow
ReplaceFieldon a sub type
- Convert enums correctly
- Fix SchemaGenerator to support arrays better
- Support turning
QueryRequestvariables from JSON objects into their requied objects
- Bring back
ReplaceFieldas technically GraphQL doesn't support overloading, so if you're using tools like Apollo etc to generate code you need to only have unique fields - Added
GetGraphQLSchemaon the schema to return a.graphqlschema file for input into tools like Apollo codegen - Add the option to add descriptions to Mutations
- Fix issue where operation name with no arguments failed
- Breaking change: Strings are now defined by double quotes
"to fit in with GraphQL better - Added support to use a LINQ-style language as a argument in GraphQL. E.g the following GQL field,
{ users(filter: "active = true and age > 20") { id name } }can be defined withschema.AddField("users", new {filter = EntityQuery<User>()}, (ctx, p) => ctx.Users.Where(p.filter), "Return filtered users"). Letting you write that filter using any fields defined on theUserobject - Add
null/emptyconstant for checking for null in EQL
- Fix bug converting Int values to double? values
- Support field "overloads" - fields with same name and different arguments.
- Renamed package EntityGraphQL to emphasizes that it implements GraphQL
- Fix issue with arrays and objects in variables parameter on the request
- Better error messages when GraphQL arguments can't be mapped to an object
- Validate required variables in operations are supplied in the variables dictionary
- Fix potential issue with selecting sub object graphs
- Change the errors to appear in
errorskey along sidedatakey as per GraphQL - Fix an issue when selecting fields from a mutation result
- Support selecting an object that may be null
{ person {name} }personwill be null if it does not exist
- Parameter types can be optional (no
!)
- Fix type issues with mutation args
- Change auto entity call with
id:(e.g.{ entity(id: 13)}) to call theFirst()method last - Fix issue with selecting a one-to-one relation in a query
- Fix a issue where schema and metrhod provider were not being passed down in
QueryObject
- Add initial support for Mutations
,between fields is optional like in GraphQL- Support
__typenamemetadata
Moved EntityQueryLanguage.DataApinamespace toEntityQueryLanguage.GraphQLto better communicate that its intent is to support- Add support GraphQL arguments in fields. See updated readme
- By default
SchemaBuilder.FromObject<TType>()generates a non-pural field for any type with a publicIdproperty, with the argument name ofid. E.g. A fieldpeoplethat returns aIEnumerable<Person>will result in aperson(id)field - Move results to field
datain the resulting object to match GraphQL - Support the
querykeyword for graphql
- Added support for complex nested queries when using the
EFRelationshipHandler - Fix type caching issue causing exception on changing a sub query