Fixes:
- Prevent creation of invalid GraphQL schemas
- Exception is thrown if you try to add a field with arrguments to types that do not support arguments -
Enum&Inputtypes - Exception is thrown if you try to add fields to a
Scalartype - Exception is thrown on invalid type name
- Exception is thrown if you try to add a field with arrguments to types that do not support arguments -
- Schema builder now creates a valid GraphQL type name for generic types
- Enum types are now added to the schema as a typed
SchemaType<T>instance. Meaning you can fetch them usingschema.Type<MyEnum>() - Fix #181 - Schema builder now correctly respects
SchemaBuilderOptions.IgnoreTypes. Note it compares names against theType.FullName - Fix #182 - Add missing dotnet scalar type for
char. By default this is added as a schema scalar type namedCharso the client can decide how to handle it. Over the wire it will serialize as a string (default forSystem.Text.Json). You can change default scalars and mappings by using thePreBuildSchemaFromContextaction when adding your schema
services.AddGraphQLSchema<TContext>(options => {
options.PreBuildSchemaFromContext = schema =>
{
// remove and/or add scalar types or mappings here. e.g.
schema.AddScalarType<KeyValuePair<string, string>>("StringKeyValuePair", "Represents a pair of strings");
};
})
- When generating a field name for the field that takes an ID argument if the name generated matches the current field EntityGraphQL will add
ByIdto the field name. E.g. a propertyList<LinePath> Line { get; set; }previously would try to add theline: [LinePath]field with no arguments and another field namedline(id: ID!): LinePath. This causes an error. EntityGraphQL will name addlineById(id: ID!): LinePath. This is because the singularized version of "line" is "line". - In built field extensions now check if their extra types have already been added by using
Typeinstead of name allowing you to add them with your own descriptions etc. - Fix mutations without any mutation arguments would incorrectly include the query context as an argument
Fixes:
InputValuetype was being registered under wrong name #184
Fixes:
- Input Types were incorrectly getting field arguments added when using
AutoCreateFieldWithIdArguments
Breaking changes:
IDirectiveProcessornow requires aList<ExecutableDirectiveLocation> On { get; }to define where the directive is allowed to be used- Removed obsolete
ISchemaType.BaseType. UseISchemaType.BaseTypes - Cleaned up
SchemaTypeconstructors - usingGqlTypeEnuminstead of many boolean flags - Removed obsolete
SchemaProvider.AddInheritedType<TBaseType> - Removed the instance parameter from
AddMutationsFromand friends. Mutation "controllers" are now always created per request like an asp.net controller. Use DI for any constructor parameters - Renamed
ISchemaType.AddBaseTypetoISchemaType.Implementsto align with GraphQL languageISchemaType.Implementswill throw an exception if you try to implement a non-interface
- Renamed
ISchemaType.AddAllBaseTypestoISchemaType.ImplementAllBaseTypesto align with GraphQL language Create&FromObjectonSchemaBuildernow take option classes to configure the create of the schema through reflectionISchemaType.AddAllFieldsalso takes the option class to configure it's behaviourISchemaType.AddAllFieldsdefault behaviour now auto adds any complex types found really reflection the properties & fields and will add those to the schema
- Added new option when building a schema with
SchemaBuilder.FromObject-AutoCreateInterfaceTypes. Defaults tofalse. Iftrueany abstract classes or interfaces on types reflected with be added as Interfaces in the schema. This is useful if you expose lists of entities on a base/interface type.
Changes:
ToGraphQLSchemaStringnow outputs directives in the schema- #154 - Dyanmically generated types used in the expressions now include the field name the type is being built for to aid in debugging issues
- #146 - Allow GraphQL mutation arguments as seperate arguments in the method signature. Avoiding the need to create the mutation argument classes. e.g.
[GraphQLMutation]
public Person AddPersonSeparateArguments(string name, List<string> names, InputObject nameInput, Gender? gender)
{
// ...
}
[GraphQLMutation]
public Person AddPersonSingleArgument(InputObject nameInput)
{
// ...
}
Turn into
type Mutation {
addPersonSeparateArguments(name: String, names: [String!], nameInput: InputObject, gender: Gender): Person
addPersonSingleArgument(nameInput: InputObject): Person
}
- #160 - Nested data annotations for validation is now supported
- Main
EntityGraphQLpackage now targetsnet6.0;net5.0;netstandard2.1 - #170 - EntityGraphQL now replaces query context expressions in service fields by matching the expression instance it extracted. This allows for more complex expressions when passing data to a service field
- Added support for @oneOf Input Types. Mark an input type with
GraphQLOneOfAttributeand EntityGraphQL will mark the type with@oneOfin the schema and validate the input meets the requiements on execution
Fixes
- #171 inheritance support for nested properties / conditional fields
- #176 - allow fully qualified enums in the filter query language
Fixes
- Fix #159 - SchemaBuilder will no longer try to create schema fields for
constfields on mutation args or input types
Fixes:
- #163 - Fix to handle null property in a nested object when processing a System.Text.Json deserialised query document
- #164 - Fix to support inline fragments in a fragment
- #166 - Add missing
!=operator in the fitler expression language and make sure precedence is correct for logic operators
Changes:
AddMutationsFromnow can use theServiceProviderinstance to create the mutation class allowing dependency injection at the constructor level like Controllers.- You can still provide an instance of the mutation class that will be used instead which is the same behaviour as previous, however this method is considered obsolete and will be removed in a future version. We suggest you utilse the ServiceProvider to register your mutation classes with your desired lifetime.
- Allow types to inherit from multiple base classes/interfaces
- Cleanup SchemaType to use an enum instead of lots of boolean type variables. Previous constructor is obsolete
- Cleanup Interfaces api - added a
AddAllBaseTypes,AddBaseTypeandAddBaseType(string)which provides a lot more flexiblity. See updated docs - Added support for Inline Fragments for types that have interfaces
ToGraphQLSchemaStringnow orders types and fields by name for consistency regardless of order of fields added and to reduce differences when diffing the schema
Fixes:
- Fix #120 - Error when using
schema.RemoveTypeAndAllFieldsand a field of the removing type had a type that has not been added to the schema - Fix #143 - Error building a null check expression in certain cases.
Changes:
FromObject/ default schema generator now adds single fields within non root-level fields. E.g. if a root-level field is a list ofpeopleand each person has a list ofprojects(and projects has an id) is will create a field onproject(id)field on person- Add support for nullable reference types - meaning the correct GraphQL schema nullable definitions are generated. @bzbetty
Fixes:
- Fix generation of singluar field with
idarguments on list fields that use a paging extension when generating a schema. @bzbetty - Fix - when adding Mutation argument types only search for public instance properties. @breyed
- Fix interface query introspection. @bzbetty
- Fix #137 - multiple line endings were used in the schema output
- Fix - make sure we use an array for arguemnts when expected instead of a list<>
- Fix null exception in service field from an object field
- Fix #123 do not output types with no fields in the schema definition
- Fix issue calling
ToListin an expression that then used aIQueryableFirstOrDefaultor friends. Resulting in an invalid expression at runtime
- Fix - Throw an error if your query document defines a non-null variable and a null value is supplied
- Service fields that return a list of items are now wrapped in a null check expression like service fields that return a single object are
- Fix - Object fields not included in the schema could be returned when the selection set was missing from the query. Now missing selection sets on list or object fields in queries throw an error. Selection sets are required in graphql queries for non scalar/enum field types. Thanks @breyed
- Fix - issue with a field using a static member e.g. DateTime.MaxValue
- Fix - issue where a nullable value was incorrectly being called
- Added support for interfaces - thanks @bzbetty
- Added
EntityGraphQLException- use this to throw exceptions and add more error data to the error result via extensions GraphQLValidatornow supports adding custom data via the extensions fieldResolveWithServicemethods will throw an exception if the expression returnsTaskas we need the result. Use.GetAwaiter().GetResult(). Expression do not supportasync/awaitas it is a compiler feature and we need the actual result to build the expression and return the data- Fix using QueryFilter with an empty string treats it as no value - i.e. no filter
- Fix - the type of an array variable defined as required
[Type!]!was incorrectly reflected - Fix - service type's field used in a field's expression was not being extracted into the select. E.g. service field
User.projecthas an expression requiring theuser.idwhich is not included in the GraphQL query.
- Fix thread safety issue with cached queries
- Fix support for using arrays in field argument definitions
- fix regression where non-required (nullable) document variables would be set their non-nullable default value. E.g.
Guid
- Fix regression where non service fields in service fields were not being pulled forward to the stage one expression execution.
- Fix regression where services were not be passed to a mutation with no arguments
Breaking changes
- Interface for Field Extensions now are passed a flag telling the extension if this is pre or post the call with service fields
GetExpressionin Field Extensions is passed the parent IGraphQLNode - useful when your extension changed the original shape of the object graph, like the paging extensionsservices.AddGraphQLSchemaadopts a more ASP.NET styleoptionscallback overload to configure the creation of the schemaMapGraphQLimplementation now returns400Bad Request status code if the query results contains errors, as a bad query was sent- Directive interface for building custom directives has changed
UseSortfield extension now takes an array ofSortInput<T>so order of sorts is used- Parsing floats/doubles/decimals now uses
CultureInfo.InvariantCultureClean up on the schema building APIs to make them more consistent, documented and concise - Fix #89 - Remove JSON.NET dependency - This means internally if EntityGraphQL hits a
JObjectorJTokenit does not know what to do with them. Make sureQueryRequest.Variablesare fully deserialized. I.e. do not have anyJObject/JTokens in there. Deserialize them to nestedDictionary<string, object>.
If you use the EntityGraphQL.AspNet package and the MapGraphQL() method you do not need to worry about anything. EntityGraphQL.AspNet uses System.Text.Json and handles the nested JsonElements with a custom type converter.
If you are directly using SchemaProvider.ExecuteRequest() (i.e. from a Controller or elsewhere), and you are using Newtonsoft.Json to deserilaize the incoming QueryRequest you can add a custom converter to your schema to handle nested JObject/JTokens when encounted in query variables.
schema.AddCustomTypeConverter(new JObjectTypeConverter());
schema.AddCustomTypeConverter(new JTokenTypeConverter());
See the serialization tests for an example.
- Remove the
WithService()method used inside a field expression and replace it withResolveWithService<TService>()on the field for easier discovery in your IDE. Example
schema.Type<Person>().AddField("age", "A persons age")
.ResolveWithService<AgeService>(
(person, ageService) => ageService.GetAge(person.Birthday)
);
- Clean up of
SchemaTypeAPIs to add/replace/remove fields.- Remove
SchemaProvider.Add/ReplaceFieldmethods.- Use
SchemaProvider.Query().Add/ReplaceField()orSchemaProvider.UpdateQuery(queryType => {})to make changes to the root Query type in the schema
- Use
- Additions to the
FieldAPI to add more uncommon functionality to chaining methods - Remove
SchemaProvider.UpdateQueryType(), useSchemaProvider.UpdateQuery(type => {}) - Remove
SchemaProvider.TypeHasField() - Remove
SchemaProvider.GetQueryFields()- useSchemaProvider.Query.GetFields() - Renamed
GetGraphQLSchema()toToGraphQLSchemaString() - Renamed
AddMutationFrom()toAddMutationsFrom() - Removed Obsolete methods:
RequiresAllClaimsreplaced byRequiresAllRolesRequiresAnyClaimreplaced byRequiresAnyRoleExecuteQueryreplaced byExecuteRequestExecuteQueryAsyncreplaced byExecuteRequestAsync
- Remove
Addition changes
- Support for persisted queries (enabled by default) - https://www.apollographql.com/docs/react/api/link/persisted-queries/
- Support for a query cache of recent queries. Enabled by default. Caches the result of compiling the query document string to an AST. Execution is then applying the document level variables, building the expressions then execution
- Better support for nested objects in
QueryVariables - Performance enhancements when building internal types for arguments
- Performance of compiling and building expressions has been improved - it is about 2 times faster. Note this is just building the expressions, not executing them which triggers your services/EF/etc
- Reduction in memory allocation when compiling queries by around 30%
- You can no add/define mutation methods as delegates/anonymous functions etc.
- You can now use
[Range]&[StringLength]attributes on your arguments for more validation options - Introduced custom argument validators - a simple way to act on field arguments before execution. Great for custom/complex input validation on arguments. Use
field.AddValidator()or theArgumentValidatorAttributeattribute. - Using
AddAllFields(true)on anInputTypewill add the sub-complex class types asInputTypes as well - New option to auto add other classes found on mutation arguments as
InputTypes when adding a mutation
Fixes
- Fix - Paging field extensions are now thread safe to support multiple different queries being run on the same field at the same time
- Fix #101 - allow custom de/serialization of incoming requests and outgoing responses, via. services
IGraphQLRequestDeserializer&IGraphQLResponseSerializer.- Note that the objects created in the resulting
QueryResulthave fields named like the fields in the schema which is controlled by thefieldNamerfunction provided to theSchemaProviderwhich defaults to GraphQL "standard" (fields camelCase, types PascalCase)
- Note that the objects created in the resulting
- Fix field name looks up that were not using the
fieldNamerfunction inSchemaProvider - Fix bug where compiler would loop through all available arguments even if it already found the matching type
- Fix argument types of unsigned short/int/long
- Fix #72 - Handling dictionaries introspection - note it will try to create a scalar type
KeyValuePair<T1, T2>in the schema by default - Fix handling argument types of unsigned short/int/long
- Fix issue parsing float/double argument values
- Fix null exception with mutations returning a selection with a list field
- Fix directives on mutation fields
- Fix #110 - Field using the wrong sort input object when the fields are the same
- Fix #99 issue using the MapGraphQL() extension method
- New option to disable introspection. Use
introspectionEnabledparameter when creatingSchemaProvider. Defaults totrue.
- Fix #96 - processing int/long/short as list arguments in mutations - thanks @pierrebelin
- Fix #92 - error processing mutation arguments that are lists/arrays
- Authorization now supports using ASP.NET policies from the
EntityGraphQL.AspNetpackageIAuthorizationServiceis resolved to check authorization and needs to be registered[Authorize]attribute can be used instead of the[GraphQLAuthorize]attribute when usingEntityGraphQL.AspNet
- Fix -
RequiredAttributeresults in the field being not null in the generated GraphQL Schema - Fix - Schema introspection was incorrectly returning
__typenamefor Enums UseConnectionPagingAttributetakes optional arguments for default page size and max page sizeUseOffsetPagingAttributetakes optional arguments for default page size and max page sizeEntityGraphQL.AspNetnow uses System.Text.Json for de/serialization internally. It still supports JSON.NET objects in the variable object (as well as System.Text.Json types)- Fix #19 - you can mark fields (including mutations) as deprecated using the dotnet
[Obsolete]attribute or theIField.Deprecate(reason)method in the schema building - Fix #88 - If an argument is marked as required and not provided in the query request an error is raised. Mark arguments optional via the API, or make it a nullable type or give it a default value
- Query used in ConnectionPaging now resolves itself using
.ToList()
RequireAnyClaim()&RequireAllClaims(). UseRequireAnyRole()&RequireAllRoles()as theClaimTypes.Rolewas used previously and this change makes it explicitschema.ExecuteQueryAsync/ExecuteQuery(QueryRequest, TContextType, IServiceProvider, ClaimsIdentity, ExecutionOptions). Use theExecuteRequest/ExecuteRequestAsyncmethods that take the fullClaimsPrincipalas we now support authorization with policies
- Fix #86. Mutations not correctly checking required authorization on the mutation field directly
- Fix -
RequiredAttributeresults in the field being not null in the generated GraphQL Schema - Fix issue with expressions failing in a high throughput, threaded use case (heavily hit API)
- Fix issue passing optional enum arguments
- New extension methods to ease adding your schema to the service collection. See docs -
services.AddGraphQLSchema<DemoContext>(options => {}) - New package EntityGraphQL.AspNet with extensions to easily expose a graphql endpoint with
MapGraphQL<T>().
app.UseEndpoints(endpoints =>
{
endpoints.MapGraphQL<DemoContext>();
});- Fix issue reconnecting from a service field to the context
- Fix issue when execution is split across non service fields and then with service fields and the first result is null
- Fix issue using Connection/Offset paging on collection fields that were not on the query root
- Fix issue using Connection/Offset paging on collection fields that have service fields
- Option to add default sort when using
UseSort()field extension
- Introduction of fields extensions to encapsulate common field logic and apply it to many fields. See update docs. New built in field extensions
UseConnectionPaging()which when applied to a collection field modifies the field to implement the GraphQL Connection spec for paging data with metadataUseOffsetPaging()which when applied to a collection field modifies the field to implement an offset style paging structureUseFilter()which when applied to a collection adds afilterargument that takes an expressionUseSort()which when applied to a collection adds asortarguments that takes fields to sort the collection by
- Replaced Antlr based GraphQL query lexer/parser with HotChocolate.Language Parser. Parsing of query documents is much faster!
- You can now directly use lists (
[12,32], etc) and objects ({name: "Frank"}) as arguments in the query document. Although it is still recommended to use theVariablesin the query - Added benchmarks to help explore performance issues in expression building (What we do with expressions is fast, but found the Antlr Parser was slow)
- Directives now supported on fragment spreads
Breaking changes
- EntityGraphQL now targets netstandard2.1
- Some optional arguments in
ExecuteQuerymoved to an Options object
- New docs https://entitygraphql.github.io/introduction
- Added
SchemaProvider.UpdateType<T>(Action<SchemaType<T>> updateFunc)to better help "contain" schema types. Instead of
schema.Type<MyType>().AddField(...);
schema.Type<MyType>().AddField(...);
schema.Type<MyType>().AddField(...);
we have
schema.UpdateType<MyType>(t => {
t.AddField(...);
t.AddField(...);
t.AddField(...);
});
Similar for SchemaProvider.AddType<T>(string name, string description, Action<SchemaType<T>> updateFunc)
- You can pass a
ILogger<SchemaProvider<T>>when creating aSchemaProvider. Exceptions etc. will be logged - Added
Take<TSource>(this IQueryable<TSource> source, int? count)that works onIQueryable<T>to support EF translation
Breaking changes
- EntityGraphQL now targets netstandard2.0
- Big refactor/clean - hopefully easier to follow the post Antlr (compiled graphql) output - see
GraphQL*Fieldclasses - Support for dotnet Entity Framework Core 3.1+ when using other services in the schema (
WithService()) - Removed the
Where<TSource>(this IEnumerable<TSource> source, EntityQueryType<TSource> filter)helper. Use theWhereWhenmethods that supportEntityQueryType
To support EF 3.x as a base schema context we now build and execute expressions in 2 stages. See the updated readme section How EntityGraphQL handles WithService().
- Update Humanizer.Core dependency which resolves issue with newer dotnet core
- 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. AddCustomScalarType()removed. Previously marked as obsolete. UseAddScalarType()
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