# Slim Framework

## Summary


Slim is a minimalistic PHP framework for implementing APIs. At its core, we can see it simply as a "routing library". It receives HTTP requests, routes them to the correct callback functions, and forwards the HTTP responses. By being minimal, Slim is fast and efficient. Unlike fullstack frameworks, developers don't end up installing lots of features that they may never use. 

Slim uses the concept of **middleware**. Each middleware can implement something specific. By chaining together many such middleware, complex web applications can be built. Many third-party middleware are available that implement authentication, security, view templating for generating HTML responses, caching, and more. 

Slim is open source and maintained by a community of developers. It can be used on its own (server-side rendering) or used alongside frontend frameworks such as React or Vue (client-side rendering).

## Discussion

### Why should I prefer Slim over so many other PHP frameworks?

Slim is a good choice if you're looking for "performance, efficiency, full control and flexibility". Slim supports standard interfaces such as PSR-7 and PSR-15. This prevents vendor lock-in. Slim framework plays well with good software practices including SOLID principles, design patterns, security principles and dependency injection. 

Slim's easier to learn than fullstack frameworks such Laravel or Symfony. Fullstack frameworks provide many things out of the box: authentication, security, database integration, template engines, session management, and more. With Slim, these are outside the core framework. They're available as middleware from third-party vendors. Developers can install them via Composer only if and when their app needs them. 

Slim is suited for building modern RESTful APIs and services where data is exchanged in JSON or XML formats.   Complex apps can also be built since the core framework can be extended with middleware. Complete web pages can be rendered on the server side with templating engines such as Twig-View or PHP-View. This brings Slim into the domain of MVC frameworks.  Developers have used Slim backend with Next.js frontend. SPAs with Slim and Vue.js are possible. 


### How's the performance of Slim?

In a performance study from 2016, Slim v2.6 ranked fifth in terms of throughput (requests per second), peak memory usage and execution time. Phalcon and Ice were the best. In another study from 2017, Slim 3.0 ranked third behind Phalcon and CodeIgniter. It performed better than microframeworks Silex and Lumen.  

Slim's routing is based on FastRoute, which optimizes the parsing of regular expressions via chunking. 


### What are the key features of Slim?

The key features of Slim include these: 

    + **Routing**: HTTP requests are efficiently routed to mapped callbacks. Routes are matched using regular expressions that can also capture and pass parameters into the callbacks. A callback is usually a function or a method of a class.
    + **Middleware**: Built-in or third-party middleware allow specific handling of requests and responses. Developers can also write custom middleware. The middleware approach is modular and flexible: middleware can be reordered or disabled if needed.
    + **PSR-7 Support**: HTTP messages interfaces conform to PSR-7 specifications. Slim provides an implementation of this interface but developers are free to adopt any alternative implementation.
    + **Dependency Injection**: This makes the app more testable or configurable. The interface is PSR-11 compliant.

### Could you share details of how Slim middleware work?

In Slim, middleware can be visualized as concentric circles. Middleware are called from the outermost to the innermost circles. At the center, the application executes and routing takes place. Subsequently, middleware are again processed but in innermost-to-outermost circles.  Another useful visualization is the LIFO stack. 

Suppose we have two middleware: authentication and caching. Authentication middleware is executed first. If authentication fails, app skips further processing. If authentication succeeds, then caching middleware is executed. If response exists in the cache, app uses the cache and skips the main callback processing. If cache doesn't exist, the main callback is executed that generates the response. Then caching middleware is called to store the response in the cache if necessary. Finally authentication middleware is called to complete or modify the response if needed. 

Slim middleware deal with PSR-7 request/response objects and PSR-15 request handler object. Middleware can be added to the app object and thus potentially called with every request. Or it can be added to only specific routes, in which case such middleware are called after routing is done. In both cases, outermost middleware is added last. 


### Which are the packaged middleware in Slim?

Default Slim installation comes packaged with a few middleware:

    + **Routing**: Implements routing based on *FastRoute* but developers can choose to use a different implementation.
    + **Error Handling**: Useful during development but also in production where errors can be logged for later analysis.
    + **Method Overriding**: Process `X-Http-Method-Override` HTTP header. For example, a `POST` request with `X-HTTP-Method-Override:PUT` header can be treated as a `PUT` request.
    + **Output Buffering**: Append to the current response body by default but this can be changed to "prepend" mode.
    + **Body Parsing**: When implementing APIs, response is often in JSON or XML. This middleware handles these formats.
    + **Content Length**: Appends `Content-Length` header to the response.

### What's the application lifecycle in Slim?

A Slim app is first instantiated with the call to `Slim\App()`. It's common to do this via the factory method `AppFactory::create()`. For each of the HTTP methods (such as GET, POST, DELETE, etc.) routes can be defined. Then middleware are added. Finally, the application is executed by calling the app object's `run()` method. 

App middleware execute in outermost-to-innermost order. When it reaches the innermost layer, application despatches the HTTP request to its suitable route object. If this route has its own middleware, they're executed in the same outermost-to-innermost order. Then control passes from the innermost to outermost middleware. Finally, application serializes and returns the HTTP response.  


### How can I create routes in Slim?

Slim framework allows us to define routes for various HTTP methods: GET, POST, PUT, DELETE, OPTIONS, PATCH. It's possible to define a route for all methods using `$app->any()` method or for multiple methods such as in `$app->map(['GET', 'POST'])`. 

Each route method accepts a **pattern** that's used to match against the URI of the HTTP request. **Placeholders** within the pattern are delimited using `{}`. Moreover, placeholders can be regular expressions. Optional parts of the pattern are delimited using `[]`. For instance, `$app->get('/users[/{id:[0-9]+})` wold match "/users" (since `id` part is optional) and "/users/23" (since `id` is a valid positive integer). 

Each route method also accepts a **callback**, which is a PHP callable with three arguments: Request, Response and Arguments. The values captured by placeholders are passed as arguments. In the above example, `id` is accessed as `$args['id']`. Callback can be specified as an anonymous function, a method defined in a class, a class that implements the `&lowbar;&lowbar;invoke()` method, etc. 

Routes can be grouped to make code more maintainable. Thus, URIs `/users/{id:[0-9]+}` and `/users/{id:[0-9]+}/reset-password` can be grouped into `/users/{id:[0-9]+}`. 


### What are some online resources to get started with Slim?

Beginners can start with the official Slim documentation. This introduces Slim with a simple example and then goes into the details. For latest updates, visit the Slim blog. To get help from the community, head to the discussion forum.

For step-by-step guides to developing APIs or apps with Slim, see the Slim Walkthrough and Rob Allen's Building Modern APIs with Slim Framework.

For ideas on how to organize a complex Slim-based app, see an example filesystem layout (slide 18) . Read about architecting a layered structure. A Slim v4 starter project is also available.

Curated list of PSR-15 middleware are available at psr15-middlewares and awesome-psr15-middlewares.

Those who wish to contribute the framework itself, can find Slim's codebase on GitHub.

## Milestones

Sep  
2010

Josh Lockhart invents the Slim framework with a focus on simplicity and rapid application development. He feels that alternatives such as Symfony, Cake and CodeIgniter have steeper learning curves and too big for his needs. 

Sep  
2011

The Slim blog illustrates a simple "Hello World" example with the Slim framework. App is initialized with the call `$app = new Slim()`. Routes are configured using `$app->get()`, `$app->post()`, and so on. Application execution is trigger with the call `$app->run()`. All of this can be placed in the file *index.php*. Via Apache's *.htaccess* file, requests can be directed to *index.php*. 

Apr  
2012

**Slim v1.6.0** is released. Framework architecture is based on the Rack Protocol. Application-wide **middleware** is introduced. Request/response interfaces, session handling, cookie handling and logging are improved. It's also announced that Slim can now be installed via Composer. 

Sep  
2012

**Slim v2** is released. It requires at least PHP 5.3. It's PSR-2 compliant and uses **namespaces**. 

Jul  
2013

**Slim v2.3.0** is released in a backward compatible manner. Environment, request, response, view and log objects can be accessed as public properties of the application instance. Route groups are added. Headers and cookies can be easily accessed in Request objects and easily set in Response objects. 

Dec  
2015

**Slim v3.0.0** is released. New features include support for dependency injection and PSR-7. Methods expect interfaces rather than concrete implementations. By November 2019, this evolves to Slim v3.12.3. 

Aug  
2019

**Slim v4.0.0** is released. This release requires PHP 7.1 or newer. It supports PSR-15 compliant middleware. Framework is decoupled from built-in PSR-7 implementation. Thus developers can use alternatives such as Zend, Nyholm and Guzzle. Likewise, routing, error handling and response emitting implementations are decoupled from the framework core. Routing is via `Slim\Middleware\RoutingMiddleware`. App factory is introduced. By March 2022, this evolves to Slim v4.10.0.