{"action":"created","issue":{"url":"https://api.github.com/repos/http-message-strategies-interop/fig-standards/issues/6","repository_url":"https://api.github.com/repos/http-message-strategies-interop/fig-standards","labels_url":"https://api.github.com/repos/http-message-strategies-interop/fig-standards/issues/6/labels{/name}","comments_url":"https://api.github.com/repos/http-message-strategies-interop/fig-standards/issues/6/comments","events_url":"https://api.github.com/repos/http-message-strategies-interop/fig-standards/issues/6/events","html_url":"https://github.com/http-message-strategies-interop/fig-standards/issues/6","id":224417225,"number":6,"title":"Reduce scope and simplify PSR","user":{"login":"mindplay-dk","id":103348,"avatar_url":"https://avatars3.githubusercontent.com/u/103348?v=3","gravatar_id":"","url":"https://api.github.com/users/mindplay-dk","html_url":"https://github.com/mindplay-dk","followers_url":"https://api.github.com/users/mindplay-dk/followers","following_url":"https://api.github.com/users/mindplay-dk/following{/other_user}","gists_url":"https://api.github.com/users/mindplay-dk/gists{/gist_id}","starred_url":"https://api.github.com/users/mindplay-dk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mindplay-dk/subscriptions","organizations_url":"https://api.github.com/users/mindplay-dk/orgs","repos_url":"https://api.github.com/users/mindplay-dk/repos","events_url":"https://api.github.com/users/mindplay-dk/events{/privacy}","received_events_url":"https://api.github.com/users/mindplay-dk/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":6,"created_at":"2017-04-26T10:20:07Z","updated_at":"2017-05-26T15:16:07Z","closed_at":null,"body":"I'd like to suggest we reduce the scope of the PSR to dealing with server-side concerns.\r\n\r\nThere are client concerns (mainly async) which are not addressed by the interfaces defined in the current proposal - this is first of all a can of worms, and secondly, there's no real reason not to push this off to a separate PSR, assuming there's any interest or value in such a PSR in the first place.\r\n\r\nI have no particular interest in the client-side interfaces myself - but I have a strong interest in seeing the server-side abstractions standardized, as soon as possible, e.g. before PSR-15 passes; which, if it passes first, will include an identical delegate interface to proxy middleware. It would be better if this interface was standardized first, such that someone could dispatch SPR-15 middleware by passing any custom handler as delegate, such that a single middleware component could be more easily invoked directly without the need to create a dedicated pipe/dispatcher, in some cases, just to dispatch a single middleware component.\r\n\r\nI see no particular reason why the server and client interfaces can't be separate PSRs - it's probably a lot easier to manage and discuss, as asynchronous client operations are radically different and more complex than synchronous server operations, and likely a much smaller community is interested in the details of that.\r\n\r\nI would therefore propose to first of all reduce the scope to the three primary server-side operations:\r\n\r\n1. Request -> Response\r\n2. Request -> Request\r\n3. Response -> Response\r\n\r\nBy reducing the scope to server-operations only, we can drop the \"server\" qualifier from interface-names.\r\n\r\nIn the following, I'm going to propose more \"neutral ground\" interface-names that I think describes these operations more in the abstract.\r\n\r\nI'm also going to propose real method names, for several reasons:\r\n\r\n1. `__invoke` is magic, which does not belong in an interface.\r\n2. Using identical method-names in every interface prevents a component from implementing more than one interface.\r\n3. Anonymous classes accomplish the same thing as callables, but allow for static analysis in tools and IDEs.\r\n4. Naming every method `__invoke` creates ambiguity at call-sites in client code.\r\n\r\nThe latter point is important, because it removes the only practical reason to use `__invoke` in the first place: you don't need callables for this, and they are actually inferior to anonymous classes, which accomplish the same thing - granted, with slightly more verbosity, but that's merely cosmetics.\r\n\r\nThe proposed method-names will include both a verb and a noun, for several reasons:\r\n\r\n1. Clearly indicates both the subject and object of each action.\r\n2. Prevents ambiguity between method-names of individual interfaces of this PSR.\r\n3. Prevents collision with common method-names in frameworks and other PSRs.\r\n\r\nI'm essentially trying to reduce the scope to cover the expected flow of operations in any given server-side web application to e.g.:\r\n\r\n1. Operations on the request prior to processing,\r\n2. The actual processing of the request and creation of a Response, and\r\n3. Operations on the request after processing.\r\n\r\nI'm trying to define a terminology that describes the above as a domain first, and as isolated operations secondly - that is, the terminology should be pervasive and consistent throughout the domain described by the PSR, but the individual facts should make sense when considered in isolation as well.\r\n\r\n#### Request -> Response\r\n\r\nThis is the most important interface of them all, so it's really important to get the terminology right.\r\n\r\nThe term \"action\" collides head-on with controller/action terminology - it's a term that's already used in practically every framework in existence, so I really think we should stay away from that.\r\n\r\nIn the very abstract, something that handles a request is probably just a \"handler\", and in the abstract, *a handler processes a request*, so I would propose:\r\n\r\n```php\r\ninterface HandlerInterface {\r\n    public function processRequest(ServerRequestInterface $request): ResponseInterface;\r\n}\r\n```\r\n\r\n#### Request -> Request\r\n\r\nThis interface (like the Response -> Response operation) describes operations performed on the request prior to processing, e.g. a \"filter\" for pre-processing. (per dictionaries, \"a piece of software that processes data before passing it to another application\".)\r\n\r\nThe term \"operator\" collides with ordinary programming terminology, and attempts to describe in the very abstract what it *is*, rather than what it *does* - because this interface describes a *facet* and not an abstract entity in it's own right, the interface name needs to reflect the role of the class that implements it.\r\n\r\nIn the abstract, something that filters a request prior to processing is probably just a \"filter\", but to avoid collision with the response filter, we need to qualify the interface name, so I think \"request filter\" describes this well, and in the abstract, *a request-filters filters a request*, so I would propose:\r\n\r\n```php\r\ninterface RequestFilterInterface {\r\n    public function filterRequest(ServerRequestInterface $request): ServerRequestInterface;\r\n}\r\n```\r\n\r\n#### Response -> Response\r\n\r\nSimilar to the Request -> Request operation, this interface describes operations performed on a response after processing, e.g. a filter for post-processing.\r\n\r\nLikewise, in the abstract, this is probably just a \"filter\", e.g. *a response-filter filters a response*, so I would propose:\r\n\r\n```php\r\ninterface ResponseFilterInterface {\r\n    public function filterResponse(ResponseInterface $response): ResponseInterface;\r\n}\r\n```\r\n\r\nFootnote:\r\n\r\nI wrote these out with PHP 7 return type-hints just for the sake of discussion, but with the understanding that these may need to be defined using `@return` doc-blocks instead.\r\n\r\nAnd please don't dismiss me by crying \"bikeshedding\" - I'm not married to these exact names; I've provided a list of criteria for a naming strategy for the types and methods of this domain, and you're of course welcome to challenge those rationale, but I'm not merely trying to put my name on this, I'm trying to ensure that the type- and method-names make sense in every conceivable context *and* as a whole.\r\n\r\n`HandlerInterface::processRequest` could possibly be reduced to `process()`, as per `DelegateInterface` in PSR-15, I'm not sure about that? I guess it depends on whether PSR-15 is going to barrel ahead with it's own interface-declaration or adopt and depend on the handler-interface proposed by this PSR - I'm hoping it will adopt this, because having two identical interfaces in two *very closely related* domains is going to create practical problems; it's very likely to prevent interoperability in numerous cases where interoperability would have been straight-forward. (Imagine the absurdity of having to write a `DelegateInterface` adapter for a `HandlerInterface` implementation.)\r\n\r\nAnyhow, there's my proposal. Look forward to hearing your thoughts.\r\n"},"comment":{"url":"https://api.github.com/repos/http-message-strategies-interop/fig-standards/issues/comments/304309660","html_url":"https://github.com/http-message-strategies-interop/fig-standards/issues/6#issuecomment-304309660","issue_url":"https://api.github.com/repos/http-message-strategies-interop/fig-standards/issues/6","id":304309660,"user":{"login":"simensen","id":191200,"avatar_url":"https://avatars2.githubusercontent.com/u/191200?v=3","gravatar_id":"","url":"https://api.github.com/users/simensen","html_url":"https://github.com/simensen","followers_url":"https://api.github.com/users/simensen/followers","following_url":"https://api.github.com/users/simensen/following{/other_user}","gists_url":"https://api.github.com/users/simensen/gists{/gist_id}","starred_url":"https://api.github.com/users/simensen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simensen/subscriptions","organizations_url":"https://api.github.com/users/simensen/orgs","repos_url":"https://api.github.com/users/simensen/repos","events_url":"https://api.github.com/users/simensen/events{/privacy}","received_events_url":"https://api.github.com/users/simensen/received_events","type":"User","site_admin":false},"created_at":"2017-05-26T15:16:07Z","updated_at":"2017-05-26T15:16:07Z","body":"@schnittstabil How is this going? I'd love to see where this is going and would like to help however I can. I'm anxious to get PSR-15 moving along again. :)"}}
{"actor":{"display_login":"simensen"}}