From d53d2df9365ed21d4309ee64bb3ed2dba7530f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Ku=C5=BEela?= Date: Mon, 20 May 2024 12:55:00 +0200 Subject: [PATCH 01/20] Add example for adding basic content type filters --- .../core/Apis.GraphQL.Abstractions/README.md | 121 +++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index c492c148851..cd2f4151bbc 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -74,7 +74,9 @@ public class Startup : StartupBase Thats it, your part will now be exposed in GraphQL... just go to the query explorer and take a look. Magic. -### Define a query filter type +## Filtration + +### Define a custom query filter type So now you have lots of data coming back, the next thing you want to do is to be able to filter said data. @@ -176,6 +178,123 @@ Shown in the example above, we have an autoroutePart argument, this is registere Done. +### Extending Content Type Query Filters + +In the previous section, we demonstrated how to create custom filters for more complex requirements. However, if you need to implement filtering based on your index atomic values, the `WhereInputObjectGraphType` and `IIndexAliasProvider` are what you need. + +We will cover: + +1. Implementing a `WhereInputObjectGraphType`. +2. Implementing `IIndexAliasProvider`. +3. Registering it in the `Startup` class. + +#### Implementing WhereInputObjectGraphType + +The `WhereInputObjectGraphType` enhances the `InputObjectGraphType` by introducing methods to define filters such as equality, array filters, etc. This is essential since it's the expected type for the `ContentItemsFieldType` responsible for the filtering logic. + +Here is an example implementation: + +```csharp +// Assuming we've added the necessary using directives. +public class AutorouteInputObjectType : WhereInputObjectGraphType +{ + // Binds the filter fields to the GraphQL type representing AutoroutePart + public AutorouteInputObjectType() + { + Name = "AutoroutePartInput"; + + // Utilize the method for adding scalar fields from the base class. + AddScalarFilterFields("path", S["Filter by the path of the content item"]); + } +} +``` + +This method will addscalar filters to all ContentItem queries, including custom Content Types. + +1. equals, not equals +2. contains, not contains +3. starts with, ends with, not starts with, not ends with +4. in, not in + +These filters are checked against index that is bound to given ```ContentPart```. + +#### Implementing IIndexAliasProvider + +To bind ```ContentPart``` to an Index, you have to implement ```IIndexAliasProvider```. Ensure that field names in your filter object are same as fields in index. It is needed for filter automatching. + + +```csharp +public class AutorouteInputObjectType : WhereInputObjectGraphType +{ + public class AutoroutePartIndexAliasProvider : IIndexAliasProvider + { + private static readonly IndexAlias[] _aliases = + [ + new IndexAlias + { + Alias = "autoroutePart", // alias of graphql ContentPart. You may also use nameof(AutoroutPart).ToFieldName() + Index = nameof(AutoroutePartIndex), // name of index bound to part - keep in mind, that fields need to correspond. E.g. 'path' has same name in index and part. + IndexType = typeof(AutoroutePartIndex) + } + ]; + + public IEnumerable GetAliases() + { + return _aliases; + } + } +} +``` + +#### Updating the Startup Class + +Update Startup class like below. + +```csharp +[RequireFeatures("OrchardCore.Apis.GraphQL")] +public class Startup : StartupBase +{ + // Assuming we've added the necessary using directives. + public override void ConfigureServices(IServiceCollection services) + { + // Code to register the AutoroutePart and AutorouteQueryObjectType is assumed to be present. + // Register WhereInputObjectGraphType + services.AddInputObjectGraphType(); + + // Register IIndexAliasProvider + services.AddTransient(); + services.AddWhereInputIndexPropertyProvider(); + } +} +``` +With these configurations, you can navigate to your GraphQL interface, and you should see the new filters available for use in all Content type queries. + +#### Example Query Filters + +Below are resulting query filters applied to an autoroutePart: + + +```json +{ + person(where: {path: {path_contains: "", path: "", path_ends_with: "", path_in: "", path_not: "", path_not_contains: "", path_not_ends_with: "", path_not_in: "", path_not_starts_with: "", path_starts_with: ""}}) { + name + } +} +``` + +Alternatively, if you register the part with ```collapse = true```, fields will not be nested inside object: + +```json +{ + person(where: {path_contains: "", path: "", path_ends_with: "", path_in: "", path_not: "", path_not_contains: "", path_not_ends_with: "", path_not_in: "", path_not_starts_with: "", path_starts_with: ""}) { + name + } +} +``` + +For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType]{https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs} and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also might check existing index for [autoroutePart](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs). + + ## Querying related content items One of the features of Content Items, is that they can be related to other Content Items. From 7f3695cee37f936c2dbb6ad9c66e6c37d0c3500b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Ku=C5=BEela?= Date: Mon, 20 May 2024 13:03:00 +0200 Subject: [PATCH 02/20] fix nesting --- .../core/Apis.GraphQL.Abstractions/README.md | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index cd2f4151bbc..dd035e4d631 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -224,24 +224,21 @@ To bind ```ContentPart``` to an Index, you have to implement ```IIndexAliasProvi ```csharp -public class AutorouteInputObjectType : WhereInputObjectGraphType +public class AutoroutePartIndexAliasProvider : IIndexAliasProvider { - public class AutoroutePartIndexAliasProvider : IIndexAliasProvider - { - private static readonly IndexAlias[] _aliases = - [ - new IndexAlias - { - Alias = "autoroutePart", // alias of graphql ContentPart. You may also use nameof(AutoroutPart).ToFieldName() - Index = nameof(AutoroutePartIndex), // name of index bound to part - keep in mind, that fields need to correspond. E.g. 'path' has same name in index and part. - IndexType = typeof(AutoroutePartIndex) - } - ]; - - public IEnumerable GetAliases() + private static readonly IndexAlias[] _aliases = + [ + new IndexAlias { - return _aliases; + Alias = "autoroutePart", // alias of graphql ContentPart. You may also use nameof(AutoroutPart).ToFieldName() + Index = nameof(AutoroutePartIndex), // name of index bound to part - keep in mind, that fields need to correspond. E.g. 'path' has same name in index and part. + IndexType = typeof(AutoroutePartIndex) } + ]; + + public IEnumerable GetAliases() + { + return _aliases; } } ``` From 07ed9bad8a799a4b319c0462ff529c7801711221 Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Tue, 21 May 2024 09:12:46 +0200 Subject: [PATCH 03/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index dd035e4d631..48e044ccb90 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -216,11 +216,11 @@ This method will addscalar filters to all ContentItem queries, including custom 3. starts with, ends with, not starts with, not ends with 4. in, not in -These filters are checked against index that is bound to given ```ContentPart```. +These filters are checked against an index that is bound to the given ```ContentPart```. #### Implementing IIndexAliasProvider -To bind ```ContentPart``` to an Index, you have to implement ```IIndexAliasProvider```. Ensure that field names in your filter object are same as fields in index. It is needed for filter automatching. +To bind ```ContentPart``` to an Index, you have to implement ```IIndexAliasProvider```. Ensure that field names in your filter object are the same as fields in the index. It is needed for filter automatching. ```csharp From 8ed0019579de432291051abe89c625df7389e125 Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Tue, 21 May 2024 09:12:54 +0200 Subject: [PATCH 04/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 48e044ccb90..a27f8750937 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -289,8 +289,7 @@ Alternatively, if you register the part with ```collapse = true```, fields will } ``` -For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType]{https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs} and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also might check existing index for [autoroutePart](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs). - +For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs) and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also might check the existing index for [`AutoroutePart`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs). ## Querying related content items From 742be79748503e30e2b05f4bea5bdb55574761af Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Tue, 21 May 2024 09:13:03 +0200 Subject: [PATCH 05/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index a27f8750937..25101d6575e 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -209,7 +209,7 @@ public class AutorouteInputObjectType : WhereInputObjectGraphType } ``` -This method will addscalar filters to all ContentItem queries, including custom Content Types. +This method will add scalar filters to all ContentItem queries, including custom Content Types. 1. equals, not equals 2. contains, not contains From 3ecdf6a8015a1d3e6caed4ebf22577e59c9b6639 Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Tue, 21 May 2024 08:18:45 +0000 Subject: [PATCH 06/20] Update docs, clarify use cases --- .../core/Apis.GraphQL.Abstractions/README.md | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 25101d6575e..105e57aa6f9 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -82,6 +82,11 @@ So now you have lots of data coming back, the next thing you want to do is to be We follow a similar process from step #1, so at this point I will make the assumption you have implemented step #1. +Use this approach if you; + +* want to add new filter on Content Type queries +* need to use custom logic for filtration. For example fetching data from service, comparing complex objects. + What we are going to cover here is; 1. Implement an Input type. @@ -130,6 +135,7 @@ When an input part is registered, it adds in that part as the parent query, in t ``` Next we want to implement a filter. The filter takes the input from the class we just built and the above example, and performs the actual filter against the object passed to it. +Note that GraphQLFilter also provides PostQueryAsync and can be used also in other usecases as checking permissions etc. ```csharp public class AutoroutePartGraphQLFilter : GraphQLFilter @@ -178,9 +184,15 @@ Shown in the example above, we have an autoroutePart argument, this is registere Done. -### Extending Content Type Query Filters +### Using default Content Type query filters + +In the previous section, we demonstrated how to create filters for complex requirements, allowing you to create custom filtration methods. However, in case you need to add filter on Content Type queries, there is also a simpler solution for many usecases. -In the previous section, we demonstrated how to create custom filters for more complex requirements. However, if you need to implement filtering based on your index atomic values, the `WhereInputObjectGraphType` and `IIndexAliasProvider` are what you need. +Use this approach if you; + +* want to add new filter on Content Type queries +* will have database index with data for your filters +* you can use simple comparison (equals, contains, in, ...) against index values. For example ```AutoroutePartIndex.path = filterValue```. We will cover: @@ -291,6 +303,19 @@ Alternatively, if you register the part with ```collapse = true```, fields will For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs) and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also might check the existing index for [`AutoroutePart`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs). +### Using arguments for query filtration + +There is also possibility to utilize query arguments and use them for filtering query results inside ```Resolve``` method. For more information visit [GraphQL documentation](https://graphql-dotnet.github.io/docs/getting-started/arguments/). + +Use this approach if you; + +* want to add new filter on any type of query, content part or field +* will use custom logic for filtration + +OrchardCore implementation of filtering query by argument can be seen [in ContentItemQuery](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemQuery.cs) or ```MediaAssetQuery```. + +OrchardCore implementation of applying argument on field can be seen in ```MediaFieldQueryObjectType```. + ## Querying related content items One of the features of Content Items, is that they can be related to other Content Items. From 790ea34ea2694f813392cc2ffb053c6cd38b019f Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Fri, 31 May 2024 22:23:58 +0200 Subject: [PATCH 07/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 105e57aa6f9..c452cfb987a 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -314,7 +314,7 @@ Use this approach if you; OrchardCore implementation of filtering query by argument can be seen [in ContentItemQuery](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemQuery.cs) or ```MediaAssetQuery```. -OrchardCore implementation of applying argument on field can be seen in ```MediaFieldQueryObjectType```. +Orchard Core's implementation of applying an argument on a field can be seen in `MediaFieldQueryObjectType`. ## Querying related content items From 5c857ce61fff586675a40c295d11fa557108c8e7 Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Fri, 31 May 2024 22:25:40 +0200 Subject: [PATCH 08/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index c452cfb987a..806c80e942f 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -82,10 +82,10 @@ So now you have lots of data coming back, the next thing you want to do is to be We follow a similar process from step #1, so at this point I will make the assumption you have implemented step #1. -Use this approach if you; +Use this approach if you: -* want to add new filter on Content Type queries -* need to use custom logic for filtration. For example fetching data from service, comparing complex objects. +- want to add a new filter on Content Type queries, +- need to use custom logic for filtering. For example, fetching data from service, or comparing complex objects. What we are going to cover here is; From 9732c8afee5773ac27136d3d38647e03b25ca299 Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Fri, 31 May 2024 22:25:58 +0200 Subject: [PATCH 09/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- .../core/Apis.GraphQL.Abstractions/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 806c80e942f..36a32ffc75f 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -303,16 +303,16 @@ Alternatively, if you register the part with ```collapse = true```, fields will For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs) and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also might check the existing index for [`AutoroutePart`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs). -### Using arguments for query filtration +### Using arguments for query filtering -There is also possibility to utilize query arguments and use them for filtering query results inside ```Resolve``` method. For more information visit [GraphQL documentation](https://graphql-dotnet.github.io/docs/getting-started/arguments/). +There is also the possibility to utilize query arguments and use them for filtering query results inside the `Resolve` method. For more information visit the [GraphQL documentation](https://graphql-dotnet.github.io/docs/getting-started/arguments/). -Use this approach if you; +Use this approach if you: -* want to add new filter on any type of query, content part or field -* will use custom logic for filtration +* want to add a new filter on any type of query, content part, or field, +* or will use custom logic for filtration. -OrchardCore implementation of filtering query by argument can be seen [in ContentItemQuery](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemQuery.cs) or ```MediaAssetQuery```. +Orchard Core's implementation of a filtering query by argument can be seen in [`ContentItemQuery`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemQuery.cs) or `MediaAssetQuery`. Orchard Core's implementation of applying an argument on a field can be seen in `MediaFieldQueryObjectType`. From 79f147937f82bf9a4a888b8ad57b94b897c70695 Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Fri, 31 May 2024 22:26:32 +0200 Subject: [PATCH 10/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- .../reference/core/Apis.GraphQL.Abstractions/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 36a32ffc75f..413fb88d04a 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -188,11 +188,11 @@ Done. In the previous section, we demonstrated how to create filters for complex requirements, allowing you to create custom filtration methods. However, in case you need to add filter on Content Type queries, there is also a simpler solution for many usecases. -Use this approach if you; +Use this approach if you: -* want to add new filter on Content Type queries -* will have database index with data for your filters -* you can use simple comparison (equals, contains, in, ...) against index values. For example ```AutoroutePartIndex.path = filterValue```. +* want to add a new filter on Content Type queries, +* will have a database index with data for your filters, +* you can use simple comparison (equals, contains, in...) against index values. For example, `AutoroutePartIndex.Path = filterValue`. We will cover: From a3241171e2ebea6dd4e01286a775878def460f4c Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Fri, 31 May 2024 22:26:47 +0200 Subject: [PATCH 11/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 413fb88d04a..76989e9c382 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -186,7 +186,7 @@ Done. ### Using default Content Type query filters -In the previous section, we demonstrated how to create filters for complex requirements, allowing you to create custom filtration methods. However, in case you need to add filter on Content Type queries, there is also a simpler solution for many usecases. +In the previous section, we demonstrated how to create filters for complex requirements, allowing you to create custom filtration methods. However, in case you need to add a filter on Content Type queries, there is also a simpler solution for many use cases. Use this approach if you: From 6f4913a7d9fbf7d56154f22d61bd5911d3f083d0 Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Fri, 31 May 2024 22:27:27 +0200 Subject: [PATCH 12/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zoltán Lehóczky --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 76989e9c382..76e5417fec5 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -134,8 +134,7 @@ When an input part is registered, it adds in that part as the parent query, in t } ``` -Next we want to implement a filter. The filter takes the input from the class we just built and the above example, and performs the actual filter against the object passed to it. -Note that GraphQLFilter also provides PostQueryAsync and can be used also in other usecases as checking permissions etc. +Next, we want to implement a filter. The filter takes the input from the class we just built and the above example, and performs the actual filter against the object passed to it. Note that `GraphQLFilter` also provides `PostQueryAsync` that can be used in other use cases too, like checking permissions. ```csharp public class AutoroutePartGraphQLFilter : GraphQLFilter From 75afa18c0a9b8819b4665a5c55ca842844b5b48c Mon Sep 17 00:00:00 2001 From: MikeKry <52829889+MikeKry@users.noreply.github.com> Date: Fri, 31 May 2024 22:28:36 +0200 Subject: [PATCH 13/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 76e5417fec5..bd92bfdaab3 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -300,7 +300,7 @@ Alternatively, if you register the part with ```collapse = true```, fields will } ``` -For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs) and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also might check the existing index for [`AutoroutePart`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs). +For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs) and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also, might check the existing index for [`AutoroutePart`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs). ### Using arguments for query filtering From 2a1312de5c0e91d1599375bcfe2559a3e96e6ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Ku=C5=BEela?= Date: Fri, 31 May 2024 22:37:30 +0200 Subject: [PATCH 14/20] apply suggestions --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index bd92bfdaab3..de300e0266b 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -233,7 +233,6 @@ These filters are checked against an index that is bound to the given ```Content To bind ```ContentPart``` to an Index, you have to implement ```IIndexAliasProvider```. Ensure that field names in your filter object are the same as fields in the index. It is needed for filter automatching. - ```csharp public class AutoroutePartIndexAliasProvider : IIndexAliasProvider { @@ -281,7 +280,6 @@ With these configurations, you can navigate to your GraphQL interface, and you s Below are resulting query filters applied to an autoroutePart: - ```json { person(where: {path: {path_contains: "", path: "", path_ends_with: "", path_in: "", path_not: "", path_not_contains: "", path_not_ends_with: "", path_not_in: "", path_not_starts_with: "", path_starts_with: ""}}) { @@ -304,7 +302,7 @@ For a more detailed understanding, refer to the implementation of [WhereInputObj ### Using arguments for query filtering -There is also the possibility to utilize query arguments and use them for filtering query results inside the `Resolve` method. For more information visit the [GraphQL documentation](https://graphql-dotnet.github.io/docs/getting-started/arguments/). +There is also the possibility to utilize query arguments and use them for filtering query results inside the `Resolve` method. For more information, visit the [GraphQL documentation](https://graphql-dotnet.github.io/docs/getting-started/arguments/). Use this approach if you: From c3ec1272bba0438b1632988025968d0638366ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Ku=C5=BEela?= Date: Sat, 1 Jun 2024 15:22:20 +0200 Subject: [PATCH 15/20] little tweaks --- .../core/Apis.GraphQL.Abstractions/README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index de300e0266b..a4b38c65ef6 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -87,7 +87,7 @@ Use this approach if you: - want to add a new filter on Content Type queries, - need to use custom logic for filtering. For example, fetching data from service, or comparing complex objects. -What we are going to cover here is; +What we are going to cover here is: 1. Implement an Input type. 2. Register it in Startup class. @@ -185,7 +185,7 @@ Done. ### Using default Content Type query filters -In the previous section, we demonstrated how to create filters for complex requirements, allowing you to create custom filtration methods. However, in case you need to add a filter on Content Type queries, there is also a simpler solution for many use cases. +In the previous section, we demonstrated how to create filters for complex requirements, allowing you to create custom filtration methods. However, in case you just need to add a simple filter on Content Type queries, there is also a simpler solution. Use this approach if you: @@ -201,12 +201,15 @@ We will cover: #### Implementing WhereInputObjectGraphType -The `WhereInputObjectGraphType` enhances the `InputObjectGraphType` by introducing methods to define filters such as equality, array filters, etc. This is essential since it's the expected type for the `ContentItemsFieldType` responsible for the filtering logic. +The `WhereInputObjectGraphType` enhances the `InputObjectGraphType` by introducing methods to define filters such as equality, substrings, or array filters. Inheriting from `WhereInputObjectGraphType` is essential since it's the expected type for the `ContentItemsFieldType` that is responsible for the filtering logic. Here is an example implementation: ```csharp -// Assuming we've added the necessary using directives. +// Assuming we've added the necessary using directives. +// It is essential to inherit from WhereInputObjectGraphType. +// Do not use the InputObjectGraphType type as it will not be +// handled by default ContentItem queries. public class AutorouteInputObjectType : WhereInputObjectGraphType { // Binds the filter fields to the GraphQL type representing AutoroutePart @@ -220,7 +223,7 @@ public class AutorouteInputObjectType : WhereInputObjectGraphType } ``` -This method will add scalar filters to all ContentItem queries, including custom Content Types. +This method will add scalar filters to all ContentItem queries, including your own custom Content Types. Scalar filters include following: 1. equals, not equals 2. contains, not contains @@ -298,16 +301,17 @@ Alternatively, if you register the part with ```collapse = true```, fields will } ``` -For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs) and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also, might check the existing index for [`AutoroutePart`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs). +For a more detailed understanding, refer to the implementation of [WhereInputObjectGraphType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs) and [ContentItemFieldsType](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemsFieldType.cs). Also, you can check the [`AutoroutePartIndex`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.Autoroute.Core/Indexes/AutoroutePartIndex.cs) that was used for examples. ### Using arguments for query filtering -There is also the possibility to utilize query arguments and use them for filtering query results inside the `Resolve` method. For more information, visit the [GraphQL documentation](https://graphql-dotnet.github.io/docs/getting-started/arguments/). +There is also the possibility to utilize query arguments and use them for filtering query results, or customizing query output inside the `Resolve` method. For more information, visit the [GraphQL documentation](https://graphql-dotnet.github.io/docs/getting-started/arguments/). Use this approach if you: * want to add a new filter on any type of query, content part, or field, * or will use custom logic for filtration. +* or you need to switch data sources, or logic, based on argument's value Orchard Core's implementation of a filtering query by argument can be seen in [`ContentItemQuery`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemQuery.cs) or `MediaAssetQuery`. From 162dd1abf5fff283ae8d490a79ac4c1094eb25fb Mon Sep 17 00:00:00 2001 From: Hisham Bin Ateya Date: Tue, 4 Jun 2024 11:56:17 +0300 Subject: [PATCH 16/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index a4b38c65ef6..bd2e559dd2d 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -244,7 +244,7 @@ public class AutoroutePartIndexAliasProvider : IIndexAliasProvider new IndexAlias { Alias = "autoroutePart", // alias of graphql ContentPart. You may also use nameof(AutoroutPart).ToFieldName() - Index = nameof(AutoroutePartIndex), // name of index bound to part - keep in mind, that fields need to correspond. E.g. 'path' has same name in index and part. + Index = nameof(AutoroutePartIndex), // name of index bound to part - keep in mind, that fields need to correspond. E.g. 'path' has the same name in the index and part. IndexType = typeof(AutoroutePartIndex) } ]; From 2979549d3757052a2d77f9c41c7a6d9115174c7c Mon Sep 17 00:00:00 2001 From: Hisham Bin Ateya Date: Tue, 4 Jun 2024 11:56:37 +0300 Subject: [PATCH 17/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index bd2e559dd2d..b491b957b79 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -311,9 +311,9 @@ Use this approach if you: * want to add a new filter on any type of query, content part, or field, * or will use custom logic for filtration. -* or you need to switch data sources, or logic, based on argument's value +* or you need to switch data sources, or logic, based on the argument's value -Orchard Core's implementation of a filtering query by argument can be seen in [`ContentItemQuery`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemQuery.cs) or `MediaAssetQuery`. +Orchard Core's implementation of a filtering query by an argument can be seen in [`ContentItemQuery`](https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentItemQuery.cs) or `MediaAssetQuery`. Orchard Core's implementation of applying an argument on a field can be seen in `MediaFieldQueryObjectType`. From 58dc86f051be1a2552c02e9ea20cf5bef1c14d80 Mon Sep 17 00:00:00 2001 From: Hisham Bin Ateya Date: Tue, 4 Jun 2024 11:57:08 +0300 Subject: [PATCH 18/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index b491b957b79..143b33bc3e6 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -84,8 +84,8 @@ We follow a similar process from step #1, so at this point I will make the assum Use this approach if you: -- want to add a new filter on Content Type queries, -- need to use custom logic for filtering. For example, fetching data from service, or comparing complex objects. +- want to add a new filter on Content-Type queries, +- need to use custom logic for filtering. For example, fetching data from a service, or comparing complex objects. What we are going to cover here is: From 5cb91bb883cd2faba1b001e017d9525ac258f5fc Mon Sep 17 00:00:00 2001 From: Hisham Bin Ateya Date: Tue, 4 Jun 2024 11:58:27 +0300 Subject: [PATCH 19/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 143b33bc3e6..459edd2f4d0 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -281,7 +281,7 @@ With these configurations, you can navigate to your GraphQL interface, and you s #### Example Query Filters -Below are resulting query filters applied to an autoroutePart: +Below are the resulting query filters applied to an autoroutePart: ```json { From c2daca3030dffd58ff4a1bbfbf7fecfdc280947a Mon Sep 17 00:00:00 2001 From: Hisham Bin Ateya Date: Tue, 4 Jun 2024 11:58:48 +0300 Subject: [PATCH 20/20] Update src/docs/reference/core/Apis.GraphQL.Abstractions/README.md --- src/docs/reference/core/Apis.GraphQL.Abstractions/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md index 459edd2f4d0..40fc8f62f48 100644 --- a/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/core/Apis.GraphQL.Abstractions/README.md @@ -183,13 +183,13 @@ Shown in the example above, we have an autoroutePart argument, this is registere Done. -### Using default Content Type query filters +### Using default Content-Type query filters -In the previous section, we demonstrated how to create filters for complex requirements, allowing you to create custom filtration methods. However, in case you just need to add a simple filter on Content Type queries, there is also a simpler solution. +In the previous section, we demonstrated how to create filters for complex requirements, allowing you to create custom filtration methods. However, in case you need to add a simple filter on Content-Type queries, there is also a simpler solution. Use this approach if you: -* want to add a new filter on Content Type queries, +* want to add a new filter on Content-Type queries, * will have a database index with data for your filters, * you can use simple comparison (equals, contains, in...) against index values. For example, `AutoroutePartIndex.Path = filterValue`.