Problem/Motivation
For both #2869792: [meta] Add constraints to all config entity types and #2300677: JSON:API POST/PATCH support for fully validatable config entities it would be helpful to get a typed config respresentation for a given entity.
Currently you'd need to call $typedConfigManager->get($name) , which is tricky as:
- Getting the name from is different from config and config entity case
- It doesn't actually work for config entities, which haven't been saved yet
Possible solutions:
- Add a
->typedData()method to both ConfigBase and ConfigEntityBase - Add methods to TypedConfigManager to return what is needed
Proposed resolution
For now I went with the second solution as I'd like to separate the idea of typed data from runtime representations of configuration.
Remaining tasks
User interface changes
None
API changes
Add \Drupal\Core\Config\TypedConfigManagerInterface::createFromNameAndData()
Data model changes
None
| Comment | File | Size | Author |
|---|---|---|---|
| #39 | interdiff-36-39.txt | 2.12 KB | effulgentsia |
| #39 | 2869809-39.patch | 6.58 KB | effulgentsia |
| #36 | 2869809-36.patch | 7.14 KB | dawehner |
| #30 | interdiff-2869809.txt | 7.62 KB | dawehner |
| #30 | 2869809-30.patch | 7.84 KB | dawehner |
Comments
Comment #2
dawehnerComment #3
wim leersIs it okay to expand this interface? Is that not a BC break?
It's not marked
@internal. Should it be?Comment #4
dawehnerI can NOT imagine anyone in the entire universe to extend the typed config manager ... :)
Comment #5
dawehnerTechnically I guess these two new methods are something like a
TypedConfigFactoryWe could always introduce new static methods and pull
$thisfrom the container.Comment #6
tim.plunkettI went through the actual code base looking for places this could be used, and came up wanting.
Most callers of this pattern already have the config name and data split out.
Here's an example of my thinking.
Also I think the two new getFor* methods should be createFrom*, since the final call is a create.
Comment #7
dawehnerI think its a good idea to not expose the concept of simple config and config entities on this level, but also its in general a smaller API surface. Let's just use this single new method. I found another place where we could use it.
Comment #8
tim.plunkett+1
I think \Drupal\locale\LocaleConfigManager::getTranslatableDefaultConfig() and \Drupal\Core\Config\TypedConfigManager::get() itself should also be changed, and then this is done.
Comment #9
dawehnerNice finds ...
Comment #10
tim.plunkettThis looks great!
Thanks @dawehner
Comment #11
tstoecklerThis seems like a behavior change. As this is only ever called with (top-level) config objects, this seems safe, but also kind of unnecessary to do here?
Drupal\Core\Entity\Entity:I like the method being introduced here, but shouldn't
ConfigEntityBasesomehow override this method? Or instead should we add aConfigEntityAdapteror something like that? Or is that left for a followup?Comment #12
dawehnerFabulous review tobias!
100% fair point. Let's keep the
ifaround.I personally consider it as a major flaw in the entity API that its typed data is exposed as a major primary API instead of rather an API in parallel to the main API.
I hope for config entities we can avoid casting them to typed data directly ... but well this is my person opinion of course.
Do you think we should keep this discussion for a followup?
Comment #13
tstoecklerI'm fine with a follow-up for that. I don't have a strong opinion in either direction, but I think we should either deprecate
EntityInterface::getTypedData()wholesale or fix it forConfigEntityBasein that follow-up. Opening that follow-up should block this issue, though, IMO.Comment #14
dawehnerSure, here it is: #2870874: EntityBase::getTypedData() does not return the correct data type for configuration entities due to lack of consideration for data type derivatives
Comment #15
tstoecklerThank you! Let's get this in, then.
Comment #16
dawehnerWe are getting somewhere, nice!
@tstoeckler
Do you have any thoughts what we should do with validations on config save time?
Comment #17
tstoecklerHmm... that's a good question. I think in an ideal world my answer would be a different one, but since content entities also don't validate on save, I think we are well advised to follow suit for config entities. On the other hand, if I read the current code correctly we already pass
$has_trusted_data = FALSEtoConfig::save()when saving configuration entities. So if we do constraint validation if$has_trusted_dataisFALSEwe would automatically trigger it for config entities by default. On the third hand I'm not sure if that wouldn't be considered a BC-break. On the fourth hand I guess currently no one will actually have constraints in their schema at the moment, so maybe we can get away with it? And also maybe we even if it's a slight BC break it's acceptable because the only thing that breaks is if people are saving invalid configuration, so it's good that we prevent it?As you can see, not really sure...
Comment #18
wim leersAgreed with #17. @tstoeckler++
I wonder what @alexpott's thoughts about this are.
Comment #19
dawehnerI 100% agree with tobias. There might be issues with migrations which historically have been really lazy with migrating 100% valid data but beside from that, I think adding more validation is just exactly what we want.
Comment #20
kristiaanvandeneyndeJust chiming in to point out that I'm actually trying to change that behavior to some extent: #2847319: Always enforce basefield and entity-level constraints
Let's not use a mistake we made in one place as an excuse to repeat it in another :) For all we know, we might fix the fact that content entities don't validate on save and then have a broken config entity save because we "just went along with it".
Comment #21
dawehnerNote: This blocks: #2300677: JSON:API POST/PATCH support for fully validatable config entities
Comment #22
dawehnerComment #23
wim leers#2300677: JSON:API POST/PATCH support for fully validatable config entities is major, so bumping this to major too.
Comment #24
wim leersComment #25
effulgentsia commentedThis patch looks pretty great to me. I still want to read the comments in this issue before committing to make sure I'm not missing anything. In the meantime, I noticed the following unused use statements. Just pointing them out in case they reflect something that should be in the patch but isn't.
Comment #26
alexpottI think we should consider the TypedConfigManager largely as an internal object and certainly not an extension point. We're adding a method to its interface here. I think we should have a CR to tell people about the nee method.
Comment #27
dawehnerTheoretically we could avoid the new method by having a new static method which gets the typed config manager in as first method parameter. Funny enough you can actually call to protected/private functions in that static method, so it could be used even beyond the case of just public method calls (which is the case here). I do agree with @alexpott that the typed config manager is not meant to be an extension point in Drupal, but here is at least an alternative we could follow, even if its super ugly.
Comment #28
effulgentsia commentedI don't think doing so is necessary, since adding methods to interfaces in minor releases is explicitly allowed for in our BC policy. However, a static method might actually make sense in this case, since it doesn't seam to me to have an implementation that would ever need swapping. In other words, if it truly is merely a utility wrapper around three other interface methods, then a static method kind of makes sense IMO, and is not "super ugly".
I'm ok with either approach though, so I leave it to those who've worked on this patch as to whether to update the patch to use a static method instead of an interface method, or whether to write a CR to inform people about the interface addition.
Comment #29
effulgentsia commentedI read through the issue comments and looks to me like all points are addressed (except per #28, doing one of either #26 or #27).
#17 hasn't been addressed, but that discussion is also taking place in #2869792: [meta] Add constraints to all config entity types, so if we need to open a new issue for it, I think it makes sense to do so as a related issue of that one, not this one.
Comment #30
dawehnerGood point @effulgentsia. Given that, I would kinda prefer #12
Nevertheless, here is some experiment about my train of thoughts in #27. It works, but well, I'm not 100% convinced of it.
Comment #31
effulgentsia commentedI think what I like least about #30 is that it's a static function with a name that starts with "create", but returns an instance of something entirely different than a typed config manager. I think all our other static "create" functions in core return an instance of the class they're on (or at least an instance of a very similar class).
If someone thinks of a more natural home for this static method, great, let's explore that.
Otherwise, I think I prefer #12 as well, despite it needing a CR.
Comment #32
effulgentsia commentedWhat about
Drupal\Core\Config\Schema\Mapping::createFromNameAndData()? Or is there a case wherecreateFromNameAndData()creates something other than aMappinginstance?Comment #33
effulgentsia commentedOr maybe
Drupal\Core\Config\Schema\ArrayElementinstead of presuming it's aMapping?Comment #34
dawehnerConceptually this method would be usable anyway, but the practical usecase would be always a mapping. On the other hand the entire unification of typed config and typed schema might resort all those keys again.
Given that I really think we should go with #12. Note: I created a basic change record describing how it is useful and how you can implement this on your own implementation.
Comment #35
wim leers#12 was RTBC'd by @tstoeckler in #15. Do we want to re-upload #12 and re-RTBC it?
Comment #36
dawehnerHere it is ...
Comment #37
wim leersOk, so we do. Great!
Comment #39
effulgentsia commentedComment #40
effulgentsia commentedTicking credit box for @tstoeckler for his reviews.
Comment #41
dawehnerThank you @effulgentsia!
@Wim Leers you have the honour, I guess :)
Comment #42
wim leers:)
Comment #43
alexpottCommitted a9fe99c and pushed to 8.4.x. Thanks!
Comment #45
wim leersYay, #2300677: JSON:API POST/PATCH support for fully validatable config entities is now unblocked!