Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Relay) Output ID instead of GlobalID in GraphQL schema #3551

Open
1 of 3 tasks
aryaniyaps opened this issue Jun 28, 2024 · 5 comments
Open
1 of 3 tasks

(Relay) Output ID instead of GlobalID in GraphQL schema #3551

aryaniyaps opened this issue Jun 28, 2024 · 5 comments

Comments

@aryaniyaps
Copy link
Contributor

aryaniyaps commented Jun 28, 2024

Request to output the ID scalar instead of GlobalID, while generating the GraphQL schema

My understanding is that GlobalID was meant to be an internal helper that resolves nodes, but ended up being a custom scalar.

Feature Request Type

  • Core functionality
  • Alteration (enhancement/optimization) of existing feature(s)
  • New behavior

Description

Currently, while using the relay integration, and working with node types, like the example code below:

import strawberry
from strawberry import relay


@strawberry.type
class Fruit(relay.Node):
    code: relay.NodeID[int]
    name: str
    weight: float

    @classmethod
    def resolve_nodes(
        cls,
        *,
        info: strawberry.Info,
        node_ids: Iterable[str],
        required: bool = False,
    ):
        return [
            all_fruits[int(nid)] if required else all_fruits.get(nid)
            for nid in node_ids
        ]

We get a schema output like this:

scalar GlobalID

interface Node {
  id: GlobalID!
}

type Fruit implements Node {
  id: GlobalID!
  name: String!
  weight: Float!
}

But in the relay specification, which the GlobalID scalar is based on:
https://relay.dev/graphql/objectidentification.htm

calls this scalar by the name ID, and not GlobalID.

I think that there is no mention of a custom scalar to be returned for object identification.

This leads to a lot of issues while working with client libraries such as relay, where directives expect the return type to be the scalar type of ID, and not GlobalID.

An example relay compiler error is shown below:

> client@0.0.0 relay
> relay-compiler

[INFO] [default] compiling...
[ERROR] Error: ✖︎ Invalid use of @deleteEdge on field 'deletedTodoId'. Expected field type 'ID', got 'GlobalID'.

  client/src/components/home-page/Todo.tsx:20:21
   19 │     deleteTodo(todoId: $todoId) {
   20 │       deletedTodoId @deleteEdge(connections: $connections)
      │                     ^^^^^^^^^^^
   21 │     }

[ERROR] Compilation failed.
[ERROR] Unable to run relay compiler. Error details: 
Failed to build:
 - Validation errors: 1 error(s) encountered above.

Output GraphQL schema (After requested change)

interface Node {
 id: ID!
}

type Fruit implements Node {
 id: ID!
 name: String!
 weight: Float!
}

It would be nice if we could change the GlobalID scalar being generated to ID

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@aryaniyaps aryaniyaps changed the title Change Output name of GlobalID scalar to ID (Relay) Output ID instead of GlobalID in GraphQL schema Jun 28, 2024
@aryaniyaps
Copy link
Contributor Author

Here is a temporary solution for anyone who has the same issue, until this has been resolved:

import strawberry
from strawberry.relay import GlobalID

# temporary hack until strawberry fixes relay ID scalar generation
ID = strawberry.scalar(
    strawberry.ID,
    serialize=lambda value: str(value),
    parse_value=lambda value: GlobalID.from_id(value=value),
)

schema = Schema(
    query=query,
    mutation=mutation,
    scalar_overrides={GlobalID: ID},
)

@DoctorJohn
Copy link
Member

Thanks for creating an issue for this. There is already a discussion (#3177) and a PR (#3180) for this. Feel free to join the conversation over there as well.

@rodaan
Copy link

rodaan commented Jul 5, 2024

@aryaniyaps your temporary solution doesn't seem to work for me. I'm getting this:
TypeError: Query fields cannot be resolved.

What version of strawberry are you using?

@aryaniyaps
Copy link
Contributor Author

aryaniyaps commented Jul 6, 2024

@aryaniyaps your temporary solution doesn't seem to work for me. I'm getting this: TypeError: Query fields cannot be resolved.

What version of strawberry are you using?

I think the issue is, after creating a scalar like this;

ID = strawberry.scalar(
    strawberry.ID,
    serialize=lambda value: str(value),
    parse_value=lambda value: GlobalID.from_id(value=value),
)

You are using strawberry.ID in your schema.
You should be using your own ID scalar instead.

I'm on version 0.235.0 btw

@pfcodes
Copy link

pfcodes commented Jul 7, 2024

Here is a temporary solution for anyone who has the same issue, until this has been resolved:

import strawberry
from strawberry.relay import GlobalID

# temporary hack until strawberry fixes relay ID scalar generation
ID = strawberry.scalar(
    strawberry.ID,
    serialize=lambda value: str(value),
    parse_value=lambda value: GlobalID.from_id(value=value),
)

schema = Schema(
    query=query,
    mutation=mutation,
    scalar_overrides={GlobalID: ID},
)

This was helpful, thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants