Problem/Motivation
Currently (and also after #2308745: Remove rest.settings.yml, use rest_resource config entities) the rest configuration is quite flexible / verbose.
+ GET:
+ supported_formats:
+ - hal_json
+ supported_auth:
+ - basic_auth
+ POST:
+ supported_formats:
+ - hal_json
+ supported_auth:
+ - basic_auth
+ PATCH:
+ supported_formats:
+ - hal_json
+ supported_auth:
+ - basic_auth
+ DELETE:
+ supported_formats:
+ - hal_json
+ supported_auth:
+ - basic_auth
Problems
- Realistically you don't want different formats for different HTTP methods
- You also don't want different authentication for different HTTP methods
Proposed resolution
Make it possible (optionally_ on the config entity level to just specify
a) the list of formats of your entire resource
b) the list of authentication methods of your resource
c) the exposed HTTP methods
At the end it could then look like the following:
<code>
methods:
- GET
- POST
- PATCH
- DELETE
formats:
- hal_json
authentication:
- basic_auth
Remaining tasks
- #2308745: Remove rest.settings.yml, use rest_resource config entities
- #2721595: Simplify REST configuration
User interface changes
API changes
Data model changes
Comments
Comment #2
wim leers+1 for principle. But we need to better understand whether we would do this before #2308745: Remove rest.settings.yml, use rest_resource config entities, or after, or only do this.
Comment #3
dawehnerI would be totally for after this, because entities allow us to introduce BC layers much easier.
Comment #4
wim leersSo, you're proposing this order:
Right?
Comment #5
dawehnerOh actually the other way round, so this issue should be postponed on #2308745: Remove rest.settings.yml, use rest_resource config entities.
Comment #6
wim leersOk.
Comment #7
wim leersThis patch fully implements this simplified REST configuration as discussed & agreed by @klausi, @dawehner and I at #2308745: Remove rest.settings.yml, use rest_resource config entities, see comments #170–#202.
This patch is built on top of #2308745-208: Remove rest.settings.yml, use rest_resource config entities. It already includes upgrade path test coverage (with an upgrade path relative to that of #2308745).
Comment #9
wim leersgitis stupid, it really really wants to consider that PHP file as binary, even though.gitattributesalready tells/forces it otherwise…So, rolling the patch with
--binary, because I can't figure out how to force git to be sane.Comment #11
dawehnerJust a quick comment.
(from core/lib/Drupal/Core/Extension/module.api.php:566)
but
Comment #12
wim leersFirst, rebased on top of #2308745-213: Remove rest.settings.yml, use rest_resource config entities. Should have the same fails.
Comment #13
wim leers#11: fixed. That will hopefully fix the first fail. I couldn't reproduce that fail locally, so I can't be certain.
The second fail — which is reproducible — is now also fixed. But I fixed it in a perhaps unexpected way. The test itself is bizarre: it installs the
halandrestmodule, which means we don't even need to enablejson. We just need to enablecookieauthentication on the existing resource. And we just need to request it in HAL+JSON, rather than JSON. That seems closer to the original intent.Self-review:
Should be
user.Specifying
cookiewould be saner, since that actually exists.Should be
user.Comment #16
wim leers#2308745-213: Remove rest.settings.yml, use rest_resource config entities introduced 5 new failures. #2308745-216: Remove rest.settings.yml, use rest_resource config entities fixed them. No interdiff because this is just a rebase on top of 216.
Comment #18
wim leers#2308745: Remove rest.settings.yml, use rest_resource config entities landed, now rerolling this.
Comment #19
wim leersRebased.
Comment #21
wim leersSIGH.
git diff --binaryit is.Comment #23
wim leersOne small change in
ResourceGranularityRestResourcesConfigEntitiesUpdateTestwasn't committed. Can't provide an interdiff because git insists on interpreting this file as binary — see #21.Comment #24
wim leersAnd this fixes the fails in
ConfigDependenciesTest. This also made me realize we need expanded test coverage for that. But first, let's see whether this is green already.Comment #26
wim leersYAY! Green! Now working on tests and clean-up.
Comment #27
dawehnerSo I guess we have to expand the test coverage for the non granular case here?
Comment #28
wim leersYep, that's what I'm working on :)
Comment #29
dawehnerUpdate numbers are a curse. This issue will conflict with #2228141: Add authentication support to REST views, that's for sure.
Comment #30
wim leersI don't mind rerolling, don't worry :)
Comment #31
dawehnerOh yeah I just wanted to trigger a review :) Thanks a ton.
Comment #32
wim leersNicely triggered :D
Here's the missing test coverage. It only made sense to update 2 test existing methods to accept providers, the rest requires separate test methods for "method" vs "resource" to be able to sanely test things. In doing so, updated the
onDependencyRemovalForResourceGranularity()code to be in sync with changes made to the parent issue after it was split off.Now hunting for inconsistencies.
Comment #34
wim leersGAAAHHHHHH
git diff --binary!!!!Comment #35
wim leersThis actually belongs in post-update.
I started working on that, but… quickly ran into problems:
So, postponing doing this until I get feedback about that.
Should use the constant.
This looks bizarre when searching for classes. I wonder if renaming from
ConfigDependenciestoEntityResourceConfigDependencieswould make more sense?Typo.
Copy/paste remnant.
@todoreferencing this issue inrest.post-update.php. That should be removed.For resource granularity REST resources, we could actually simplify the schema further. Looking into that now.
Comment #36
wim leersI thought we could get rid of the
configurationkey for the resource granularity. We can't. We need the schema type (calledgranularityhere) to affect a predictable key (calledconfigurationhere).Comment #38
wim leersFor #35.1, here's what I started to do:
interdiff-post_update.txt.The only remaining thing is #35.3. But that can happen in a follow-up for sure.
So, AFAICT the main thing to review here is whether to use
hook_post_update_NAME()orhook_update_N().Comment #39
wim leers#35 is green. This is now blocked on review. Unassigning.
Comment #40
dawehnerAre we sure this actually works properly? Wouldn't this method be executed before
\rest_post_update_create_rest_resource_config_entities?As said before, we could simplify all that to a single array_filter call, can't we?
Note: This file uses a module weight of 8201, did you considered using 21121112 instead? Or some other number :)
Comment #41
wim leersDiscussed with dawehner. Moving the upgrade path to post-update.
#40:
hook_update_N(), where the fixture must include the "N" in the filename?Comment #42
wim leersComment #43
dawehnerSorry I should have been more clear. This was about the core.extension weight being the same as the module schema version, due to some c&p.
Exactly, cool
Comment #44
wim leersGot it, thanks! :)
Comment #45
wim leersSo this reroll:
hook_update_N()tohook_post_update_NAME()RestConfigurationEntitiesUpdateTesthad to be updated, because that will now also run this new post-update functionTo be able to test this post-update hook in isolation, which is necessary to be able to test all nuances of this post-update hook, turns out you have to set the
existing_updateskey-value pair in thepost_updatecollection in the key-value store. This is the very first test doing that. That required a lot of digging.However, to make it much worse, the move from
hook_update_N()tohook_post_update_NAME()introduced at least two bizarre problems, one of which is minor, the other one of which is critical:loadMultiple()now appears to be insisting on returning things in a different order, even when callingresetCache()after running updates:had to be changed to:
loadMultiple()seems to be forever returning the old values (even after callingresetCache()), andload()always returns the correct, updated value. This is a HUGE WTF. I'm totally lost. I included the following debug code:Help very much appreciated with solving that second WTF.
Because that of course means the tests aren't passing… the very same tests that were passing just fine before! That's the even more scary/mysterious part: that this bug apparently only happens when running/testing post-update functions.
Still to do:
drupal-8.rest-rest_update_8202.php, since it's no longer for ahook_update_N()functionComment #47
wim leersRarely have I been this glad to see a fail from testbot. It confirms what I see locally:
Those should all be
resource, but clearly they're not.Hopefully a (config) entity system or update system expert can figure out the root cause for this.
Comment #48
dawehnerWe use simply a bad setup.
Here is a comment I had before.
So this is what happens:
You do stuff before running the updates, see
\Drupal\rest\Tests\Update\ResourceGranularityRestResourcesConfigEntitiesUpdateTest::testMethodGranularityResourcesConvertedToResourceGranularityResourcesThis line is part of that for example:
$resource_config_entities = $resource_config_storage->loadMultiple();This lines calls out to
ConfigEntityStorage, andConfigFactoryandCachedStorage::findByPrefix. This later one caches stuff statically.Here is a patch which adds a reset, but I'm not sure its actually a good idea to call out to any kind of api before running the test.
Comment #50
dawehnerDamnit, I forgot
--binaryComment #51
dawehnerComment #52
wim leersGAHHHHHHHHHHH !!!!!!!!!!!!!!
Glad you found it, a fresh pair of eyes clearly saved the day there :D
There's no reset in the patch.
IMO it is fine. The whole point of post-update is that it behaves just like regular code. Which means you get tag-based invalidation, and static cache invalidation.
This patch is now ready as far as I'm concerned. The only thing that remains to be done, is renaming
core/modules/rest/tests/fixtures/update/drupal-8.rest-rest_update_8202.phpto something that doesn't include8202in its name. The post-update function has a quite long name (rest_post_update_simplify_method_granularity_to_resource_granularity_where_possible()), do we want the same for the fixture? Do we even want that very long name for the post-update function?Comment #53
dawehneroh yeah that was the patch before I found the actual reason.
Well, I would just use
rest_post_update_simplify_granularity()and call it a day.Comment #54
wim leersCool, will do.
Comment #55
wim leersDone.
Comment #56
dawehnerThank you!
Comment #58
wim leersRandom fail in
Drupal\field\Tests\EntityReference\EntityReferenceAdminTest. Re-testing, back to RTBC.Comment #60
wim leersTrivial conflict in
core/modules/rest/config/optional/rest.resource.entity.node.ymlafter #2755843: The order in which config is saved affects dependency calculations landed.Straight reroll, so no interdiff.
Comment #61
gcassie commentedI'm getting an error trying to apply this update.
STR:
* Clean Drupal 8.1.6 install with Rest UI contrib
* Enable the user rest resource, with GET and basic auth
* Update core code to 8.2.x-dev
* Attempt to run update.php
* Get this:
Comment #62
wim leers#61: the same problem was reported at #2308745-253: Remove rest.settings.yml, use rest_resource config entities, it's not something this patch introduces.
Comment #63
effulgentsia commentedGrrr. d.o. ate my dreditor review of this patch. I need to rewrite that review, but don't have time this second. Will do so within 24 hours.
Comment #64
effulgentsia commentedYay!
Is it not possible for existing config to support some methods without supporting GET?
Same question here, but for new config using resource granularity.
Should we reference the constants here instead of the literals?
Can we changes this and similar code blocks to use switch/case, and still throw an exception when not one of the allowed constants? Both for clarity, and since nothing in the config schema enforces the value to one of these 2.
This shows up in the patch as binary rather than text, so no additional context via dreditor. But, within this file, there's db
->mergestatements, but we know the starting database, so shouldn't these all be either->insertor->update? Other similar fixtures in HEAD use explicit insert/update, not merge.Let's add a comment here explaining why this is done (e.g., so that there's a test of updating configuration with method-specific formats).
Let's add a comment here explaining why this is done (e.g., so that there's a test of updating configuration with method-specific authentication).
Comment #65
wim leersWill reroll.
Comment #66
wim leers->merge(), that's where I even got the idea from. Examples:core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php,core/modules/system/tests/fixtures/update/drupal-8.language-enabled.php.Re-RTBC'd since this is all trivial refactoring.
Comment #68
wim leersRandom fail:
UpdatePathTestBaseFilledTest.Comment #69
effulgentsia commentedSorry. A few more nits.
Either we assume that the result of this function always passes through DependencyTrait::addDependency() (which it does within
RestResourceConfig::calculateDependencies()) prior to being saved to storage or otherwise needing to be sorted, or we do not assume this. If we assume it, then we shouldn't need this hunk, but we should add docs to the function to clarify this assumption. If it's only to make a unit test pass, then perhaps the unit test should be the one to sort. If we do not assume this, and therefore, require this function to sort, then it should mimic DependencyTrait::addDependency() and also ensure uniqueness.Per #64.2, we shouldn't assume GET is defined. Technically, this code doesn't, as the implementation of getFormats() ignores the passed-in method, but that's not obvious from reading this code in isolation. Any reason not to simply use
$configuration['formats']instead of$rest_config->getFormats('GET')?Same as above, but for getAuthenticationProviders().
Comment #71
effulgentsia commentedAs I looked more at #69, I couldn't find a reason for those points to block commit, so pushed to 8.2.x. A follow-up for #69 would be appreciated though.
Comment #72
wim leersAwesome, thank you! I will file a follow-up first thing tomorrow!
Comment #73
effulgentsia commentedComment #74
wim leersFollow-up created: #2773185: Fix nits in \Drupal\rest\Entity\ConfigDependencies.
Comment #75
wim leersAlso updated https://www.drupal.org/developing/api/8/rest: https://www.drupal.org/node/2667736/revisions/view/9794157/9913841.