Cms: Pass in slugs to GraphQL relatedTo argument

Created on 22 Oct 2019  Â·  19Comments  Â·  Source: craftcms/cms

We need to be able to pass slugs as arguments in GraphQL requests made using the relatedTo query.

This would be essential for things like having a url /blog/cats that makes a request for a list of blogposts related to the cats category. In this case, you won't know the id, so you would have to make two requests to get the list of categories first just to get the id.

enhancement graphql

Most helpful comment

@dangayle so I just pushed 6ebde1526167dfab621a561b56cd60598507b471 to a separate branch, which is planned to get merged into Craft 3.6

All 19 comments

GraphQL basically wraps around Element queries, so this would first have to be implemented in element queries. If this were a twig page, it would still require two separate element queries, right? Of course, there's the difference that it would happen on a single HTTP request, but the point still stands.

So, there are three ways of going forward:

1) do two requests (not optimal, but currently the only way out of the box)
2) implement matching elements by slugs in element queries (feels overkill-y to me, but it's just an opinion)
3) facilitate using the results of a GraphQL query in another GraphQL query in a single request.

My personal favorite is (3). Even though it's not trivial, this seems like the option that offers the most flexibility. But I can't promise it will happen for 3.4.

@andris-sevcenko This of course attracted my divergent thoughts tendencies, probably as it models a particular aspect not fully in mind yet about GraphQL.

A couple of things found might be useful to your thinking?

back to what I'm supposed to be doing...

Hi @andris-sevcenko, i checked the Changelog in the 3.5 branch to see if this feature will be added there but could not find anything related to this issue here.

Is this feature still planed to be part of 3.5?

@denisyilmaz probably not. 3.5 (in terms of GraphQL) will be mainly a mutation-themed release.

This lack of urgency is because there _is_ a way of doing this out of the box by running two queries instead of one (one to fetch ids by slugs, the second one to fetch the relations by ids).

In the long term, I still want to implement the option (3) from the list above as that would add the flexibility of rolling two requests into one.

@andris-sevcenko thanks for the quick reply. I got this to work in my project the way you described with the two queries. Its working but introduces a delay for page load around 50-100ms depending on server conditions because we have now two roundtrips.

I think this could be resolved when GraphQL Query Batching is working https://github.com/craftcms/cms/issues/5677 . any updates on this issue?

EDIT: just realized this is the Option 3 you are talking about, right?

Yeah, talking about (3). but I'll see if I can add the batching thing to 3.5!

@denisyilmaz Query Batching just takes two queries that are executed in short intervals and combines them into one request. So, given that you can't do the second query before you get the first one back, it won't help you.

As far as the query sequencing (that's the name I'm choosing to call the (3) goes, I've made it happen locally, but it's not part of the GraphQL spec, so, most likely, will happen as a plugin at some point)

@andris-sevcenko thanks for the clarification. I already guessed this would be not working. But wouldn't it still be easier to extend the entry/entries relatedTo parameter to allow slugs as well? or is this a GraphQL spec as well that only IDs are allowed? I just feel having this sequencing for only getting ids (slug > id > relatedTo(id)) of entries would be something that can happen easier on the server.

In my current project I got it working with to API requests chained after each other. Performance is ok, but still, two requests to get an entry that is related to some other entry where I don't know the ID in runtime this chaining is not a very clean solution.

Still locking forward to Query Batching because then some of the other (unrelated) api-requests might be batched and the Sequencing of the ID would be even less of an issue performance wise.

But wouldn't it still be easier to extend the entry/entries relatedTo parameter to allow slugs as well?

It's not something that's easy to add to Craft Element queries. IDs are easy. They are unique and refer to a specific element, which cannot be said for slugs. Even if it weren't for the potential of elements with the same slug existing in multiple sites, also every draft and revision of a given entry will have the same slug so identifying en element with a slug is nowhere near as specific as identifying it with an id.

That kind of begs a question of unifying in the latter-day drafts/revisions architecture, doesn't it?

Could not a gql query be defaulted to only present the single _active_ element of a slug per site, with subsidiary queries available to ask for the sets of drafts or revisions if you want to examine those?

Could not a gql query be defaulted to only present the single active element of a slug per site

GQL queries wrap around element queries and relatedTo is an element query parameter.

The problem here would not be solved by limiting the returned data, since the limitations need to be applied to the join that relatedTo eventually ends up performing and, honestly, that parameter is convoluted enough without any "use slugs, but I don't want drafts" switches.

Hmm, yes, I didn't think towards the join, and those sorts of joins within Craft can be nightmarish enough, which is a good bit of why the results they enable are so straightforward and useful.

I'd also been off-screen recalling how I handled this successfully in Live Vue, which yes, is still successful, but which I don't see ever offering. But this didn't have to deal with joins.

I guess I will leave you with the intuition that you may well be the guy who could suddenly see a way to partition or otherwise work with this...and maybe also that you are a bit like me, in that such solutions reliably start appearing in mind, every time,, just after I might have expressed the thought, 'can't'.

Cheers, Andris, as ever

Element queries do filter out drafts & revisions by default, so all good on that front. But slug ambiguity is a legit concern.

Seriously made me laugh, with your new(?) avatar pic, @brandonkelly Brandon :)

Just a thought, and apologies if this was covered in other thoughts above and I misunderstood, would a good syntax for this be something like relatedEntries, relatedAssets etc. which behave like a normal entries / asset loop but with the relatedTo pre-populated with the current entry. So you could do things like this very weird, but hopefully useful example...?

entry(section:"offices",slug:"london"){
   title,
   id,
   ... on offices_offices_entry {
      peopleInThisOffice: relatedEntries(section:"people"){
        title
      }
      facilitiesInThisOffice: relatedEntries(section:"facilities"){
        title
      }
      imagesTaggedInThisOffice: relatedAssets(source:"images"){
        title
      }
   }
}

@andrewfairlie That seems like a slightly different FR than what this one is about – can you post it as a new issue?

It does give me a good idea about how this FR could be resolved. In addition to the generic relatedTo argument (which only accepts a list of IDs), we could add new element type-specific ones – relatedToEntries, relatedToAssets, etc., which accept a criteria object.

Going with the original example (fetch all entries related to the cats category):

query BlogPostsByCategory($catSlug: String) {
  entries(section: "blog", relatedToCategories: {slug: $catSlug}) {
    ... on blog_article_Entry {
      title
      body
    }
  }
}

@dangayle so I just pushed 6ebde1526167dfab621a561b56cd60598507b471 to a separate branch, which is planned to get merged into Craft 3.6

Awesome! This is great news.

On Fri, Nov 27, 2020 at 3:43 AM Andris Sevcenko notifications@github.com
wrote:

@dangayle https://github.com/dangayle so I just pushed 6ebde15
https://github.com/craftcms/cms/commit/6ebde1526167dfab621a561b56cd60598507b471
to a separate branch, which is planned to get merged into Craft 3.6

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/craftcms/cms/issues/5143#issuecomment-734794849, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AAA7US5ZE3LGWZPVN3TIQBLSR6GEVANCNFSM4JDUNMKA
.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

angrybrad picture angrybrad  Â·  3Comments

leigeber picture leigeber  Â·  3Comments

angrybrad picture angrybrad  Â·  3Comments

bitboxfw picture bitboxfw  Â·  3Comments

richhayler picture richhayler  Â·  3Comments