Rapid proof of concept using PostGraphile with Docker to build a C# WinUI 3.0 desktop app

We need to rapidly build a proof of concept to assert whether we could start using Project Reunion 0.5 (WinUI) in C#. The functional domain is a physiotherapy management software.

Adrien Pellegrini
8 min readMay 21, 2021

[proof of concept]

evidence, typically deriving from an experiment or pilot project, which demonstrates that a design concept, business proposal, etc. is feasible.

Oxford Dictionaries

Developing a proof of concept should be quick and focus only on the purpose of the experiment. Also, the proof of concept should be functional and usable. Consequently, having good data is almost an implicit requirement of any proof of concept.

Yet, anyone could argue that providing a satisfactory dataset is quite challenging. A lot of time being misspent in data generation as well providing these data through an API should be avoided.

Several tools and services exist to tackle this. There are services like Hasura or Prisma but, in this article, I choose to use PostGraphile. The primary reason is the ability to run everything on my local computer using Docker.

But, what is PostGraphile?

Instantly spin-up a GraphQL API server by pointing PostGraphile at your existing PostgreSQL database.

PostGraphile automatically detects tables, columns, indexes, relationships, views, types, functions, comments, and more — providing a GraphQL server that is highly intelligent about your data, and that automatically updates itself without restarting when you modify your database.

by Graphile | Powerful, Extensible and Performant GraphQL APIs Rapidly

PostGraphile (with GraphQL and PostgreSQL) + Docker

Functional context of the proof of concept

One of the requirements of our proof of concept is to assert the performance of a search box component. Every use of our application starts by searching for patients’ information. Henceforth, the search feature was deemed critical. It makes sense to invest time early to measure if such functionality could be improved within the next release of our application.

Computer requirements

Hereafter, you can find which components are required to follow this article and an explicit version for each of those components.

  • Windows 10 Pro Insider — build 21376
  • WSL 2 — Ubuntu Focal 20.04.2 LTS
  • Docker Desktop — 3.3.1 (with WSL integration)
  • .NET 5.0 SDK — 5.0.300-preview.21180.15
  • Visual Studio 2019 — 16.10.0 Preview 2.1
  • Azure Data Studio — 1.29.0-insider

Quickly setting up the environment

Developing with Docker has become the de facto standard for local development. Especially, Docker Compose makes our life so much easier.

Without any further delay, let’s define the docker-compose.yml file containing the multiple containers needed to run our proof of concept with:

  • a PostgreSQL database
  • a PostGraphile GraphQL API server

To start the containers, we use the docker-compose up -d command-line:

We can check if our containers are started using the docker ps -a command-line:

Unfortunately, the PostGraphile container exited directly after its creation. If we inspect the logs with docker logs postgraphile we can see the error.

In fact, the PostgreSQL database needs more time to start-up for the first time. As a result, the PostGraphile container failed to start. If we wait a few more seconds and run again the docker-compose up -d command-line again, it will start successfully.

The next step is obvious, we need to create tables and seed the database with data.

Azure Data Studio

I am a heavy user of Azure Data Studio. It enables us to work with PostgreSQL databases using the azuredatastudio-postgresql extension.

Let’s see if we can correctly connect to our database container.

We can configure a new connection with PostgreSQL connection type:

And then connect to the database successfully. The database is, as expected, empty.

The next goal is to inject our sample data.

Entity Framework to quickly seed data

Now that we have the PostgreSQL database available, we need to create some tables and add some data. Creating the required tables for the proof of concept is quite easy using SQL. Generating the seed data is unfortunately a cumbersome process using only SQL.

Another alternative is to seed data using C# code. To do so, we can use Entity Framework Core for PostgreSQL: Npgsql.EntityFrameworkCore.PostgreSQL.

Two tables will be created: Patients and Providers.

In an attempt to generate near-accurate sample data, we can use Bogus: A simple and sane fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js. (github.com).

Straight away, we can validate the seeding result using Azure Data Studio.

API server

The search functionality of our proof of concept will perform a lookup against a list of patients. This operation will be performed using the GraphQL API that PostGraphile creates automatically.

Since it’s a GraphQL server, we have also access to the playground interface using GraphiQL IDE.

However, the GraphQL schema is empty.

As the container was created before the tables in the PostgreSQL database, we need to restart the PostGraphile container.

After restarting, we can verify the schema again in the GraphiQL IDE and, for example, load all patients.

For some curious folks who looked further at the GraphiQL tool, you probably noticed that the filtering capabilities of the default PostGraphile docker image are not sufficient enough for what we need to achieve.

As a reminder, we are going to search for patients using their names, date of birth, or national identification number.

The condition query filter allows us only to match a string.

PostGraphile plugins

PostGraphile provides plugins to extends its functionality. For example, the plugin postgraphile-plugin-connection-filter adds a powerful suite of filtering capabilities to a PostGraphile schema.

Here is a list of useful plugins:

For a more extensive list go to the PostGraphile community plugins page.

New docker images for PostGraphile with plugins and PostgreSQL

To add those plugins, we need to customize the docker-compose.yml file and create a custom Dockerfile for both PostGraphile and PostgreSQL database.

After building the new docker images using docker-compose build, we can recreate the containers using docker-compose up -d.

New capabilities are now offered in the GraphiQL IDE such as advanced filtering, simplified names and subscriptions.

Calling the API from Project Reunion 0.5 (WinUI) and Reactive extensions

The proof of concept will be a desktop application written in C# and XAML. It will use the new Project Reunion 0.5 preview — Visual Studio project templates.

The proof of concept will allow the user (a care provider) to log-in into the application. After a successful attempt, the user will be redirected to the search feature where he can look up patients. And finally, the user will be able to disconnect from his account (and start over, if needed).

To summarize promptly, the proof of concept will require the following features:

  • a minimal working application lifecycle;
  • basic navigation to multiples views;
  • calling an external API;
  • displaying a loading indicator;
  • searching for patients;
  • refining the search criteria multiple times in a responsive and reactive manner.

First and foremost, let’s bootstrap a new Blank App, Packaged (WinUI 3 in Desktop) with Visual Studio 2010 Preview.

After creating the LoginView page, the ShellView page, the SearchView page and the NavigationService, we can finally call the PostGraphile GraphQL API.

LoginView (design taken from the ContosoAirlinePOS demo app)
SearchView

To search for a patient named “Tami”, we use the following GraphQL query:

The call to the GraphQL API server is an HTTP POST request (using the HttpClient class). The previous GraphQL query needs to be embedded into the request payload within a query property (and next to an optional variables property).

The result would be:

To produce a more realistic sample, we will use the Reactive Extensions to display the loading indicator and cancel a previous HTTP request when the user refined his search criteria.

But first, let’s preview the XAML code of the SearchView page:

The view follows the MVVM pattern and so, a ViewModel is coupled to it. Inside this ViewModel, we initialize the observables triggered when the user write the search criteria inside the TextBox.

On L.20, the view binds the TextChanged event to an observable.

rxui:FromEventTextBox.TextChangedSubject="{x:Bind ViewModel.SearchInputChanged, Mode=TwoWay}

Here is the observable defined in the ViewModel and how it is initialized:

Here (at last!), a preview of the proof of concept:

Conclusion

On a final note, PostGraphile is really simple to use and required little to no effort. It allows us to focus on the (proof of concept) features instead of all the boilerplate needed to make it works.

I did not know PostGraphile and I am very happy to have discovered it recently. It would have saved me a lot of time on my development in the past.

--

--