The quickest way to start the app is with:
docker compose -f fullstack.yml up --buildIt will run everything in containers including database, client and server.
You can cleanup by running:
docker compose -f fullstack.yml down --remove-orphansFor development, you should run both client and server directly from the file-system. Since it will automatically reload when you change the files.
Setup
docker compose up
npm ci --prefix clientClient
npm run dev --prefix clientServer
dotnet watch --project server/ApiYou can also run the applications from your IDE instead if you want a debugger attached.
You can reset the database with:
docker compose down --remove-orphans && docker compose upThe application is a blog-like application with markdown support.
Authentication, authorization, user and session management is something you will implement through a small series of exercises.
All development settings are defined in
appsettings.Development.json.
Settings for deployment can be specified in appsettings.Production.json.
All secrets for deployment should be set using Google Cloud - Secret
Manager.
Here are the URLs to access the various parts.
When running directly from file-system:
| Sub-system | URL |
|---|---|
| Client | http://localhost:5173/ |
| Server | http://localhost:5088/api/swagger/index.html |
| MailCatcher | http://localhost:1080/ |
When running the full stack with docker:
| Sub-system | URL |
|---|---|
| Client | http://localhost:1080/ |
| MailCatcher | http://localhost:1080/ |
client will proxy request with base-path /api to backend.
Database:
| Parameter | Value |
|---|---|
| URL | jdbc:postgresql://localhost:5432/postgres |
| Username | postgres |
| Password | mysecret |
| Connection string | HOST=localhost;DB=postgres;UID=postgres;PWD=mysecret;PORT=5432; |
The application ships with some test data. That includes users with different roles. After implementing authentication, you will be able to log-in using these credentials:
| Email / Username | Password | Role |
|---|---|---|
| admin@example.com | S3cret! | Admin |
| editor@example.com | S3cret! | Editor |
| othereditor@example.com | S3cret! | Editor |
| reader@example.com | S3cret! | Reader |
The example application mostly based on technology you are already familiar with.
- ASP.NET with Controller-based APIs - framework
- PostgreSQL - database
- Docker - containers
- FluentValidation - validation
- Swagger (Swashbuckle) - REST specification & UI
- React - framework
- tailwindcss - styling
- daisyUI - component library
- Axios with swagger-typescript-api - HTTP/API client
- Jotai - state
- React Router
- React Hook Form - form handling & data loading
- yup - validation
- react-markdown - markdown rendering
There are a couple of new libraries that you are (likely) not familiar with on in the client. They aren't that important for the exercises. Just in case you are curious. Here is a quick rundown.
React Hook Form
This is probably the most noticeable difference from what you are used to.
It provides a useForm hook that can take care of managing state + validation
for input elements and submitting forms.
React Router loader
React router is nothing new. But, I'm using the loader api to fetch data from API on route navigation.
You are likely used to load data with useEffect hook like
this.
Loading data through the router simply means it doesn't have to be dealt with
within the component.
yup
Is a validation library similar to FluentValidation (but for React).
react-markdown
It renders text written using Markdown syntax, so it looks nice. Markdown is a simple easy to learn markup language well suited for writing programming documentation. In fact that is how documentation on GitHub is written. This document you are reading right now is written in Markdown.
Complete these exercises in order, since each builds on the previous. Make a commit each time you complete an exercise.