Skip to content
Download

Understanding Minimal APIs

Minimal APIs let you define HTTP endpoints directly on your Mach application without creating controller classes.

They are a lightweight way to map routes to handler functions and are well suited to small endpoints, simple services, and applications that do not need the additional structure of controllers.

A minimal endpoint is defined directly on the application:

int main() {
mach::AppBuilder builder;
auto app = builder.build();
app.mapGet("/", [] {
return mach::ok("Hello, World!");
});
return app.run();
}

Here, mapGet() maps GET / to a handler function.

When a request matches the route, Mach invokes the handler and uses its returned reply to produce the HTTP response.

Minimal APIs and controllers both define endpoints, but organize them differently.

A minimal API keeps the route and handler together:

app.mapGet("/users/{id:int}", [](mach::Context& context) {
const int id = context.request.routeParam<int>("id");
return mach::ok(id);
});

A controller groups related actions inside a class:

class UsersController final : public mach::ControllerBase {
public:
inline static constexpr std::string_view route = "/users";
mach::Reply<int> getUser() {
const int id = request().routeParam<int>("id");
return ok(id);
}
static void configure(mach::ControllerBuilder<UsersController>& builder) {
builder.mapGet("/{id:int}", &UsersController::getUser);
}
};

Both approaches use the same routing system. The main difference is how endpoint logic is organized.

Minimal APIs are a good fit when an endpoint is small and does not need the structure of a controller.

They work especially well for:

  • small applications and services
  • simple endpoints
  • health checks and utility routes
  • prototypes
  • endpoints that can remain concise when defined inline

Controllers are often a better fit when many related endpoints need to share organization, dependencies, or controller-specific behavior.

A minimal API handler can receive a mach::Context& when it needs access to request or response data:

app.mapGet("/users/{id:int}", [](mach::Context& context) {
const int id = context.request.routeParam<int>("id");
return mach::ok(id);
});

The context exposes the current request and response for the endpoint.

For route syntax, parameters, and constraints, see the Routing guides rather than redefining those concepts here.


Next, you’ll learn how to define minimal API endpoints for different HTTP methods.