{"action":"created","issue":{"url":"https://api.github.com/repos/slimphp/Slim/issues/1288","labels_url":"https://api.github.com/repos/slimphp/Slim/issues/1288/labels{/name}","comments_url":"https://api.github.com/repos/slimphp/Slim/issues/1288/comments","events_url":"https://api.github.com/repos/slimphp/Slim/issues/1288/events","html_url":"https://github.com/slimphp/Slim/issues/1288","id":87107052,"number":1288,"title":"Middleware and ServiceProviders","user":{"login":"designermonkey","id":221344,"avatar_url":"https://avatars.githubusercontent.com/u/221344?v=3","gravatar_id":"","url":"https://api.github.com/users/designermonkey","html_url":"https://github.com/designermonkey","followers_url":"https://api.github.com/users/designermonkey/followers","following_url":"https://api.github.com/users/designermonkey/following{/other_user}","gists_url":"https://api.github.com/users/designermonkey/gists{/gist_id}","starred_url":"https://api.github.com/users/designermonkey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/designermonkey/subscriptions","organizations_url":"https://api.github.com/users/designermonkey/orgs","repos_url":"https://api.github.com/users/designermonkey/repos","events_url":"https://api.github.com/users/designermonkey/events{/privacy}","received_events_url":"https://api.github.com/users/designermonkey/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-06-10T21:05:09Z","updated_at":"2015-06-11T00:07:16Z","closed_at":null,"body":"Just following on from a comment @silentworks made in #1275 about ServiceProviders.\r\n\r\n>On a separate note can we stop coupling the ServiceProvider with the actual code for the package. I see this is becoming a pattern that others will follow. Now that we are using Container Interop, we shouldn't bind the actual package to the Pimple ServiceProviderInterface, we should create a separate class in each package to do this.\r\n\r\nI think it was a very valid point, and something we should all discuss to make sure we come up with a convention to suit Middleware we create for Slim (which is available for other frameworks) and Middleware we use from other sources.\r\n\r\nDetails like this are useful to document for developers who come to the framework, and for ourselves.\r\n\r\nOne thing I'd like to bring to the fore is that there are two types of functionality at play here; We have Middleware which are invokable classes, and we have ServiceProviders which provide services via a container, we should be careful not to confuse the two, although a package could indeed provide both, ala Slim-HttpCache.\r\n\r\n## ServiceProviders\r\n\r\nIf we opt for a separate ServiceProvider class, something like `PimpleServiceProvider`, then there would be a problem of how to instantiate a class with constructor options. Take the Slim-Flash package for example, it requires a `$storage` parameter in the constructor.\r\n\r\nThe only way I can see to do it is a bit of a long way round IMO\r\n\r\n```php\r\n\r\n$flash = new Slim\\Flash\\Messages($_SESSION); // I know it's default, but for an example\r\n\r\n$container->register(new Slim\\Flash\\PimpleServiceProvider($flash));\r\n```\r\n\r\nand in the `PimpleServiceProvider`\r\n\r\n```php\r\nclass PimpleServiceProvider implements Pimple\\ServiceProvider\r\n{\r\n    protected $flash;\r\n\r\n    public function __construct($flash)\r\n    {\r\n        $this->flash = $flash;\r\n    }\r\n\r\n    public function register(Container $container)\r\n    {\r\n        $container['flash'] = $this->flash;\r\n    }\r\n}\r\n```\r\n\r\nIs this a pattern everyone would be happy with? It seems a little backward to me as the `ServiceProviderInterface` is meant to be used directly in the class itself.\r\n\r\n\r\n## Middleware\r\n\r\nThis is a simple one, though there are a few different implementations of Middleware out there. We opt for using `__invoke`, so maybe an interface would be a good idea?\r\n\r\nAn interface could define a class as invokable Middleware by requiring it to have a definite footprint.\r\n\r\n```php\r\n\r\npublic function __invoke(RequestInterface $request, ResponseInterface $response, $next = null);\r\n```\r\n\r\nAny additional arguments could be collected using `func_get_args()`.\r\n\r\nI've set `$next = null` in the example, but personally I think that there should always be a `$next` available, even if it is a simple closure that returns the response as it is passed, but that's a preference."},"comment":{"url":"https://api.github.com/repos/slimphp/Slim/issues/comments/110952056","html_url":"https://github.com/slimphp/Slim/issues/1288#issuecomment-110952056","issue_url":"https://api.github.com/repos/slimphp/Slim/issues/1288","id":110952056,"user":{"login":"jensscherbl","id":1640033,"avatar_url":"https://avatars.githubusercontent.com/u/1640033?v=3","gravatar_id":"","url":"https://api.github.com/users/jensscherbl","html_url":"https://github.com/jensscherbl","followers_url":"https://api.github.com/users/jensscherbl/followers","following_url":"https://api.github.com/users/jensscherbl/following{/other_user}","gists_url":"https://api.github.com/users/jensscherbl/gists{/gist_id}","starred_url":"https://api.github.com/users/jensscherbl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jensscherbl/subscriptions","organizations_url":"https://api.github.com/users/jensscherbl/orgs","repos_url":"https://api.github.com/users/jensscherbl/repos","events_url":"https://api.github.com/users/jensscherbl/events{/privacy}","received_events_url":"https://api.github.com/users/jensscherbl/received_events","type":"User","site_admin":false},"created_at":"2015-06-11T00:07:16Z","updated_at":"2015-06-11T00:07:16Z","body":"> Middleware out there. We opt for using __invoke, so maybe an interface would be a good idea?\r\n\r\nFrom my understanding, any callable implementing the expected signature can be a middleware, so not sure if an interface would really be that useful. Same would probably apply to controllers / route callbacks?\r\n\r\nAre there any plans regarding [Relay][1]?\r\n\r\n[1]: https://github.com/relayphp/Relay.Relay"}}