According to the GraphQL specification, it is “a query language designed to build client applications by providing an intuitive and flexible syntax and system for describing their data requirements and interactions”.
Starting with version 25, connecting List & Label with a GraphQL API as data source is as simple as creating a new List & Label GraphQLDataProvider object and passing your API address as URL constructor parameter.
GraphQLDataProvider prov = new GraphQLDataProvider("https://localhost:44375/api/graphql");
First, the data provider will try to extract the types and queries defined in the GraphQL server by looking at the schema and – based on that – it will create tables, rows, columns and relations.
Queries that are created as tables have a “Q_” prefix in their name. The prefix can be changed by giving a new prefix to the optional constructor parameter “queryPrefix” of the GraphQLDataProvider class. These queries are the only elements that can be used on the “root” level to print and design, as calling a query is the only way to get actual data in GraphQL. The type-based tables can only be used as child tables of queries as shown below.
If a GraphQL query contains query parameters, these are automatically be added as report parameters. It should be noted here that the GraphQL syntax must be fully maintained when entering the values for the report parameter. A simple example shows how it would work with the default type String:
{ Categories(CategoryName:"Beverages") { CategoryID, CategoryName, Description } }
Here List & Label would now create the report parameter “CategoryName” and expects as value directly the category name (e.g. Beverages) after which to filter.
But if the GraphQL schema has defined typed query parameters it is necessary to specify the whole schema when entering the value in the report parameter:
{ Categories(MyArgument:{CategoryName:{eq:"Beverages"}}) { CategoryID, CategoryName, Description } }
List & Label would now create the report parameter here with the name “MyArgument” and now expects the GraphQL syntax for the entire query when it is entered as a value in order to build and run the filter: {CategoryName:{eq:“Beverages“}}
There are two other properties in this data provider:
- QueriesRootName: GraphQL server packs all the queries as fields of one single type. By default, the name of the queries type is “Query”, but if your API is different, you need to inform List & Label about this fact.
- MutationsRootName: a mutation is a write followed by a fetch. Because writing the database is not needed nor supported from the reporting side, mutations must not be part of the structure in the Designer. GraphQL server packs all of the mutations as fields of one single type. By default, the name of the mutations type is “Mutation”, but if your API is different, you need to inform List & Label about it in order to exclude the mutations from the data structure.
If your GraphQL data source is to support images, you can serialize and transfer them using GraphQL via Base64 string encoding. To decode these fields back to Bitmap for ListLabel, you can use ListLabel AutoDefineField event. the following code shows how to do it in a Northwind sample:
LL.AutoDefineField += new AutoDefineElementHandler(LL_AutoDefineField); void LL_AutoDefineField(object sender, AutoDefineElementEventArgs e) { string name = e.Name.ToString(); string value = e.Value.ToString(); if (name == "Q_categories.picture") { ListLabel ll = sender as ListLabel; e.Suppress = true; if (value.Length > 50 && value.Length %25 4 == 0) { ll.Fields.Add(e.Name, Convert.FromBase64String(value)); } else { ll.Fields.Add(e.Name, string.Empty, LlFieldType.Drawing_hBitmap); } } }
This is what the Designer looks like when connecting to a simple Northwind service. Note that we’re using the Query Q_Categories as root table, not the Type “Category”.
Of course, you may also add a GraphQL data source to the Report Server. It also supports to pass authentication information to access your API.