Problem/Motivation
I've been playing around this the JSON:API module in D9 using the Umami Profile to have some content to query against. I noticed that when sorting by title on node queries they are not being returned in the correct alphabetical order (at least as I understand it).
For instance: /jsonapi/node/recipe?sort=title
returns the list of recipes in the following order:
- Vegan chocolate and nut brownies
- Crema catalana
- Thai green curry
- Deep mediterranean quiche
- Fiery chili sauce
- Gluten free pizza
- Super easy vegetarian pasta bake
- Victoria sponge cake
- Watercress soup
interestingly, sorting in the reverse order with: /jsonapi/node/recipe?sort=-title
seems to return the correct order:
Actually the reverse order is off as well. "Deep mediterranean quiche" should be above "Crema catalana" and "Gluten free pizza" should be above "Fiery chili sauce"
- Watercress soup
- Victoria sponge cake
- Vegan chocolate and nut brownies
- Thai green curry
- Super easy vegetarian pasta bake
- Fiery chili sauce
- Deep mediterranean quiche
- Gluten free pizza
- Crema catalana
the same thing appears to be happening on other content types such as articles: /jsonapi/node/article?sort=title
I'm using Umami as an example but I assume there is nothing particular about the Umami profile that is causing the issue.
Steps to reproduce
- Install Drupal 9 with the Umami Profile.
- Enable the JSON:API module and any associated modules.
- Got to the url:
/jsonapi/node/recipe?sort=title
Expected Order:
- Crema catalana
- Deep mediterranean quiche
- Fiery chili sauce
- Gluten free pizza
- Super easy vegetarian pasta bake
- Thai green curry
- Vegan chocolate and nut brownies
- Victoria sponge cake
- Watercress soup
Actual Order:
- Vegan chocolate and nut brownies
- Crema catalana
- Thai green curry
- Deep mediterranean quiche
- Fiery chili sauce
- Gluten free pizza
- Super easy vegetarian pasta bake
- Victoria sponge cake
- Watercress soup
Proposed resolution
So far:
Get the language_code in EntityResource.php
's getCollectionQuery
method and pass to entity query
Remaining tasks
Review
User interface changes
N/A
API changes
N/A
Data model changes
N/A
Comment | File | Size | Author |
---|
Issue fork drupal-3186834
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
PCate CreditAttribution: PCate commentedComment #3
Kristen PolThanks for reporting this bug and creating such a great issue summary! I was able to reproduce the issue when testing on 9.2 as well.
Comment #4
Kristen PolOne thing I should have noted before is that I tried testing with specifying the langcode as en-US and also got a non-alphabetical ordering though I think it was different than in the issue summary. I might try that again.
Comment #5
jibranJSON:API uses EFQ under the hood. See
\Drupal\jsonapi\Controller\EntityResource::getCollectionQuery
. One way to verify, that it's not a JSON:API issue, is to create an equivalent EFQ and check the results. JSON:API sort parameter is handled by\Drupal\jsonapi\Query\Sort
and as per\Drupal\Tests\jsonapi\Unit\Query\SortTest::parameterProvider
?sort=title
will be converted to following valuesYou resultant EFQ will be:
Can you please share the output of the above script?
Comment #6
mohit_aghera CreditAttribution: mohit_aghera at QED42 commented@jibran
I am seeing different behavior.
I've attached a test only patch to see how it goes.
For me on local, entity queries are giving the correct results.
Somehow for my test case, when I request the translation URL like
/ca/jsonapi/node/article
, the sorting process is happening as per the english labels only.Where as for translation sorting should happen as per translated titles.
Feel free to correct me if I am missing something here.
Comment #7
jibranCan you try the following patch?
Comment #8
mohit_aghera CreditAttribution: mohit_aghera at QED42 commentedMerging the patches from #6 and #7
Comment #9
adalbertov CreditAttribution: adalbertov at CI&T commentedHello, have just checked the patch #8, the list looks ordered properly, so I'm moving the issue to RTBC.
Comment #10
adalbertov CreditAttribution: adalbertov at CI&T commentedComment #12
benjifisherPlease do not ask the testbot to try again until #3207086: [HEAD BROKEN] Consistent failure in MonthDatePluginTest is fixed.
Comment #13
alexpott#3207086: [HEAD BROKEN] Consistent failure in MonthDatePluginTest is fixed. I have not reviewed the code.
Comment #14
catchShould be 'Tests multilingual JSON:API calls.' I think.
Should the article creation be moved out of ::setUp() into a helper method, so that we can avoid creating then deleting the nodes?
Comment #15
kuldeep_mehra27 CreditAttribution: kuldeep_mehra27 at Valuebound for Valuebound commentedComment #16
mohit_aghera CreditAttribution: mohit_aghera at QED42 commented@catch, I tried to refactor it. However, currently we are creating articles like,
$this->createDefaultContent(5, 5, TRUE, TRUE, static::IS_MULTILINGUAL, FALSE);
insetup()
method.Now, if we want to refactor it, we want to add a similar line in all the test cases of
JsonApiFunctionalMultilingualTest
class, so it will create the required nodes for all the test cases.I found it a bit repetitive to do. Let me know if I should go ahead and refactor it.
Comment #17
mohit_aghera CreditAttribution: mohit_aghera at QED42 commented@catch Updated the test cases as per discussion on slack and mentioned in #14
Comment #19
LuisPimentelLopesThis issue also occurs on Drupal 8.9.12. Thanks @kuldeep_mehra27 #15 works!
Comment #20
bbralaThe asked changes have been applies in #15 and #17, changed are minor. Setting it back to RTBC
Comment #21
alexpottWe need to make this change in BC compatible way. I.e We need to allow NULLs for $language_manager and trigger a deprecation error if language manager is NULL. See \Drupal\Core\Extension\ModuleInstaller::__construct() on 9.3.x for a couple of examples of how to do this.
Comment #23
mohit_aghera CreditAttribution: mohit_aghera at QED42 commentedThanks @alexpott
I've updated the changes and created a new fork for implementation.
Comment #25
paulocsI added test to test the deprecation message.
Comment #26
alexpottI wonder if we should be fixing this problem at a lower level. It seems to me that the result of calling
->sort()
with aNULL
in\Drupal\jsonapi\Controller\EntityResource::getCollectionQuery()
is unexpected. Why is providing a langcode so important? Is it ever correct to provide a NULL when the field is not a base field?Comment #27
bbralaI was wondering if there is something to be learned from this issue #2794431: [META] Formalize translations support in regards to this bug.
Comment #28
vikashsoni CreditAttribution: vikashsoni as a volunteer and at Zyxware Technologies commentedThanks for the patch now we able to sort title
Comment #30
bbralaLeft a comment and #26 also doesn't seem addressed. Setting to needs work.
Comment #34
andregp CreditAttribution: andregp at CI&T commentedAs previous MR was unmergeable I created a new MR, where I applied the last patch (#17) and cherry picked the related-to-the-issue commits from the first MR.
Still needs work tough, to address the comment right before #30 by @bbrala
And the question on #26 by @alexpott.
Edit: I believe I should have pushed the new branch before adding the commits, that way they would show here on the comments making clearer which commits I picked. So here is a copy of my log.
Comment #37
GRcwolfI created a patch for Drupal 10.0, if anybody else needs to patch this.
It's the same as #15 but without the tests.
Comment #38
cbccharlie CreditAttribution: cbccharlie as a volunteer and at Balidea commentedHi,
Current patches are not working with entities without translations (langcode column missing).
Column not found: 1054 Unknown column 'ENTITY.langcode' in 'on clause'.
Comment #39
mohit_aghera CreditAttribution: mohit_aghera at PreviousNext commented- Combining both the PR's changes in single patch.
- Making it ready for 10.1.x's latest head
- Put back the original test cases from previous patches.
Addressing following feedback as well:
Now, checking resource type and validating content/config entity. From there we are deciding the language type.
@cbccharlie
- I think it seems to be working fine for entities without translation. I tried to run `testRead()` in
JsonApiFunctionalTest
.It worked fine for me.
Can you share if there are any specific things with your setup?
I tried following steps to validate the issue.
- Install standard profile.
- Enable jsonapi module
- Create a couple of page content
- Visit
http://127.0.0.1:8080/jsonapi/node/page
and I was able to see the results.@alexpott
Can you please elaborate further #26
I am somewhat confused about it.
Comment #41
mohit_aghera CreditAttribution: mohit_aghera at PreviousNext commentedFixing test case failures.
Ensuring that entity is translatable before passing the langcode.
@cbccharlie
I think this should fix the failures that you were experiencing.
Let me know if that helps.
Comment #42
smustgrave CreditAttribution: smustgrave at Mobomo commentedChanges look good. Only think I can think of is a change record that should also be added to the trigger_error.
Comment #43
mohit_aghera CreditAttribution: mohit_aghera at PreviousNext commentedAdded a change record here https://www.drupal.org/node/3357049
Updated the patch accordingly.
Comment #44
smustgrave CreditAttribution: smustgrave at Mobomo commentedCR short and to the point.
Changes look good to me.
Comment #46
mohit_aghera CreditAttribution: mohit_aghera at PreviousNext commentedTriggering retest for #43 since failures seems random.
Comment #47
rpayanmLeft it back to RTBC per #44
Comment #48
bbralaGreat work everyone! Some small nits ;)
I don't understand this change, and do not see the resoning on this in the comments. That worries me.
Can we please be more explicit here? Perhaps:
Comment #49
Vidushi Mehta CreditAttribution: Vidushi Mehta at gai Technologies Pvt Ltd commentedThis patch only addressing the second point mentioned by #48
Comment #50
Vidushi Mehta CreditAttribution: Vidushi Mehta at gai Technologies Pvt Ltd commentedComment #51
bbralaThanks, your interdiff does look weird though, you sure you interdiffed the right patches?
First feedback in my issue is indeed not addressed yet.
Comment #52
smustgrave CreditAttribution: smustgrave at Mobomo commentedShould be moved to review when all points have been addressed or least attempted
Comment #53
Vidushi Mehta CreditAttribution: Vidushi Mehta at gai Technologies Pvt Ltd commentedYes, created an interdiff between 43-49 patches
Comment #54
GRcwolfI've used the patch #43 and encountered an issue with it.
Setup
I have a D10.0.x site. It is multilingual (DE/FR).
I use the json api to get a filtered/sorted list of custom content entities.
The entity type has a translateable name and an untranslatable weight (number).
I request a list of the entities sorted by their weight (primary) and their name (secondary).
My requests look like this:
/LANGCODE/jsonapi/my_entity/my_entity?fields[my_entity--my_entity]=...&filter[status]=1&page[limit]=12&page[offset]=0&sort=field_weight,name
Problem
Not using the patch means that the name sorting doesn't work as expected for the French (non primary language) translations.
However, applying the patch causes a new issue for me.
Filtering by field_weight doesn't work anymore for French but it still works for German (primary/default language).
For French, I simply get a list sorted by name.
The cause appears to be the value in the langcode column of the my_entity__field_weight table.
I went into the database and changed the value to "und" this caused the sorting to also break for German. Updating the column again and setting the values back to 'de' fixed it again for German.
Thoughts
My issue is that the proposed solution seems to break sorting for untranslatable fields.
I guess this didn't happen before as the json api always used the default translation of the field for sorting.
I also guess that the json api is now always using the field value for the current language for sorting.
As the field has no specific value for French, it treats the field as if it where empty. The json api probably doesn't get that the field is not supposed to have a French value as it is not translatable.
Those are just my initial thoughts on this. I haven't had time to dive into the code of the json api and explore how sorting, etc. is implemented.
Please let me know if i understood something completely wrong and this is not unexpected behaviour.
Comment #56
xeniksp CreditAttribution: xeniksp commentedApplying a patch with the changes mentioned on #48 comment in the #43 patch with the interdiff.
Comment #57
xeniksp CreditAttribution: xeniksp commentedRe adding the files again with fixed paths.
Comment #58
xeniksp CreditAttribution: xeniksp commentedHad the same issue mentioned in #54 with untranslatable fields.
Updated the patch so the langcode passes to the query only when the sort field is translatable.
Comment #59
xeniksp CreditAttribution: xeniksp commentedThis patch should pass the failed tests.
Comment #60
_utsavsharma CreditAttribution: _utsavsharma at OpenSense Labs for DrupalFit commentedPatch for 11.x.
Comment #61
_utsavsharma CreditAttribution: _utsavsharma at OpenSense Labs for DrupalFit commentedTried to fix failure in #61.
Comment #62
xeniksp CreditAttribution: xeniksp commentedRe-roll #59 for 10.2.x
Comment #66
mohit_aghera CreditAttribution: mohit_aghera as a volunteer and at PreviousNext commentedThanks for the fixes @xeniksp
I think test run should be green now.
Apart from your changes in the MR, I've addressed following thigns.
Failing tests are passing on local now.
I'll move issue to Needs review after test run is successful.
Comment #67
mohit_aghera CreditAttribution: mohit_aghera at PreviousNext commentedComment #68
smustgrave CreditAttribution: smustgrave at Mobomo commentedLeft some small comments.
CR appears to be outdated slightly.
Hiding patches for clarity.