question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

replace relay global id with object id

See original GitHub issue

So basically I am trying to query through the objects using relay. when I fetch the id it returns the relay global id.

{
  allShops(first: 1){
    edges{
      node{
        id
        name
      }
    }
  }
}

output

{
  "data": {
    "allShops": {
      "edges": [
        {
          "node": {
            "id": "U2hvcE5vZGU6NTA4NTRhYTUtNzJmZC00NzNmLThhNTEtNmQxNWJjYWUwNjE5",
            "name": "pops"
          }
        }
      ]
    }
  }
}

it works just fine , even filtering and stuff. But the problem occurs in mutation i cant pass the relay id while updating or referencing an entry in django. I want the object id there.

A workaround I tried Use this function

id = from_global_id(id)

its in graphql_relay.node.node but the problem is it increases a lot of my code and everywhere I want i have to use this and I have a lot of code to manage already.

*Is there any way to globally replace relay global id with model id,(i am using Django’s UUID field) keeping two ids is redundant code

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:4
  • Comments:14 (1 by maintainers)

github_iconTop GitHub Comments

16reactions
jkimbocommented, May 10, 2020

I think there 2 issues here which are causing confusion:

1. DjangoFilterConnectionField returns Relay IDs by default

The documentation doesn’t do a good job of differentiating what is a relay only concept and what is not the code often defaults to assumption that you are using relay which is often not the case. The connection pattern (edges, nodes etc) is a relay concept that has been adopted by other graphql client libraries because it allows efficient filtering and pagination of long lists. The Relay Global ID is specific to Relay only and (as far as I know) hasn’t been adopted by any other graphql client library and is often very confusing to people who are not using Relay.

The fact that Graphene-Django’s API defaults to relay in some places and not others (this issue being a good example) is not great and we should move to default to non relay specific APIs with relay being support being an option.

In this particular use case the support is there to not return Relay IDs from DjangoFilterConnectionField. You can do it by changing the ShopTypeNode type to not implement the relay.Node interface but instead mark it as a plain connection:

class ShopTypeNode(DjangoObjectType):
    class Meta:
        model = ShopType
        use_connection = True

This option is not documented and IMO is not very intuitive. I find it confusing that you would “enable the connection” on the ObjectType and I think it makes more sense for you to define a wrapper Connection type like you would do it in graphene: https://docs.graphene-python.org/en/latest/relay/connection/ . For example:

class ShopTypeNode(DjangoObjectType):
    class Meta:
        model = ShopType

class ShopTypeConnection(relay.Connection):
	class Meta:
		node = ShopTypeNode

class Query(ObjectType):
	all_shops = DjangoFilterConnectionField(ShopTypeConnection, filterset_class=ShopFilter)

It’s more verbose but I think it makes a lot more sense. Feedback welcome.

Additionally I think we should try and add filter support to the plain DjangoListField because I don’t think you should have to use the connection pattern if you don’t want to.

2. Support for Relay IDs in DjangoModelFormMutation

Again, because the Graphene-Django API is inconsistent it’s quite easy to assume that the mutation classes would accept Relay IDs because that is what is being returned by the connection fields. However that is not the case as @ulgens points out. In my opinion it would be better to make relay specific versions of the mutation classes (or at least document how to accept Relay IDs) rather than try and figure out if the ID is a Relay ID or not. Not sure exactly what the API should look like. @ulgens any ideas?

4reactions
ulgenscommented, May 10, 2020

@jkimbo What about creating a new issue to discuss relay - non-relay stuff? I think it’s doable and i have some ideas, but not sure when / where to implement them. v3 is a good candidate, but it’s too late for that version imo, maybe with 3.1.

Read more comments on GitHub >

github_iconTop Results From Across the Web

GraphQL Global Object Identification Specification - Relay
This id should be a globally unique identifier for this object, and given just this id , the server should be able to...
Read more >
How to use a custom id with Graphene and Relay?
Once you do that you'll have to replace the two references to relay.Node with CustomNode like so. class ExampleTableNameNode(DjangoObjectType): ...
Read more >
Relay/GraphQL: De-mystifying Node Interface/ID | Code Oil
The Relay/GraphQL tutorial's chapter on Object Identification elucidates how Relay/GraphQL requires Node IDs for re-fetching objects.
Read more >
Relay Support - Join Monster - Read the Docs
Global ID. These are Relay's unique identifiers used as cache keys. Implementing is relatively straight-forward. We can import the globalIdField helper and ...
Read more >
The magic of the Node interface - DEV Community ‍ ‍
Global Object Identification in GraphQL is about two things: ... and Relay compatible as well!) query: node(id: "MDQ6VXNlcjM1Mjk2").
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found