Blazor and Supabase, the perfect duo for developing in record time!
Part 1 : Database
Part 2 : Authentication
Part 3 : Real Time
Introduction:
Blazor, I know it well, but what is Supabase?
Supabase is an open-source development platform, a "cloud back end" that offers tools for building web and mobile applications using a PostgreSQL relational database. It's often seen as an open-source alternative to Google's Firebase, but with SQL-based features.
Supabase provides several integrated services, which we'll use in this article, including:
Database (PostgreSQL): Supabase uses PostgreSQL, a relational database management system, and offers tools for managing databases, including features like SQL queries, relationships, and role management.
Authentication: Supabase provides a ready-to-use authentication solution with user management, including login via email, OAuth providers (Google, GitHub, etc.), and other methods.
Storage: It also offers a storage system for hosting and serving files, similar to Firebase Storage.
Real-time Subscriptions: Supabase allows tracking real-time changes in the database through WebSocket-based subscriptions.
One of Supabase's main strengths is its open-source nature and compatibility with traditional SQL tools, making it popular among developers who want an alternative to Firebase with more flexibility in terms of databases and technology.
But I work with C# ! Do I have to code everything from scratch? Absolutely not! Thanks to the community, a complete library exists. GitHub project : https://github.com/supabase-community/supabase-csharp
Official documentation : https://supabase.com/docs/reference/csharp/introduction
In this article, we will create a simple project and use most of Supabase’s features:
- A database
- JWT-based authentication
- Real-time functionality
What will this project do? How about an app to order Breton crêpes?
Knowledge of Blazor is recommended but not required.
The chosen architecture is simple and not intended for complex commercial projects; the focus is on Blazor and Supabase.
For those interested in adapting this project to clean architecture: https://github.com/jasontaylordev/CleanArchitecture
Our app needs to be launched quickly, so we’ll use a library to make our lives easier: Radzen ! This library will allow us to create complex forms in just a few lines of code. We’ll also use FluentResult to simplify error handling.
Project Overview
- To explore the database aspect of Supabase: The app will allow users to add, edit, and delete crêpes and ingredients.
- To explore the authentication aspect of Supabase: The app will enable users to create and log into an account.
- To explore the real-time aspect of Supabase: The app will display a message to the kitchen staff when a crêpe is ordered or modified.
Setting Up Supabase
Let's get started!
Create a Supabase project:
After creating an account on the Supabase site, click on New Project.
Fill out the form. Region selection can be important if you're handling personal data or if your site's users are mainly in a specific area. Wait a few minutes for the project to be created.
Creating the Database
In the left menu, choose Database, then click “+ New Table.”
- Table "crepes" :
- id: int4 not null \ PK
- name: text not null
- price: float4 not null
- created_at : timestampPtz not null
- image_url : text null
- Table "ingredients" :
- id: int4 not null \ PK
- name: text not null
- created_at : timestampPtz not null
- Table "crepes_ingredients"
- crepe_id: Primary Key \ FK with public:crepes.id \ Cascade on Delete - Cascade on Update
- ingredient_id: Primary Key \ FK with public:ingredients.id \ Cascade on Delete - Cascade on Update
For all these tables, we won’t use RLS security; it should be disabled. This option is important if you want to manage table or record access for specific users only.
Creating the Solution in Visual Studio (or your preferred IDE)
Creating 3 projects:
- BlazorSupabase.Model: Data model containing Supabase entities and Dtos
- BlazorSupabase.Data: Data access
- BlazorSupabase.Web: UI, a Blazor project with InteractiveServer mode for better SEO for our crêperie!
Add a reference to the Supabase NuGet package.
I encourage you to clone and test the project.
If you run into any issues, feel free to contact me!
Here are a few code snippets that might come in handy. Nothing to do with crêpes, but they can be useful.
- To return cities filtered by name or postal code:
public async Task<CityDto> GetBySlugAndDepartmentCodeAsync(string slug, string zipCodeTwoLetters)
{
var result = await _client.From<City>()
.Filter(r => r.Slug, Constants.Operator.ILike, slug)
.Filter(r => r.ZipCode, Constants.Operator.ILike, $"{zipCodeTwoLetters}%")
.Single();
return result?.ToDto();
}
- Using multiple filters:
List<IPostgrestQueryFilter> filters =
[
new QueryFilter("slug", Constants.Operator.ILike, $"%{searchQuery}%"),
new QueryFilter("zip_code", Constants.Operator.ILike, $"%{searchQuery}%"),
];
var cities = await _client.From<City>()
.Or(filters).Order(c => c.Name, Constants.Ordering.Ascending)
.Get();
- To return only specific properties:
var marketCityIds = (await _client.From<Market>().Select("city_id").Get()).Models.Select(m => m.CityId).ToList();