Learning path

The full stack learning path, simplified.

The shortest route from zero to a working app. A front-end in HTML, CSS and JavaScript, an ASP.NET Core back-end and a PostgreSQL database, and the two connections that hold them together.

Overview

What a full stack application is.

A full stack application has three parts: a front-end the user sees, built with HTML, CSS and JavaScript, a back-end that does the work, and a database that keeps the data. The front-end and the back-end talk over HTTP. The back-end and the database talk through Entity Framework. This path teaches you all three parts and the two connections between them.

The three parts

01

Front-end

what the user sees
  • Everything that runs in the browser: the pages, the buttons, the forms. Built with HTML for structure, CSS for looks and JavaScript for behaviour.
  • No framework. Plain HTML files, a stylesheet and JavaScript that runs when the page loads.
  • The front-end does not keep the data. It shows data it receives from the back-end and sends the user's input back.
  • It never talks to the database directly. The browser cannot be trusted with a database password.
02

Back-end

where the work happens
  • A program that runs on a server and waits for requests from the front-end. We build it as an ASP.NET Core Web API in C#.
  • Each URL it answers is called an endpoint. For example GET /api/expenses returns the list of expenses.
  • It checks the input, applies the rules of the application (who is allowed to do what, what counts as valid) and reads or writes the database.
  • It sends back a response, usually JSON, that the front-end can show.
03

Database

where the data lives
  • PostgreSQL is a relational database. Data is stored in tables, every table has columns, every record is a row.
  • Tables are linked with keys: a primary key identifies a row, a foreign key points to a row in another table.
  • You talk to it in SQL: SELECT, INSERT, UPDATE, DELETE.
  • It is the only part that survives a restart. If the server reboots, the data is still there.

The two connections

04

Front-end to back-end: HTTP

how the browser talks to the server
  • HTTP is the protocol of the web. The browser sends a request, the server sends back a response. Nothing happens without a request first.
  • A request has a method and a URL. GET reads, POST creates, PUT updates, DELETE removes.
  • A response has a status code: 200 OK, 201 created, 400 bad input, 404 not found, 500 server error.
  • Both sides send data as JSON. The front-end uses fetch to send the request and reads the JSON that comes back.

See it happen

Change the name or the value, press Send, and watch the data travel. The JSON keys on the left become the properties of the C# object on the right.

Front-end browser
JSON
{
  "name": "Coffee",
  "value": 3.5
}
Back-end ASP.NET Core
C# class
public class Expense
{
    public string Name { get; set; }
    public decimal Value { get; set; }
}
Expense object
expense.Name = …
expense.Value = …
1/5

The user fills in the form in the browser.

// Front-end (JavaScript in the browser)
const response = await fetch('/api/expenses', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Coffee', value: 3.5 })
})
const expense = await response.json()
// Back-end (ASP.NET Core minimal API)
app.MapPost("/api/expenses", async (Expense expense, AppDbContext db) =>
{
    db.Expenses.Add(expense);
    await db.SaveChangesAsync();
    return Results.Created($"/api/expenses/{expense.Id}", expense);
});
05

Back-end to database: Entity Framework Core

how C# talks to PostgreSQL
  • Entity Framework Core (EF Core) lets the back-end work with the database using C# classes instead of writing SQL by hand.
  • A C# class is an entity. EF Core maps it to a table: the class becomes the table, its properties become the columns, each object becomes a row.
  • The DbContext is the door to the database. It holds a DbSet for every table and the connection string.
  • You query with LINQ in C#. EF Core translates it to SQL, sends it to PostgreSQL through the Npgsql provider, and turns the rows back into objects.
  • Migrations keep the database in step with your classes. Change a class, add a migration, and EF Core creates or alters the tables.
// Entity: becomes the "Expenses" table
public class Expense
{
    public int Id { get; set; }          // primary key
    public string Name { get; set; }
    public decimal Value { get; set; }
}

// DbContext: the door to PostgreSQL
public class AppDbContext : DbContext
{
    public DbSet<Expense> Expenses { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseNpgsql("Host=localhost;Database=expenses;Username=app;Password=secret");
}

// LINQ in C# ...
var bigOnes = await db.Expenses.Where(e => e.Value > 10).ToListAsync();
// ... becomes SQL in PostgreSQL
// SELECT "Id", "Name", "Value" FROM "Expenses" WHERE "Value" > 10

One request, end to end

  1. The user fills in a form in the browser and clicks Save.
  2. JavaScript on the page sends POST /api/expenses over HTTP with the form data as JSON.
  3. The ASP.NET Core API receives the request and checks the data is valid.
  4. The API adds a new Expense object to the DbContext and calls SaveChangesAsync.
  5. EF Core turns that into an INSERT statement and sends it to PostgreSQL.
  6. PostgreSQL stores the row and returns the new Id.
  7. The API responds with 201 Created and the saved expense as JSON.
  8. JavaScript reads the response and adds the new expense to the page.

Try it

Fill in the form in the Browser card and click Add expense. Your values become the JSON, then the C# object, then the SQL, then a row in the table. Add a few and watch the Ids count up.

Browser
HTML, CSS, JavaScript
Expensesno expenses yet
ASP.NET Core API
C# on the server
POST /api/expenses
name is not empty
value is a number
JSON → Expense object
Entity Framework Core
C# objects to SQL
Expense → "Expenses"
db.Expenses.Add(expense)
SaveChangesAsync()
PostgreSQL
the "Expenses" table
IdNameValue
empty
0/8

Fill in the form and click Add expense to send one through the whole stack.

Where to start: pick any topic in the menu. Each one adds a piece of this picture.

Want the full picture?

This path skips the advanced topics on purpose. When you are ready to go deeper, the dedicated paths pick up where this one stops.