Code Monkey home page Code Monkey logo

Comments (12)

erebus1 avatar erebus1 commented on August 10, 2024 4

Guys, thanks a lot for your help with an investigation!
@jtesch I've added your fix with tests and published new version

@jtesch @firaskafri @fabianriewe Can you please test 0.0.6 version in your projects, and report if any issue with external is still there?

from graphene-federation.

firaskafri avatar firaskafri commented on August 10, 2024 1

@erebus1 True in our case the type is defined in another service.
But the issue is generic and goes beyond base types (of any type, not only DjangoObjectType's) the regex identifying the external fields when a type is implementing "Node".

from graphene-federation.

erebus1 avatar erebus1 commented on August 10, 2024

Thanks for reporting!
Seem it is an issue with regexp
Can you please share your schema definition, so that I'll be able to reproduce an issue?
At least [doc] ExamResult [payment] Plan and types which has @external on FIELD_DEFINITION

from graphene-federation.

fabianriewe avatar fabianriewe commented on August 10, 2024

Sure! ExamResult type has an external user. But other type haven them as well.

Plan.py in payment/types/plan.py

from graphene_federation import key
from graphene_mongo import MongoengineObjectType

from src.models import PlanModel


@key('id')
class Plan(MongoengineObjectType):
    class Meta:
        model = PlanModel

ExamResult.py in doc/types/exam_result.py

import graphene
from graphene_mongo import MongoengineObjectType

from graphene_federation import key
from src.models import ExamResultModel
from .exam import Exam
from .material import Material
from .topic import Topic
from .user import User


@key('id')
class ExamResult(MongoengineObjectType):
    exam = graphene.Field(Exam)
    material = graphene.Field(Material)
    gaps = graphene.List(Topic)
    user = graphene.Field(User)

    class Meta:
        model = ExamResultModel

external User in doc/types/user.py

import graphene

from graphene_federation import extend, external


@extend('id')
class User(graphene.ObjectType):
    id = external(graphene.ID())

I need to overwrite external relations, because by default MongoengineObjectType sets them as internal.

from graphene-federation.

firaskafri avatar firaskafri commented on August 10, 2024

@erebus1 We are facing the same issue. Any ideas or pointers?

from graphene-federation.

firaskafri avatar firaskafri commented on August 10, 2024

@erebus1

After a lot of investigation, it turns out that the regex is marking wrong occurrences when you try to use the external directive on a DjangoObjectType's field.

from graphene-federation.

erebus1 avatar erebus1 commented on August 10, 2024

@firaskafri Thanks for an investigation!
I'll try to fix it on weekends

from graphene-federation.

erebus1 avatar erebus1 commented on August 10, 2024

@firaskafri Can you please provide an example when you're using external on DjangoObjectType's field

As I understand if the field is of type DjangoObjectType - then this means this is a base type and should not be marked as external

Or you mean that this type is defined in another service?

from graphene-federation.

devopsjosh avatar devopsjosh commented on August 10, 2024

I am experiencing a similar issue but receiving Directive "external" may not be used on INPUT_FIELD_DEFINITION.

I have a Django model that stores an id and a set of objects (ManyToMany). This model is an extension of a model in another service where the id's match. The schema is setup as

Service 1

@key(fields="id")
class MyObjectNode(DjangoObjectType):
    class Meta:
        model = MyObject
        interfaces = (RelayNode,)

Service 2

@extends(fields="id")
class MyObjectNode(DjangoObjectType):
    id = external(ID(required=True))
    related_object_set = DjangoConnectionField(RelatedObjectNode)
    
    def resolve_related_object_set(self, info):
        return self.related_object_set.all()

    class Meta:
        model = MyObject
        interfaces = (RelayNode,)

I have two mutation classes that adds/removes RelatedObjects to/from the extended MyObject class. It gives the above error when using more than one mutation that returns a MyObjectNode.

class AddRelatedObjectMutation(graphene.Mutation):
    class Arguments:
        id = graphene.UUID(required=True)
        related_objects = graphene.List(graphene.UUID, required=True)

    my_object = graphene.Field(MyObjectNode)
    errors = graphene.List(
        ErrorType, description="May contain more than one error for same field."
    )

    def mutate(self, info, id, related_objects):
        my_object = MyObject.objects.get(pk=id)
        my_object.related_objects.add(*related_objects)

        return AddRelatedObject(my_object=my_object, errors=None)


class RemoveRelatedObjectMutation(graphene.Mutation):
    class Arguments:
        id = graphene.UUID(required=True)
        related_objects = graphene.List(graphene.UUID, required=True)

    my_object = graphene.Field(MyObjectNode)
    errors = graphene.List(
        ErrorType, description="May contain more than one error for same field."
    )

    def mutate(self, info, id, related_objects):
        my_object = MyObject.objects.get(pk=id)
        my_object.related_objects.remove(*related_objects)

        return RemoveRelatedObjectMutation(my_object=my_object, errors=None)


class Mutation(graphene.ObjectType):
    add_related_objects = AddRelatedObjectMutation.Field()
    remove_related_objects = RemoveRelatedMutation.Field()

If I swap out my_object = graphene.Field(MyObjectNode) on the second mutation for something like ok = graphene.Boolean(), my Apollo Gateway will work. Doesn't seem to like the mutations having the same NodeType returned.

Edit: Simply renaming the RemoveRelatedObjectMutation class to DetachRelatedObjectMutation, allowed it to work. I inspected and compared the produced schema from get_sdl() in service.py of both mutation type definitions. The one that doesn't work has @external directive added to the input definition on the mutation, whereas the other does not.

from graphene-federation.

devopsjosh avatar devopsjosh commented on August 10, 2024

Schema:

 type RemoveRelatedObjectMutation{   myObject: MyObject   errors: [ErrorType] }  input MyObjectRelatedInput {   id: UUID!   tasks: [UUID]! }

After checking what the regex matches on my mutation schema, I noticed it will match the following:

MyObject   errors: [ErrorType] }  input MyObjectRelatedInput {   id: UUID!

And will proceed to add @external after the id definition.

Perhaps looking for @key or type\s{entity_name} when marking it external would help.

from graphene-federation.

erebus1 avatar erebus1 commented on August 10, 2024

I close an issue
Feel free to reopen it if you'll see an issue again

from graphene-federation.

mahdyhamad avatar mahdyhamad commented on August 10, 2024

Facing this error when using id field in filter_fields
More details:
It happened when an id is in filter_fields of a DjangoObjectType Node.

This Node is inside an extended Node as a DjangoFilterConnectionField.
This is happening on a specific node only and when adding the 'id' field in filter_fields.
If filter_fields = { "id": ["icontains"] } only, this works fine, but when "exact" lookup is added to the list, I have this error.
... that would be filter_fields = { "id": ["exact"] }

A turnaround solution to this problem is to pass the id to the resolver.
Ex:
foo_field = DjangoFilterConnectionField(FooNode, id=graphene.ID(required=False))

If I am not the only one facing this problem when trying to filter, please open this issue

from graphene-federation.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.