Routing Basics

Routing is the heart of Slim: it maps an HTTP method and URL path to a piece of code (a handler) that should run when a matching request comes in. Slim gives you one method per HTTP verb, plus ways to handle multiple verbs on a single route.

Routes for Each HTTP Verb

Slim's $app object exposes a method named after each common HTTP verb:

$app->get('/users', function ($request, $response, $args) {
    $response->getBody()->write("List all users");
    return $response;
});

$app->post('/users', function ($request, $response, $args) {
    $response->getBody()->write("Create a user");
    return $response;
});

$app->put('/users/{id}', function ($request, $response, $args) {
    $response->getBody()->write("Update user " . $args['id']);
    return $response;
});

$app->delete('/users/{id}', function ($request, $response, $args) {
    $response->getBody()->write("Delete user " . $args['id']);
    return $response;
});
Common convention: GET /users lists users, POST /users creates one, PUT /users/{id} updates one, and DELETE /users/{id} removes one. This "resourceful" pattern shows up constantly in REST APIs.

The Three Handler Parameters

Every route handler closure receives the same three parameters, always in this order:

ParameterWhat it is
$requestThe incoming PSR-7 request object — query params, POST data, headers, and more.
$responseAn empty PSR-7 response object you write your output into and then return.
$argsAn associative array of any dynamic route placeholders (e.g. {id}) matched in the URL.

Writing to the Response and Returning It

You never echo output directly in a Slim route handler. Instead you write into the response's body stream and then return that response object:

$response->getBody()->write("Some output");
return $response;
Why you must return it: PSR-7 request and response objects are immutable. Methods that look like they modify the response (like withStatus() or withHeader()) actually return a brand-new object rather than changing the original in place. Slim only sends whichever response object your handler returns — so forgetting to return it means your changes are silently lost.

Handling Multiple Verbs on One Route

If a route should respond to more than one HTTP method, use $app->map() with an array of verbs, or $app->any() to match every verb:

$app->map(['GET', 'POST'], '/contact', function ($request, $response, $args) {
    $response->getBody()->write("Handles GET and POST");
    return $response;
});

$app->any('/ping', function ($request, $response, $args) {
    $response->getBody()->write("pong");
    return $response;
});
Next steps: Continue to Route Parameters to see how dynamic URL segments like {id} actually work, including optional and pattern-constrained parameters.