uCalc API Version: 2.1.3-preview.2 Released: 6/16/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
				
					#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;
   }
}
				
			
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
				
			
Matching '/home': Handler: HomePage
Matching '/users/42': Handler: UserProfile, id: 42
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
				
					#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;
         }
      }
   }
}
				
			
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
				
			
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