Showing posts with label coding. Show all posts
Showing posts with label coding. Show all posts

19 May 2020

DadenU Day: GraphQL

From Steven:

GraphQL is a data query language to make it easier and more intuitive to use APIs. Existing APIs use fixed endpoints to give the user what they want, however, the fixed nature means that that endpoint can give too much or too little information. These are called over-fetching and under-fetching. Over-fetching uses more intensive database calls on the server and more bandwidth, whereas under-fetching requires more API calls and more complexity on the client. GraphQL allows the user to define what data they want.

I used a prewritten example to experiment with this in the C# library GraphQL for .NET. The example includes a nice GUI playground to test queries. An example GraphQL query is show in Figure 1.



Figure 1:An example query from the playground.

The GraphQL query consists of a type “query”, a name “TestQuery”, a reference to the query to query “reservations”, a list of arguments to the query, and a list of fields to include in the result. This allows the ability to include only the fields you want and no more. It is passed in a standard get or post request to /graphql by default, so very easy to use.

The result of this GraphQL query is shown in Figure 2. It is in JSON format so is easily read by humans and easily parsed with standard libraries. It looks similar in structure to the query, which allows quick checking of the results.




Figure 2:The result from the query in Figure 1.

The example uses a simple hotel reservation system with rooms, reservations and guests. Each of these has its own C# class as normal. To make the GraphQL classes, we need to define a new ObjectGraphType that takes the existing type as a generic parameter as in Figure 3.



Figure 3:The reservation ObjectGraphType. It takes the existing Reservation type as a generic parameter, but fields still need to be defined in the constructor.


Each property in that type must then be given in the constructor by applying the Field method to it. Complex properties are defined manually by giving the type as a generic parameter and the string for querying, though this seems like a library limitation.

A GraphQL query is defined as another ObjectGraphType where the Field method defines the name of the query, a list of arguments to pick up on, and a resolve method that is called to resolve the GraphQL query using the defined arguments. This is shown in Figure 4. The return type is a List of Reservations as expected, but each type is its counterpart in GraphQL.



Figure 4:The reservation query. The argument and resolve parameters are defined unlike in Figure 3.

The resolve function gets passed a context, which contains all the arguments and subfields from the GraphQL query. In the function you can then build up a query to access data depending on what is in the GraphQL query. The arguments can end up triggering complex filters, not just equality checks, and could include sorting.

In GraphQL, there are not just “queries”, there are also “mutations” that allow data change, and “subscriptions” that allow real-time updates. These are wrapped up in a schema, although I am only using queries here. The schema is shown in Figure 5.



Figure 5:The schema used in the example.

All these classes are made available through dependency injection in Startup.cs as shown in Figure 6. Every GraphQL type needs added, and the Query is retrieved in the Schema through the service provider.



Figure 6:The Startup.cs showing the level of dependancy injection required.

The resolve function was originally a list of if-else statements with similar structure. I changed it to a series of chained calls to the same function to remove code duplication and improve readability. I also added conditional inclusion so that the extra fields are only included if they exist in the GraphQL query. This cuts down on the cost of database calls. These methods are shown in Figure 7.

Overall GraphQL is something I will consider in a future project. Once the initial hurdle has been overcome it is powerful, and can be backed up by a standard API if necessary.

Expressions



Figure 7:IQueryable extensions to enable conditional including and generic equal functions.

I wanted to be able to pass a lambda to select a field in the class, a string for the argument and a list of validation functions with messages. I am using Entity Framework Core (EF) to do the database calls, so to avoid execution of the query until the end, I had to write the lambda as an expression. Expressions are the form the C# compiler keeps the function logic until they are compiled and are also used by EF to translate queries into SQL, instead of C#.

In C# you can define a lambda as an Expression<Func<>> and C# will automatically convert the lambda into an expression. However, building on an expression requires you to use the expression tree API and define every little part of the lambda including parameters to build up the tree. In the AddEqual method, you can see the method I wanted to write commented out at the end of the return line. The expression tree building took four statements to build up, by defining the next small bit of the function its own statement. In the end though, it allows the same method to be used for a generic type where you want to check equality in an EF query.

As an aside, checking equality generically for all types in a function (value vs reference, nullable vs non-nullable) required a call to EqualityComparer<T>.Default.Equals(x, default) instead of just using == or .Equals().

In the Include function I had to pass an expression and examine the PropertyInfo to check if that property exists in the subfields.

2 November 2017

C# as a Scripting Language - and in Fieldscapes?

By: Iain Brazendale

Daden U days give me the opportunity to play with ideas that have been floating around at the back of my mind for some time and this Daden U day was no exception.

I’ve been reading good things about the changes Microsoft have been doing to their .NET complier platform “Roslyn” particularly with regards to adding scripting support. It was this combined with thoughts of how we could easily add additional functionality to Fieldscapes that made me decide it was time to take a deeper look at scripting.

The advantage of scripting provided through .NET compiler is that there’s no need to learn yet another scripting language, scripts are simply written in C# but with looser syntax requirements.


Following the article quickly gave me a rough working console application to do some testing with:






This example shows accessing an array containing the names of images for different days of the week. The third query to me shows the real power of the script – here the day of the week becomes the index into the images and returns the correct images for the day of the week (You guessed it – I ran this example on a Tuesday). The ability to show a different image for each day of the week is not something that is ever likely to be baked into Fieldscapes, however, adding scripting support allows this new functionality to be added with a single line of script.

This example below shows how picking of images at random can be achieved.





However, with great power comes great responsibility… if we let users add their own scripts then they could take advantage:








Here we can see that users may access functionality that wasn’t intended, in this case displaying inappropriate messages. Also of note, as you can see from my several attempts to get the syntax right (C# is case sensitive), it could be fiddly for people to write scripts without the use of a good IDE correcting those minor typos. These issues suggest that scripting is something that should initially be left to the “advanced” users and more thought and design will be needed before it becomes a “typical” user feature.

So, when will scripting be added Fieldscapes? Unfortunately, scripting requires .NET 4.6 and Roslyn. Unity still uses .NET 3.5 with a non-Roslyn compiler so as wonderful as this technology looks it won’t be a scripting solution for Fieldscapes until the tech catches up. However, it could be a useful technology for Daden’s other products such as Datascape.







16 November 2015

DadenU Day: MongoDB

By: Iain Brazendale, Development Manager

Weather data from OpenWeatherAPI routed to a MongoDB database, and then displayed in Datascape 2

At Daden we all enjoy new challenges, so once in a while we take a day out to do some blue skies research and spend a day working with technologies that we find interesting. These days are known as Daden U days and help the team to take a wider look at technology and encourage innovation.

I’ve always had an interest in Databases but have never had the opportunity to look into NoSQL, so for the Daden U day I spent some time investigating MongoDB.

MongoDB unlike traditional SQL databases is a document database and as such stores its data in an unstructured way. I love how easy it is to get JSON data into the database and extract it.

I’ve got to say a big well done to the team at MongoDB, the getting started documentation is some of the best I’ve seen. Being able to dive right into documentation specifically aimed at C# was fantastic. Installing MongoDB, adding data and writing the first program to read the data took less than five minutes. Trust me when I say this was a lot shorter than my first adventures (many years ago) with MSSQL and Perl.

So was the Daden U day worth it? Well I now know more about NoSQL than I did last week, and more importantly it has encouraged me to learn more. Was it worth it to the company? Well funnily enough a few days after the Daden U day a new client asked me “Do you know anything about MongoDB” and I was happy to reply “Yes”.