uCalc API Version: 2.1.3-preview.2 Released: 6/17/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
Project: Developing a Basic Web Server Route Matcher
Product:
Class:
A step-by-step guide to building a simple web server route matcher using the uCalc Transformer's declarative patterns.
Remarks
💡 Project: Developing a Basic Web Server Route Matcher
A core task for any web server is routing: mapping an incoming URL path like /users/123 to the correct application logic (a "handler") and extracting any dynamic parameters (like the user ID 123). This project will guide you through building a simple but powerful route matcher using the declarative patterns of the uCalc Transformer.
The Goal: A Simple Routing DSL
We'll create a Domain-Specific Language (DSL) for defining routes that is common in modern web frameworks like Express.js or Flask. Placeholders for dynamic segments are enclosed in curly braces.
/users/{id}/products/{category}/{id}
The Strategy: Transformer Rules
The core idea is to treat routing as a text transformation problem. We'll take an incoming URL path and transform it into a string that represents the action to take.
- Input:
/users/42 - Rule:
FromTo("/users/{id}", "Handler: UserProfile, id: {id}") - Output:
"Handler: UserProfile, id: 42"
The application can then easily parse this output string to call the correct function with the extracted parameters.
Step 1: Setting Up the Transformer
First, we need a Transformer instance. This will be our router. We will define all our route patterns on this object.
using (var router = new uCalc.Transformer()) { // ... rules will go here ...}Step 2: Defining the Routes
Each route is a FromTo rule. The pattern matches the URL structure, and the replacement string defines the output.
Static Route: A simple, fixed path.
router.FromTo("/about", "Handler: AboutPage");Dynamic Route: A path with one or more variable placeholders.
router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}");
Step 3: Precedence Matters (LIFO)
What happens if you have two similar routes, like /users/new and /users/{id}? A request for /users/new could technically match both patterns. To resolve this, the Transformer uses a LIFO (Last-In, First-Out) precedence rule: the most recently defined rule is checked first.
Therefore, you must define your most specific rules last to give them higher priority.
// General rule defined first (lower priority)router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}");// Specific rule defined last (higher priority)router.FromTo("/users/new", "Handler: CreateUserPage");Step 4: Matching an Incoming URL
To process a request, simply call Transform() on the incoming URL string. If the result is different from the original URL, a match was found. If it's unchanged, it's a "404 Not Found."
⚖️ Why uCalc? (Comparative Analysis)
- vs. Regex: Building a router with regular expressions is common but can be complex. Each route requires a carefully crafted regex, and managing their precedence can be tricky. uCalc's patterns are more readable (
/users/{id}vs./users/(\w+)), and the LIFO precedence is a clear, built-in system. - vs. Manual String Splitting: Splitting the URL by
/is brittle and doesn't handle complex patterns or constraints well.
uCalc provides a declarative, token-aware, and extensible way to define a routing system that is both powerful and easy to maintain.
Examples
A succinct example defining one static and one dynamic route, then matching a URL against each.
using uCalcSoftware;
var uc = new uCalc();
using (var router = new uCalc.Transformer()) {
// Define routes
router.FromTo("/home", "Handler: HomePage");
router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}");
// Test routes
Console.WriteLine($"Matching '/home': {router.Transform("/home")}");
Console.WriteLine($"Matching '/users/42': {router.Transform("/users/42")}");
}
Matching '/home': Handler: HomePage
Matching '/users/42': Handler: UserProfile, id: 42 using uCalcSoftware; var uc = new uCalc(); using (var router = new uCalc.Transformer()) { // Define routes router.FromTo("/home", "Handler: HomePage"); router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}"); // Test routes Console.WriteLine($"Matching '/home': {router.Transform("/home")}"); Console.WriteLine($"Matching '/users/42': {router.Transform("/users/42")}"); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
{
uCalc::Transformer router;
router.Owned(); // Causes router to be released when it goes out of scope
// Define routes
router.FromTo("/home", "Handler: HomePage");
router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}");
// Test routes
cout << "Matching '/home': " << router.Transform("/home") << endl;
cout << "Matching '/users/42': " << router.Transform("/users/42") << endl;
}
}
Matching '/home': Handler: HomePage
Matching '/users/42': Handler: UserProfile, id: 42 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; { uCalc::Transformer router; router.Owned(); // Causes router to be released when it goes out of scope // Define routes router.FromTo("/home", "Handler: HomePage"); router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}"); // Test routes cout << "Matching '/home': " << router.Transform("/home") << endl; cout << "Matching '/users/42': " << router.Transform("/users/42") << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Using router As New uCalc.Transformer()
'// Define routes
router.FromTo("/home", "Handler: HomePage")
router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}")
'// Test routes
Console.WriteLine($"Matching '/home': {router.Transform("/home")}")
Console.WriteLine($"Matching '/users/42': {router.Transform("/users/42")}")
End Using
End Sub
End Module
Matching '/home': Handler: HomePage
Matching '/users/42': Handler: UserProfile, id: 42 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Using router As New uCalc.Transformer() '// Define routes router.FromTo("/home", "Handler: HomePage") router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}") '// Test routes Console.WriteLine($"Matching '/home': {router.Transform("/home")}") Console.WriteLine($"Matching '/users/42': {router.Transform("/users/42")}") End Using End Sub End Module
A practical example of a router with multiple rules, demonstrating LIFO precedence and handling of a '404 Not Found' case.
using uCalcSoftware;
var uc = new uCalc();
using (var router = new uCalc.Transformer()) {
// --- Define Routes ---
// General rules first (lower precedence)
router.FromTo("/products/{category}/{id}", "Handler: ProductDetail, category: {category}, id: {id}");
router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}");
// Specific rule last (higher precedence)
router.FromTo("/users/new", "Handler: CreateUserPage");
// --- Simulate Requests ---
string[] urls = {"/users/123", "/users/new", "/products/electronics/567", "/contact"};
foreach(var url in urls) {
var originalUrl = url;
var result = router.Transform(url);
if (result.Text == originalUrl) {
Console.WriteLine($"URL: {originalUrl} -> 404 Not Found");
} else {
Console.WriteLine($"URL: {originalUrl} -> {result}");
}
}
}
URL: /users/123 -> Handler: UserProfile, id: 123
URL: /users/new -> Handler: CreateUserPage
URL: /products/electronics/567 -> Handler: ProductDetail, category: electronics, id: 567
URL: /contact -> 404 Not Found using uCalcSoftware; var uc = new uCalc(); using (var router = new uCalc.Transformer()) { // --- Define Routes --- // General rules first (lower precedence) router.FromTo("/products/{category}/{id}", "Handler: ProductDetail, category: {category}, id: {id}"); router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}"); // Specific rule last (higher precedence) router.FromTo("/users/new", "Handler: CreateUserPage"); // --- Simulate Requests --- string[] urls = {"/users/123", "/users/new", "/products/electronics/567", "/contact"}; foreach(var url in urls) { var originalUrl = url; var result = router.Transform(url); if (result.Text == originalUrl) { Console.WriteLine($"URL: {originalUrl} -> 404 Not Found"); } else { Console.WriteLine($"URL: {originalUrl} -> {result}"); } } }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
{
uCalc::Transformer router;
router.Owned(); // Causes router to be released when it goes out of scope
// --- Define Routes ---
// General rules first (lower precedence)
router.FromTo("/products/{category}/{id}", "Handler: ProductDetail, category: {category}, id: {id}");
router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}");
// Specific rule last (higher precedence)
router.FromTo("/users/new", "Handler: CreateUserPage");
// --- Simulate Requests ---
vector urls = {"/users/123", "/users/new", "/products/electronics/567", "/contact"};
for(auto url : urls) {
auto originalUrl = url;
auto result = router.Transform(url);
if (result.Text() == originalUrl) {
cout << "URL: " << originalUrl << " -> 404 Not Found" << endl;
} else {
cout << "URL: " << originalUrl << " -> " << result << endl;
}
}
}
}
URL: /users/123 -> Handler: UserProfile, id: 123
URL: /users/new -> Handler: CreateUserPage
URL: /products/electronics/567 -> Handler: ProductDetail, category: electronics, id: 567
URL: /contact -> 404 Not Found #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; { uCalc::Transformer router; router.Owned(); // Causes router to be released when it goes out of scope // --- Define Routes --- // General rules first (lower precedence) router.FromTo("/products/{category}/{id}", "Handler: ProductDetail, category: {category}, id: {id}"); router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}"); // Specific rule last (higher precedence) router.FromTo("/users/new", "Handler: CreateUserPage"); // --- Simulate Requests --- vector<string> urls = {"/users/123", "/users/new", "/products/electronics/567", "/contact"}; for(auto url : urls) { auto originalUrl = url; auto result = router.Transform(url); if (result.Text() == originalUrl) { cout << "URL: " << originalUrl << " -> 404 Not Found" << endl; } else { cout << "URL: " << originalUrl << " -> " << result << endl; } } } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Using router As New uCalc.Transformer()
'// --- Define Routes ---
'// General rules first (lower precedence)
router.FromTo("/products/{category}/{id}", "Handler: ProductDetail, category: {category}, id: {id}")
router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}")
'// Specific rule last (higher precedence)
router.FromTo("/users/new", "Handler: CreateUserPage")
'// --- Simulate Requests ---
Dim urls() As String = {"/users/123", "/users/new", "/products/electronics/567", "/contact"}
For Each url In urls
Dim originalUrl = url
Dim result = router.Transform(url)
If result.Text = originalUrl Then
Console.WriteLine($"URL: {originalUrl} -> 404 Not Found")
Else
Console.WriteLine($"URL: {originalUrl} -> {result}")
End If
Next
End Using
End Sub
End Module
URL: /users/123 -> Handler: UserProfile, id: 123
URL: /users/new -> Handler: CreateUserPage
URL: /products/electronics/567 -> Handler: ProductDetail, category: electronics, id: 567
URL: /contact -> 404 Not Found Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Using router As New uCalc.Transformer() '// --- Define Routes --- '// General rules first (lower precedence) router.FromTo("/products/{category}/{id}", "Handler: ProductDetail, category: {category}, id: {id}") router.FromTo("/users/{id}", "Handler: UserProfile, id: {id}") '// Specific rule last (higher precedence) router.FromTo("/users/new", "Handler: CreateUserPage") '// --- Simulate Requests --- Dim urls() As String = {"/users/123", "/users/new", "/products/electronics/567", "/contact"} For Each url In urls Dim originalUrl = url Dim result = router.Transform(url) If result.Text = originalUrl Then Console.WriteLine($"URL: {originalUrl} -> 404 Not Found") Else Console.WriteLine($"URL: {originalUrl} -> {result}") End If Next End Using End Sub End Module