Deprecation warning

This course has been deprecated. It's out of date. I'm leaving it here for historical value, but I don't recommend you start this course if you haven't already.

What does it take to build an entire web app from scratch? This course is a longer one. It starts from a barebones project and gradually develops into a complete web app with REST API. Some of the features we develop:

  • REST HTTP API with correct response codes and content-type handling
  • ClojureScript frontend
  • Authentication + Authorization (users, logging in, passwords)
  • A robust data model
  • Deployment

This course is not completed yet. It will be a very long time to develop such a rich application.

Deprecation warning

This course has been deprecated. It's out of date. I'm leaving it here for historical value, but I don't recommend you start this course if you haven't already.

Extra Resources

Register for a free account or log in to access these resources.

  • Ring Spec to Hang on the Wall

    If you program the web in Clojure, you probably use Ring. Even if you don’t, your server is likely Ring compatible.

    Ring has a small SPEC. It’s centered around defining the keys one can expect in the request and response maps. And the exact names for keywords are easy to forget.

    I don’t want to forget. I use Ring often enough that I want a quick reference. A while ago, I printed out a quick summary of the keys for the request and response maps and hung it on the wall behind my monitor. I refer to it frequently.

    If you program the web in Clojure, you might appreciate this printout. If you’re learning, it could be an invaluable reference.

Complete Web App from Scratch

Deprecation warning

This course has been deprecated. It's out of date. I'm leaving it here for historical value, but I don't recommend you start this course if you haven't already.

Lessons

Video time: 05h11m

Hello, World!
  • 7 min

In this first video, we start from an empty project, add the Ring dependencies, and get the server up and running, displaying "Hello, World!" to every request.

Connecting to the Database
  • 19 min

We extend our very simple web server by connecting it to a PostgreSQL database. We use HugSQL to express our SQL and connect. We begin by creating our first table.

Expanding the data model
  • 18 min

Now that we're connected to the database, we build out our data model using CREATE TABLE statements. These will run every time the server is started.

Loading data from a CSV
  • 14 min

Our tables complete, we now turn our attention to the core functionality: reading in a CSV and putting the data into our data model. To read in the CSV, we use clojure.data.csv.

Checking our insertion
  • 21 min

Now that there is data in the database, we can start to ask question about it. How many rows were in the data set? What were the header names? We use those to check our insertion and debug some issues.

Posting files to our server
  • 33 min

We're now ready to develop the upload capabilities of our web server. We make a very barebones routing system using core.match, build in a middleware stack, and add the middleware to handle posting files.

Development workflow
  • 18 min

We build out a development workflow so we don't have to restart the server to test new code.

Static Homepage
  • 8 min

We create a static homepage for the app so that we can talk about how awesome it is.

Logged in styles
  • 11 min

We did styles for the homepage. Now we need to add bootstrap to the logged in sections of the site. We add a new route called /dashboard and make it serve HTML using Hiccup.

Bidi Routes
  • 14 min

We replace our router with Bidi, a bidirectional routing library that plays well with the HTTP library Yada.

Setting up Yada
  • 31 min

We replace our Ring handlers with Yada resources to correctly implement the HTTP spec.

Uploading a file with Yada
  • 13 min

We implement CSV file uploading in Yada and hook it into our CSV importer.

Serving static files from Yada
  • 10 min

We learn how to serve static files using Yada.

Responding correctly to POSTs
  • 4 min

We take manual control of the HTTP response after a POST so we can put in a JSON body.

Cleanup
  • 29 min

After doing everything in one Clojure file, we start to separate everything into namespaces. It's a messy task and we actually break the system. I test and debug it until it works again.

Event Sourcing Design
  • 19 min

We need to design an Event Sourcing system to be used by the rest of the app. I sketch it out on the whiteboard.

Event Sourcing Implementation
  • 44 min

We implement the Event Sourcing system using HugSQL and iterative development at the REPL.

Deprecation warning

This course has been deprecated. It's out of date. I'm leaving it here for historical value, but I don't recommend you start this course if you haven't already.