uCalc API Version: 5.7.0-preview.1 Released: 7/30/2026
Warning
uCalc API Preview Release Notice:This preview documentation describes the intended behavior of the API. It is not fully accurate or complete.The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.Use of the preview version in your production code is not recommended.
A step-by-step guide to building a simple web server route matcher using the uCalc Transformer's declarative patterns.
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.
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 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.
/users/42FromTo("/users/{id}", "Handler: UserProfile, id: {id}")"Handler: UserProfile, id: 42"The application can then easily parse this output string to call the correct function with the extracted parameters.
First, we need a Transformer instance. This will be our router. We will define all our route patterns on this object.
csharp
using (var router = new uCalc.Transformer()) {
// ... rules will go here ...
}
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}");
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.
## Step 4: Matching an Incoming URLTo process a request, simply call [Transform()](/reference/classes/ucalc.transformer/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.ID: 1435
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
ID: 1436
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