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:

  1. create an account
  2. login with created account
  3. add and delete websites which can be monitored
  4. have a overview of the reports generated for the websites

Stack

  1. C# .NET 6 (Backend)
  2. Svelte (Frontend)
  3. TailwindCSS + DaisyUI (Frontend)
  4. Supabase (Auth + PostgreSQL)
  5. 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.

website_model

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.

report_model

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

supabase_impl

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.

jwt_tokens_validate

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_impl

Login

Next step is creating an Login endpoint. Easy as creating an account, just use the SignIn method with an email and password.

login_impl

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.

api_endpoints

User middleware

We’ll create an middleware where we get the user from supabase and append it to the Items dictionary in the HttpContext.

middleware

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.

quartz_impl

To add an job you need to create a class which implements the IJob interface. Here’s what I’ve come up with:

monitor_job

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.

crud

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.

titanium_impl

The result is obviously a masterpiece where I utilize tables, which are indeed very unique.

laugh

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

dashboard

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.

report_table

Result

dashboard

👏 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.

Link to the project

https://github.com/atresnjo/uptimey