{"action":"created","issue":{"url":"https://api.github.com/repos/TryGhost/Ghost/issues/9192","repository_url":"https://api.github.com/repos/TryGhost/Ghost","labels_url":"https://api.github.com/repos/TryGhost/Ghost/issues/9192/labels{/name}","comments_url":"https://api.github.com/repos/TryGhost/Ghost/issues/9192/comments","events_url":"https://api.github.com/repos/TryGhost/Ghost/issues/9192/events","html_url":"https://github.com/TryGhost/Ghost/issues/9192","id":269930520,"number":9192,"title":"Routes, resources & urls -> Centralised Services","user":{"login":"ErisDS","id":101513,"avatar_url":"https://avatars1.githubusercontent.com/u/101513?v=4","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false},"labels":[{"id":687043190,"url":"https://api.github.com/repos/TryGhost/Ghost/labels/refactoring/cleanup","name":"refactoring/cleanup","color":"1d76db","default":false},{"id":82875520,"url":"https://api.github.com/repos/TryGhost/Ghost/labels/server","name":"server","color":"0B939C","default":false}],"state":"closed","locked":false,"assignee":{"login":"ErisDS","id":101513,"avatar_url":"https://avatars1.githubusercontent.com/u/101513?v=4","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false},"assignees":[{"login":"ErisDS","id":101513,"avatar_url":"https://avatars1.githubusercontent.com/u/101513?v=4","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false}],"milestone":null,"comments":0,"created_at":"2017-10-31T11:51:55Z","updated_at":"2018-04-24T10:00:15Z","closed_at":"2018-04-24T10:00:15Z","author_association":"OWNER","body":"This is going to be a catch-all issue for a whole bunch of refactoring I'm working on. \r\n\r\nBelow are 3 specific problems I want to solve, and 3 specific use cases I hope will be achievable at the end.\r\n\r\nNote: The goal is to move towards these things being possible internally & in internal apps to see what sort of structures/APIs we end up with. Once the refactoring work is done, we'll address exposing functionality in other ways.\r\n\r\nProblems:\r\n\r\n- Resource <-> URL 2 way generation E.g. what is the url for a post? which post does a url represent?\r\n- Easy way to generate sitemaps, or other lists of urls, with meta data \r\n- Having routing be enumerable, and then configurable, extensible, etc\r\n\r\n**3 main use cases we currently cannot support**\r\n\r\n1. custom home pages\r\n2. rendering a resource at a non-standard URL, e.g. /tag/recipes/ -> /recipes/\r\n3. custom routes and their meta data, e.g. whether they should be in the sitemap, E.g. `/subscribe/`, `/featured/`, `/recipes/`, `/private/`, `/*/amp/`.\r\n\r\nThe expected outcome of this refactoring work is that we will have new services which control the ability to register routes, describe what happens at that route, and provide meta data about the route. Also that can then manage individual URLs, when they are added or removed from the system, and track some meta data about them. \r\n\r\nRough task list:\r\n\r\n- [x] Apps, register routes\r\n- [x] Centralised concept of what routes are available\r\n- [ ] Centralised concept of resources\r\n- [ ] Centralised concept of controllers\r\n- [ ] Centralised concept of renderers\r\n- [ ] Improve url generation to be driven from shared config\r\n- [ ] Separate out the \"url generation\" from sitemaps -> url service\r\n- [ ] Ability to manage urls: add/edit/remove + events\r\n- [ ] 2 way generation resource <-> url\r\n- [ ] Decorate routes, urls, controllers etc with meta data they need\r\n- [ ] url utils moved into service\r\n- [ ] App routes: when are they enabled? -> feature service?!\r\n\r\nThen:\r\n- [ ] Rewrite sitemap code\r\n- [ ] Revisit controllers, how can we generalise them?\r\n- [ ] Revisit full configuration and API, what else can be improved?\r\n- [ ] Tags & Authors get urls in JSON API responses\r\n\r\nNotes:\r\n- ensure we also refactor post.published events to never trigger on import as part of this.\r\n- get rid of the weird secure/setRequestIsSecure everywhere (was #6593)\r\n- figure out how route keywords fit into the route system (was #8492)\r\n- improve what is included in sitemaps (revisit ideas in #4588)"},"comment":{"url":"https://api.github.com/repos/TryGhost/Ghost/issues/comments/383875549","html_url":"https://github.com/TryGhost/Ghost/issues/9192#issuecomment-383875549","issue_url":"https://api.github.com/repos/TryGhost/Ghost/issues/9192","id":383875549,"user":{"login":"ErisDS","id":101513,"avatar_url":"https://avatars1.githubusercontent.com/u/101513?v=4","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false},"created_at":"2018-04-24T10:00:15Z","updated_at":"2018-04-24T10:00:15Z","author_association":"OWNER","body":"Closing in favour of #9601 "}}
{"actor":{"display_login":"ErisDS"}}