Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk4 min

C++20 Web Framework Design: Four Lessons from Building Mach

Building Mach taught Asaf Dahan that API convenience has implementation costs, ownership choices depend on context, routers need edge-case tests, and release timing can justify deferring a feature.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Building Mach, a C++20 web framework, taught Asaf Dahan four practical lessons: a simple API takes deliberate engineering, abstractions need clear ownership boundaries, plausible code still needs adversarial tests, and a worthwhile feature may be better deferred than rushed into a release. These are lessons from one project, not rules proven optimal for every framework.

1. A simple C++ API takes deliberate work

For Mach, Dahan wanted handlers to accept useful inputs without imposing an arbitrary parameter order. The framework’s examples include handlers with no arguments, a request body, a context, or both a body and context in either order. Rather than require users to memorize one convention, Mach inspects handler signatures at compile time, then binds incoming data and invokes the selected handler at runtime. The convenience at the call site depends on machinery behind it.

As an Amazon Associate I earn from qualifying purchases.

The same principle shaped request validation. In Dahan’s account, a request type provides a validate() method, identifies fields with member pointers, and declares rules such as minimum or maximum length. Mach validates the body and returns a 400 response with errors when validation fails. This is an implementation choice in Mach, not a capability to assume of C++ frameworks generally.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The design question is not simply whether an API can hide complexity. It is whether hiding that complexity removes a real burden for the framework’s users—and whether the resulting implementation is worth maintaining. In Mach’s handler example, avoiding a needless ordering rule was the intended payoff.

2. Put abstractions and object lifetimes in the right places

Use indirection where its cost fits

Dahan used PImpl for AppBuilder to separate its public interface from its implementation. Its implementation uses a unique_ptr, which introduces a heap allocation. He accepted that cost during application setup, while being more cautious about adding it to an object created for every request. This is a contextual trade-off, not a measured performance result.

The useful distinction is where an object is created and how often that path runs. An allocation accepted during setup may be a different decision from one added to a high-frequency request path. Dahan’s account does not provide benchmarks comparing alternatives, so it supports a design consideration, not a claim about the size of the cost.

Make ownership and borrowing explicit

Dahan describes learning to distinguish storing an object, borrowing it, transferring ownership, and sharing its lifetime. He used unique_ptr extensively and shared_ptr where shared lifetime made sense, including asynchronous operations. He says he finished Mach without writing an explicit new or delete. That is his experience with this project, not a claim that manual allocation is always wrong.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Build on infrastructure when it lets the project focus

Mach used Boost.Asio and Boost.Beast for asynchronous networking and HTTP, and spdlog for logging. Dahan’s rationale was to concentrate his effort on Mach’s architecture and behavior rather than recreate substantial infrastructure. That choice illustrates a boundary: a framework author can spend effort on the behavior that makes the framework distinct while relying on existing components for other needs.

3. Test the cases that make plausible code fail

A router may need to reconsider an earlier choice

Dahan’s route example registers /a/{param}/c and /a/b/d, then receives /a/b/c. A router that tries the static b branch first follows the second route’s shape, but reaches a dead end at the final segment. The parameterized route would match: b can be the value of {param}.

Mach’s traversal was changed to backtrack. It tries the preferred static path first, then tries the parameterized path if the first choice cannot complete. As Dahan puts it, “Recursion was how I solved the problem; the important missing behavior was the ability to reconsider an earlier choice.” The key lesson is not that every router must use recursion, but that a locally sensible match can fail when the rest of the path is considered.

Reject ambiguity and test combinations

Dahan also says Mach rejects route patterns that are ambiguous for the same method, such as /a/{name}/c and /a/{id}/c. The parameter names differ, but both patterns describe the same path shape, so the router cannot distinguish them by URL alone.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

His broader testing lesson is to ask what combinations could break a system that appears to work. That means examining failing tests rather than treating a passing happy path as sufficient—and remembering that tests themselves can contain bugs. The route example gives a concrete way to apply that mindset: combine overlapping route shapes with an input that makes the preferred branch fail only later.

Best Value
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

4. Defer features when release timing makes the risk too high

Dahan wanted handlers to accept typed route and query parameters directly in their signatures. Implementing the feature meant identifying where each parameter came from, validating which combinations were allowed, and integrating the behavior. As Mach approached v1.0 and an API freeze, he judged that there was not enough time to design and implement it properly, so he deferred it rather than force it into the final stretch.

That decision did not mean the feature was impossible or without value. It meant its design and implementation work did not fit the release window. The distinction matters: deferral keeps an idea available for later, while shipping a rushed API can commit users to a design that has not had enough thought or testing.

Dahan’s account says Mach v1.0 binds request bodies to handler parameters. It does not establish the framework’s current release status, compatibility, or maintenance state. The source for these project-specific lessons is Asaf Dahan’s account of building Mach.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.