strawberry-graphql / strawberry-django

Strawberry GraphQL Django extension
MIT License
394 stars 115 forks source link

GlobalID not returned via query #372

Closed sdobbelaere closed 9 months ago

sdobbelaere commented 10 months ago

I've setup Strawberry django for a Company model, and created types, input types, queries via relay and mutations. Also, I've setup the MAP_AUTO_ID_AS_GLOBAL_ID: True setting.

When I look at the query result, I can see that the object ID is mapped as a GlobalID.

Screenshot 2023-09-21 at 16 32 48

However, when I want to try and remove that object, the mutation is complaining that my ID is of the wrong type and should be a base64 string.

Screenshot 2023-09-21 at 16 33 19

If the mutation is correct, shouldn't the query supply me with an actual converted GlobalID instead of a stringified id? Or perhaps I'm missing something in my setup?

Some more detail on the models, types, inputtypes and queries below:

class Company(models.Model):
    name = models.CharField(max_length=100)

@strawberry.django.type(Company, filters=CompanyFilter, order=CompanyOrder, pagination=True, fields='__all__')
class CompanyType(relay.Node):
    pass

@strawberry_django.input(Company)
class CompanyInput:
    id: auto
    name: auto

@strawberry.type(name="Query")
class ContactsQuery:
    company: CompanyType = strawberry_django.field(extensions=[IsAuthenticated()])
    companies: ListConnectionWithTotalCount[CompanyType] = strawberry_django.connection(extensions=[IsAuthenticated()])

@strawberry.type(name="Mutation")
class ContactsMutation:
    create_company: CompanyType = mutations.create(CompanyInput, extensions=[IsAuthenticated()])
    create_companies: List[CompanyType] = mutations.create(CompanyInput, extensions=[IsAuthenticated()])
    update_company: List[CompanyType] = mutations.update(CompanyPartialInput, extensions=[IsAuthenticated()])
    delete_company: CompanyType = mutations.delete(NodeInput, extensions=[IsAuthenticated()])
    delete_companies: List[CompanyType] = mutations.delete(NodeInput, extensions=[IsAuthenticated()])

Upvote & Fund

Fund with Polar

bellini666 commented 10 months ago

Hi @sdobbelaere ,

Hrm, that is a corner case of the fields='__all__' you are using.

I'll try to take a look at that soon

sdobbelaere commented 10 months ago

Interesting @bellini666, what should I be seeing?

The following stripped down type, with manually declared fields yields the same query response:

@strawberry.django.type(Company)
class CompanyType(relay.Node):
    id: auto
    name: auto
    related_companies: List['CompanyType']

@strawberry.type(name="Query")
class ContactsQuery:
    companies: ListConnectionWithTotalCount[CompanyType] = strawberry_django.connection(extensions=[IsAuthenticated()])
{
  companies(first:1) {
    edges {
      node {
        name
        id
      }
    }
  }
}
{
  "data": {
    "companies": {
      "edges": [
        {
          "node": {
            "name": "Some name",
            "id": "1"
          }
        }
      ]
    }
  }
}
sdobbelaere commented 10 months ago

Oh I see, it's the declaring of field id that causes the original id to be shown instead of the hash.

As a workaround, it seems that excluding the id from the fields returns the right data.

@strawberry_django.type(Company, filters=CompanyFilter, order=CompanyOrder, pagination=True, exclude=['id'])
class CompanyType(relay.Node, TypeMultiTenantFilterMixin):
    name: auto
    related_companies: List['CompanyType']
{
  companies(first:1) {
    edges {
      node {
        name
        id
      }
    }
  }
}
{
  "data": {
    "companies": {
      "edges": [
        {
          "node": {
            "name": "Some Name",
            "id": "Q29tcGFueVR5cGU6MQ=="
          }
        }
      ]
    }
  }
}
sdobbelaere commented 10 months ago

@bellini666 I added a pull-request to exclude the id from the model-fields. This seemed to be the lowest hanging fruit to handle the inclusions. Looking forward to your thoughts.
Pull request: #373