Architecture that remains habitable
Thoughts on Jakarta EE, Scala, UI architecture, and the quiet work of building durable systems.
Building a Complete Web Application with Scala
A practical series that builds a blog with Scala, Scala.js, and PostgreSQL, from an empty repository to a deployed application. Start with the features, the stack, and the path of a request.
From an Empty Directory to a Runnable Project
Create the first working version of our Scala blog. Set up the sbt build, connect Undertow, RESTEasy, and CDI, then verify the HTTP endpoint with a real integration test.
Starting an HTTP Server with Jakarta Components
Connect Undertow, RESTEasy, and Weld through CDI discovery. Add a liveness endpoint, follow a request through its scopes, and verify resource registration and cleanup with real HTTP tests.
Understanding Database Access and Transactions
Connect PostgreSQL, Hibernate, Agroal, and Narayana. Keep one persistence context through response serialization, then verify commit and rollback with real database tests.
Our First Domain Model
Model BlogPost with a UUID, version, unique slug, and publication rules. Discover entities through CDI, map them to PostgreSQL, and verify validation and optimistic locking.
Evolving the Data Model
Adopt an existing PostgreSQL schema with Hibernate DDL Manager, give tables and columns stable identities, and add an optional summary while preserving posts and publication rules.
Describing an Entity with EntitySchema
Define one field model for JSON mapping and typed Criteria queries. Cover every BlogPost field, preserve timestamps, and verify that readable fields remain protected from incoming writes.
Serving Posts through REST
Turn the BlogPost model into a public API. Use entity graphs, the JSON mapper, and Data/Table responses to serve published lists and details, then verify the contract through real HTTP requests.
Building the First Interface with Scala.js
Build a readable journal with the Scala.js UI component DSL. Bind properties, conditions, and lists, serve the page through Undertow, and verify keyboard controls and mobile layout in a real browser.
Connecting the Frontend and Backend
Load published posts into Scala.js models, connect route loaders to the REST API, and handle empty lists, failed requests, and navigation without losing the entity contract.
User Accounts and Sign-In
Create the first administrator and wire Soteria into Undertow for password sign-in, protected sessions, and a Scala.js account form.
Registration and Account Recovery
Verify email ownership before creating reader accounts, deliver single-use links, and reset passwords while revoking existing sessions.
Permissions and HATEOAS
Enforce endpoint, object and field permissions, then let an editorial interface follow the actions offered by each response.
Applying Changes Safely
Prepare entity changes before mutation, enforce current versions, validate the complete result and return useful errors without losing atomicity.
Building a Form from End to End
Bind the post model directly to a form, show field errors and preserve newer edits when saves or conflicts arrive.
Searching, Filtering and Pagination
Use HibernateSearch and CDI providers for typed filters, compact projections and URL-driven pagination that survives reloads and browser history.
Managing Entity Relationships
Model authors and tags as shared entities, accept safe ID-only references, and update relationships deliberately across the API and editor form.
Uploading and Serving Media
Validate image uploads, attach them to posts by reference, authorize each image request by post visibility, and safely clean up abandoned uploads.
Integrating a Post Editor
Add a Markdown editor to the post form, secure embedded image uploads and references, and share one rendering path between preview and public reading.
Translating the Interface
Add English and German routes, a message catalog and a language switch while preserving form state and editorial content.
Translating Blog Content
Add independently published German post translations, consistent localized search and complete English fallback without changing the source article.
Rendering Pages on the Server
Render the existing Scala.js blog with GraalJS so localized posts arrive as complete HTML with the correct HTTP status.
Hydrating the Server-Rendered Page
Keep the server DOM, reuse its initial public response once and attach interactivity without a second initial data request.
Completing the Public Pages
Finish the blog with consistent page metadata, published language links, a sitemap, Atom feeds and HTTP responses that match the content.