Problem/Motivation
We want to auto-generate HTML routes for entities, so that we don't force people to double-enter things. (See parent issue for background.)
Proposed resolution
Add a "route handler" for entities. It is optional, so auto-generation becomes opt-in.
The route handler, if specified, will be called by a dedicated dynamic route event listener to generate appropriate routes for a given entity.
A default will be provided that most entities can use that will generate the routes we know how to generate from known links. It MAY be a different default for content and config entities or not, TBD.
This issue is just about implementing the framework and doing the easy conversions.
Remaining tasks
Implement it.
User interface changes
None.
API changes
Addition: Route handlers are available to entity definitions. We anticipate all entities using it eventually but it's not a requirement.
(This issue was approved by catch and alexpott in Amsterdam.)
Beta phase evaluation
| Task, because it expands the API and opens up a lot of prototype DX advantages | |
|---|---|
| Issue priority | Major because the DX issue of setting up entity routes itself is major. |
| Disruption | It is an additional API, so there is no disruption at all. |
| Comment | File | Size | Author |
|---|---|---|---|
| #46 | 2350503-46.patch | 16.87 KB | dawehner |
| #46 | interdiff.txt | 1.2 KB | dawehner |
| #19 | 2350503-19.patch | 18.31 KB | dawehner |
Comments
Comment #1
dawehnerNot sure whether this is a normal to be honest?
Comment #2
dawehner.
Comment #3
pwolanin commentedDo we have a reasonably fast and simple way to get all the routes for a particular entity or entity type once they are generated?
Comment #4
dawehnerLet's add a small test.
@pwolanin
On the longrun we should either use linkTemplates or uriRelationships but yeah this is not really part of the discussion around this particular issue.
Comment #5
berdirWhy do... ? That's a pattern used when having internal helper methods to a public method, but there is no public instantiateHandler(), so why not just name so?
@return object? Do we now no longer need a description?
string[] is I think how we document this now?
Wondering if provideRoutes() is really a good method name here?
Wondering how fast this is for 50, 100 or however many entity types you will have. Would it make sense to optimize this to check if $entity_type has any router provider classes first?
We're obviously not going to change that, but I kind of like the pattern we use for BaseFieldDefinition, with the ::create() method, then you don't need the () trick.
I'm wondering when it makes sense to use constructor arguments, when multiple and when single methods. Seems like in cases like this, calling setDefault() would be easier to read? Or use the constructor, which has $defaults as second argument, and $requirements as third..
Those are not removed from user.routing.yml
Comment #6
berdirAlso, should we move routes that are specific to an entity type but will likely not be autogenerated too? things like node.add, entity.node.preview, entity.node.version_history
And, should we include node_type routes too in this issue? config entities are probably usually easier to generalize.
Comment #7
dawehnerFixed
Improved the docs a bit.
Let's improve it properly, let's it return stuff and rename it to just routes?
Well, let's add the check directly.
HAHAHHAHAHAA, did you really suggested to add a method to symfonys route object? Hilarious, just hilarious :)
Well, you know everyone can do what he things is the best, but I would agree with you if php would have named parameters ...
Good catch ...
I don't think so we should ... these routes are specific to the link templates. Can we discuss that later?
Comment #8
berdirYeah, should be easy, right? ;)
Hm, I would have gone with getRoutes() then, not sure.
Let's check if we can get some other opinions, from alexpott maybe?
I'm fine with discussing the non-link-template-specific routes later, but for example the version_history one *is* a link template, but it will not be possible to autogenerate it. So it is currently very hard to see what should be done there and what in routing.yml. IMHO, it would make sense to pull all routes that are for a specific entity type in the route provider. But separate issue is fine. Are we going to do a single one to move all node types over as a follow-up? doing per-module issues seems a bit overkill, as it is very easy for now. Or do you want to look into generating them first, before we move more of them around?
Comment #10
Crell commentedBerdir: Why wouldn't we be able to auto-generate version-history?
Comment #11
berdirWell, because there's nothing standardized about that route?
Custom controller, access, options.. there's nothing that we could generate?
Comment #12
Crell commentedHm. Sounds like a potential place for further standardization as time allows then. :-)
It's true that we won't be able to auto-generate every single route; since we cannot control what links an entity may define we can't guarantee that there's code ready for generating everything. That's fine, as long as we can get all of the major/easy/common ones.
Comment #13
dawehnerWell, beside real life this statement is maybe right.
This certainly works much better in case you just have to care about REST routes.
This should hopefully fix it.
Comment #14
dawehnerAnyone wants to step forward and review it?
Comment #15
andypostThe code is fine but the primary question is this way makes entity system easy?
The old approach require devs to use annotations for routes (link templates) and yml file so it's easy to find the route.
The new way require to implement additional class to provide routes for none-standard ones.
I really sure that we need to make it easy for devs to provide entity routes, but current code looks like complication.
The old one is more readable
Comment #16
damiankloip commentedI asked in IRC but you didn't answer, so I will ask again here :p Why do we not have a base
implementation here that can be used?
Comment #17
dawehner@damiankloip
My computer of myself was probably offline at that point ... for now the point is to enable the machinery which will
allow us in future to auto-generate the common routes for entities. Writing this auto-generation as part of this issue just defers the process.
Well, you can't deny that for sure, but on the longrun you, especially for custom code, not have to write the code at all.
Comment #18
andypostComment #19
dawehner... Reroll.
Well, you can agree with that point, on the other hand that is not the point of this issue.
Comment #20
andypostReadability is not the primary question here...
I really trying to get that future. The big picture is not clear.
In my POV entity should provide a canonical link prefix (path: /node, /taxonomy/term)
Then #16
EntityRouteProvidercollects a link names (probably entity-operations) that exposed via entity annotation and build routes (maybe route collections per entity type).#8
@dawehner suppose 2 issues for config and content would be enough, is not it?
Comment #21
Crell commentedI'm rather surprised this didn't exist already. :-)
Although the method_exists() calls really really should e interfaces. Probably OT for this issue but who were those ever added as method_exists()s?
I assume the idea is that this line changes to use the canonical link value once #2281645: Make entity annotations use link templates instead of route names is in? (And similar elsewhere.)
The generic version of this class is also waiting on #2281645: Make entity annotations use link templates instead of route names, I take it?
Comment #22
dawehnerI just copied that over from the other handler code ... nothing new in this patch ...
Right, and for obvious reasons we can't do it here.
its as simple as that.
So do you want to update the issue status of this issue?
Comment #24
Crell commentedI suppose this is as much as we can do until #2281645: Make entity annotations use link templates instead of route names is in, so let's land this and move our attention back over there. Further changes to the code here shouldn't be hard API changes, and that's the important part.
Comment #25
tstoecklergetRoutes() would be more inline with our standards IMO. Especially in the entity/field system we generally only static methods don't have the "get" prefix.
Comment #26
dawehnerThank you tobias.
I'll don't complain here, but using "getters" for things which aren't getters let's you stop thinking about domain knowledge, but instead
just always expose internal data structures and be done. Sadly this antipattern is hard to stop, and requires work.
Comment #27
tstoecklerThanks for the quick fix!
Wow, that's very interesting. I'll have to think about that some before being able to respond :-)
Comment #28
dawehnerBtw. We went with this method name, because all the existing route callbacks in the
$module.routing.ymlfiles follow that pattern already.Comment #29
tstoecklerHmm... that's true. I guess it's up to the committers to commit either #19 or #26.
Comment #30
berdirThis conflicts with #2335879: Change SqlContentEntityStorageSchema::requiresEntityDataMigration() to ask the old storage handler if it has data rather than assuming yes unless NULL storage which just got committed, that added a public method of the method here called initiateHandler().
Comment #32
tstoecklerComment #34
dawehnerCool, exactly what we need here.
Comment #35
dawehnerGiven that I think we are back to RTBC?
Comment #36
tstoecklerYup, reroll looks good.
Comment #37
dawehnerWorked on this issue on the train, so this justifies the tag.
Comment #38
dries commentedThis is good work, but I don't want to commit this during the Ghent sprint. On its own it makes the DX worse and while that can get fixed (via a base class) in follow-up issues, I don't feel that should be our focus. I'd rather have us focus on critical issues at this stage of the release cycle.
Comment #39
Crell commentedDries, I think you're missing the context here. This is (sort of) the 2nd part of #2281645: Make entity annotations use link templates instead of route names, which catch approved in Amsterdam for post-beta. If you want to hold off on this issue until that one is in that's one thing, but I do believe both of these issues need to get in before release. (And have been worked on in some form since well before Amsterdam, too.)
Comment #40
dawehnerLet's just link to another related issue for now.
Comment #41
alexpottWe seem to have zero documentation of what can go in the handlers key in an entity type annotation:
(from \Drupal\Core\Entity\EntityType)
Whilst fixing this is beyond the scope of this issue. Adding a @todo here and creating the issue to add the documentation is not. Once this is done I don't see why we should hold up making progress here on the ghent sprint.
I think this change is overall positive for DX. If you are creating a new entity type you have to do less, if you looking for an entity's routes the current expectations would be to look in the routing file and entity type definition - now you need to look in a different place in entity type definition - but once you've learnt this then you're good. What we should have is a D8 to D8 change record to tell everyone.
Comment #42
berdirAs discussed in Amsterdam, the route generation handler is designed to be opt-in, defining the routes manually in routing.yml will still work.
I'm also not sure if we should even document this already in a change record, because it is only to prepare for the more important next step: Generating default routes. Not sure if it makes sense for contrib to already switch to this pattern as they will have to switch again if they want (part of) their entity routes to be automatically generated.
Comment #43
dawehnerCool, we are allowed to work on this issue again.
This is a tough question ... its not adding advantage for contrib to use it.
Comment #44
dawehnerAnyone wants to review it?
Comment #45
jibranThis issue still needs change record. Some minor nits. Please ignore if seems irrelevant other then that RTBC.
Provides
Can we please give it some better name? onDynamic is not helpful a lot.
Comment #46
dawehnerThis issue still needs change record.Right, ... we argued before, why we don't want to add one already.
Comment #47
jibranok then
Comment #48
alexpottCommitted 1601b08 and pushed to 8.0.x. Thanks!
Thanks for adding the beta evaluation for to the issue summary.
I still think we should be working in on draft change record for this and the more important next step...
Comment #51
lokapujya