Intro
Trying out new technologies is boring unless you’re utilizing them for the next unicorn SaaS. So let’s build an website uptime monitor where we can:
- create an account
- login with created account
- add and delete websites which can be monitored
- have a overview of the reports generated for the websites
Stack
- C# .NET 6 (Backend)
- Svelte (Frontend)
- TailwindCSS + DaisyUI (Frontend)
- Supabase (Auth + PostgreSQL)
- Quartz.NET (Job scheduling)
Backend
Let’s see how minimal the new approach being used in .NET 6 is.
Models
Website
A list of reports and a reference to the user, nothing fancy.
Report
Our users will be able to add an website to monitor and our background service will periodically execute a GET request to the website and persist the report. The report will contain the date the website was checked, an error if there was one and the response time.
Initializing supabase
Rather than fighting with auth, we’ll just use supabase which offers a very generous free tier 💓, that tier also includes a PostgreSQL database. We’ll use the official C# library provided by supabase. The provided example in the README seems easy enough. Let’s just create an extension method so we have a cleaner Program.cs
Authentication
Validating the JWT Token
You can get the signing key on your supabase settings page. Nothing fancy here, just setting up jwt auth to be able to authorize my endpoints.
Sign Up
First we’ll create our sign up endpoint. We just have to use the SignUp method where we pass an email and password. Easy enough! supabase also offers creating accounts via a magic link or various social providers.
Login
Next step is creating an Login endpoint. Easy as creating an account, just use the SignIn method with an email and password.
Using C# 9 and writing top level statements feels a bit weird, but nothing that I can’t get used to. Thanks to records this ends up being very slim. How nice is this? No annoying controllers. I’ve never been a fan of controllers anyway, as they mostly just end up being a stupid man in the middle delegating the work. The .NET team is definitely on its way to reducing Carpal tunnel syndrome.
API endpoints
We’ll create an extension method to setup our endpoint routing. So simple, expressive and clean. No time wasted on setting up controllers.
User middleware
We’ll create an middleware where we get the user from supabase and append it to the Items dictionary in the HttpContext.
Do note though, that in production you would preferably cache this; to avoid calling the supabase API on every request.
Setting up Quartz NET to process background jobs
Quartz.NET is an excellent job scheduling library. We’ll create an extension method as usual to set it up properly.
To add an job you need to create a class which implements the IJob interface. Here’s what I’ve come up with:
We’ll make use of the DisallowConcurrentExecution attribute as we don’t want the job being run more than one instance at the same time. This is obviously a poor man’s implementation, as this won’t scale. Preferably for your unicorn SaaS you’d have a separate scheduler/queue for every customer or a priority queue, as your pricing model might also offer multiple tiers with different monitoring limits.
CRUD endpoints
The usual CRUD stuff. The user can add a website, delete one and get its available websites and the reports. Here we make use of the middleware and get the user object out of the HttpContext.
Frontend
UI Design
For this design I have utilized my superior creativity and talent, which not many people possess. I’ve used excalidraw (super cool and easy to use) to come up with an extraordinary design.
The result is obviously a masterpiece where I utilize tables, which are indeed very unique.
Svelte 💘
I’ve fallen in love with Svelte, for the past year I have been using it actively. My productivity has exploded, even though the ecosystem is no where equal to react or vue, the simplicity of Svelte makes it really easy to not require a huge ecosystem to implement certain things. Its simplicity really reminds me on .NET 6. For this project I am using SvelteKit, which offers SSR, Routing and many other cool features out of the box! I’m not gonna go deeper into Svelte, feel free to check it out yourself!
Implementing my design
Declaring variables just as you would do it in vanilla js, no need to bother with all the React boilerplate. It feels so refreshing and simple.
Code
Main dashboard component
The table component rendering the reports. I’m a big fan of svelte’s templating language. In my opinion it’s easier on the eyes, at least for me.
Result
👏 Summary
A big praise to the team working on .NET 6. The simplicity, performance and the ecosystem .NET offers is unbeatable in my humble opinion. Combining it with Svelte you now have a toolkit which simply feels unreal when it comes to efficiency.