Mapping response from GraphQL queries to entity model using ClientLibrary

I’m submitting a…

  • [ ] Regression (a behavior that stopped working in a new release)
  • [ ] Bug report
  • [ ] Performance issue
  • [x] Documentation issue or request

Current behavior

I’m sending a GraphQL query request using the Client Library and GraphQlAsync.<>() .
I can see that the correct data is being returned by the api but I have no idea how to map the result to my entity model. I’ve read the docs and browsed the lIbrary and Squidex backend source. I haven’t slept for a couple of days. Help.

Expected behavior

Minimal reproduction of the problem

My schema is:

> {
>     "properties": {
>         "label": "Pages"
>     },
>     "scripts": {
>         "create": "var data = ctx.data;\n    \n            if (data.title && data.title.iv) {\n                data.slug = { iv: slugify(data.title.iv) };\n\n                replace(data);\n            }",
>         "update": "var data = ctx.data;\n    \n            if (data.title && data.title.iv) {\n                data.slug = { iv: slugify(data.title.iv) };\n                replace(data);\n            }"
>     },
>     "fieldsInLists": [],
>     "fieldsInReferences": [],
>     "fields": [
>         {
>             "name": "title",
>             "properties": {
>                 "isRequired": true,
>                 "fieldType": "String",
>                 "editor": "Input",
>                 "label": "Title"
>             },
>             "partitioning": "invariant"
>         },
>         {
>             "name": "contentArea",
>             "properties": {
>                 "isRequired": true,
>                 "fieldType": "References",
>                 "editor": "Dropdown",
>                 "maxItems": 1,
>                 "resolveReference": true,
>                 "schemaIds": [
>                     "0e330a52-04f0-49b9-8277-b207016b4c02"
>                 ],
>                 "label": "Content area",
>                 "hints": "contentareahint"
>             },
>             "partitioning": "invariant"
>         },
>         {
>             "name": "image",
>             "properties": {
>                 "isRequired": true,
>                 "fieldType": "Assets",
>                 "minItems": 1,
>                 "maxItems": 1,
>                 "mustBeImage": true,
>                 "resolveImage": true,
>                 "label": "Image"
>             },
>             "partitioning": "invariant"
>         },
>         {
>             "name": "body",
>             "properties": {
>                 "fieldType": "String",
>                 "editor": "RichText",
>                 "label": "Body"
>             },
>             "partitioning": "invariant"
>         },
>         {
>             "name": "slug",
>             "properties": {
>                 "isRequired": true,
>                 "fieldType": "String",
>                 "editor": "Input",
>                 "label": "Slug (Autogenerated)",
>                 "hints": "Autogenerated slug that can be used to identity the page."
>             },
>             "isDisabled": true,
>             "partitioning": "invariant"
>         }
>     ],
>     "isPublished": true
> }

My query:

> {
>   queryPageContents(filter: "data/slug/iv eq 'indoor-cricket'") {
>     id
>     flatData {
>       title
>       slug
>       body
>       image {
>         id
>         url
>       }
>       contentArea {
>         id
>         flatData {
>           name
>           basePath
>           slug
>         }
>       }
>     }
>   }
> }

My entity data model:

> public class PageData
>     {
>         [JsonProperty(PropertyName = "title")]
>         public string Title { get; set; }
> 
>         [JsonProperty(PropertyName = "slug")]
>         public string Slug { get; set; }
> 
>         [JsonProperty(PropertyName = "body")]
>         public string Body { get; set; }
> 
>         [JsonProperty(PropertyName = "image")]
>         public List<string> Image { get; set; }
> 
>         [JsonProperty(PropertyName = "contentArea")]
>         public List<string> ContentArea { get; set; }
>     }

My api client:

> public class ApiClient : IApiClient
> {
> 	private readonly SquidexClient<Page, PageData> pagesClient;
> 
> 	public ApiClient(IOptions<AppOptions> appOptions)
>     {
>         var options = appOptions.Value;
> 
>         clientManager =
>             new SquidexClientManager(
>                 options.Url,
>                 options.AppName,
>                 options.ClientId,
>                 options.ClientSecret);
> 
>         pagesClient = clientManager.GetClient<Page, PageData>("page");
>     }
> 
>     public async Task<Page> GetPageAsync(string slug)
>     {
>     	var graphQlQuery = new
>         {
>         query = @"{
> 			queryPageContents (filter: ""data/slug/iv eq '" + slug + @"'"") {
> 			    id
> 			    flatData {
> 			      title
> 			      slug
> 			      body
> 			      image {
> 			        id
> 			        url
> 			      }
> 			      contentArea {
> 			        id
> 			        flatData {
> 			          name
> 			          basePath
> 			          slug
> 			        }
> 			      }
> 			    }
> 			  }
> 			}"
>         };
> 
>         QueryContext ctx = QueryContext.Default.Flatten();
>         var result = await pagesClient.GraphQlAsync<JObject>(graphQlQuery, ctx);
>         /*
>      		??????????????????????????
>      	*/
>     }
> }

Where all the others methods in Squidex.ClientLibrary.SquidexClient return the entity you want, the graphql one doesn’t and I can’t work out how to parse the response.

Environment

  • [ ] Self hosted with docker
  • [ ] Self hosted with IIS
  • [ ] Self hosted with other version
  • [ x] Cloud version

Hi,

there are a few examples: https://github.com/Squidex/squidex/blob/master/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs#L184

You either need a class model that matchs to your structure or a JObject that is like a nested dictionary.

Ok, thanks.

Not used GraphQL before. After working with it some more I can understand why GraphQlAsync can’t auto-map to a SquidEx entity model in .Net.

GraphQL is good :slight_smile: