Giter Club home page Giter Club logo

Comments (8)

d-exclaimation avatar d-exclaimation commented on May 17, 2024 2

Sorry for just jumping to the conversation here.

I am also interested in which types wouldn't resolve and whether that's an issue during the schema building or the resolving process.

In my case, Both Union and Array types are working fine for me, even with using

func schema() throws -> Schema<Resolver, Context> {

Resolving union

Screenshot 2022-11-01 at 7 24 49 PM

Resolving other types within an Array

Screenshot 2022-11-01 at 7 25 41 PM

I have the working example here

https://github.com/d-exclaimation/pioneer-example/tree/v1

Not sure whether there are other requirements needed to recreate the issue or whether my example is even relevant to the issue to begin with.

from graphiti.

NeedleInAJayStack avatar NeedleInAJayStack commented on May 17, 2024 1

Hey @cshadek, have you been able to get a reproducer of this issue? If not, I'm planning to close it with the can't reproduce status. Thanks!

from graphiti.

cshadek avatar cshadek commented on May 17, 2024 1

@NeedleInAJayStack, so I just checked and ConnectionTypes seem to work fine now without the Types block, so I'll close this issue.

from graphiti.

NeedleInAJayStack avatar NeedleInAJayStack commented on May 17, 2024

Oh dang! Thanks for reporting @cshadek!

From a quick initial investigation, I'm seeing that the Graphiti tests for resolution are passing on union types, array types, and type fields within arrays. We don't seem to have any tests on ConnectionTypes though.

Do you have a schema I could use to recreate the issues you are seeing? It would help me diagnose the issue and I'd love to use it to write testing coverage if we're missing it.

Thanks again!

from graphiti.

cshadek avatar cshadek commented on May 17, 2024

Thanks for getting back so quickly @NeedleInAJayStack!

So I'm not entirely sure why this worked, but I was able to get the Union types and Array types to resolve by changing how the schema was declared.

I was using the old way:

static func schema() throws -> Schema<MainAPI, UserContext> {

and am now doing it as recommended:

let schema = try! Schema<RootResolver, UserContext>(coders: coders) {

For some reason this one change caused the Union and Array types to resolve. I don't really understand why.

Still the connection types are not resolving and then also it seems that nested types inside array types are not resolving either.

Unfortunately, I can't share the exact schema as it's proprietary.

Here's an example:

Type(ParentObject.self, interfaces: [InterfaceA.self, InterfaceB.self]) {
                Field("objects", at: ParentObject.objects, as: [ObjectA].self)
 }

Type(ObjectA.self, interfaces: [InterfaceA.self]) {
                Field("objectB", at: ObjectA.objectB, as: ObjectB?.self)
                Field("objectC", at: ObjectA.objectC, as: ObjectC?.self)
 }
            
Type(ObjectB.self) {
...
}
            
Type(ObjectC.self) {
....
 }

ParentObject, ObjectA, ObjectB, and ObjectC are all Codable types.

I haven't confirmed yet if the schema I just created above resolves or not. I'll check on that, but this is a rough recreation of the schema in question.

In my schema when I comment out the line with the array, all the types resolve. So, I figure it must have to do with the array part.

The actual schema is much more extensive, but this is what seems to be causing a problem. For some reason, ObjectB and ObjectC don't get resolved unless I include them in the Types construct. The server returns an error on introspection.

The only other cause I could think of is if the depth of the schema graph matters. Both ObjectB and ObjectC in my case are nested several layers down the graph.

from graphiti.

NeedleInAJayStack avatar NeedleInAJayStack commented on May 17, 2024

Darn, I'm still having trouble recreating this. I built the test file below based on your example and everything still worked. What is the specific error that you are seeing? And is it on the Schema creation or the query resolution step?

import Graphiti
import NIO
import XCTest

private protocol InterfaceA: Codable {
    var interfaceAField: String? { get }
}
private protocol InterfaceB: Codable {
    var interfaceBField: String? { get }
}
private struct ParentObject: Codable, InterfaceA, InterfaceB {
    let interfaceAField: String?
    let interfaceBField: String?
    let objects: [ObjectA]
}
private struct ObjectA: Codable, InterfaceA {
    let interfaceAField: String?
    let objectB: ObjectB?
    let objectC: ObjectC?
}
private struct ObjectB: Codable {
    let scalar: String
}
private struct ObjectC: Codable {
    let scalar: String
}
private struct TestResolver {
    func parentObject(context _: NoContext, arguments _: NoArguments) -> ParentObject {
        return ParentObject(
            interfaceAField: "ParentObject is A",
            interfaceBField: "ParentObject is B",
            objects: [
                ObjectA(
                    interfaceAField: "ObjectA1 is A",
                    objectB: ObjectB(scalar: "I'm A1's B"),
                    objectC: ObjectC(scalar: "I'm A1's C")
                ),
                ObjectA(
                    interfaceAField: "ObjectA2 is A",
                    objectB: ObjectB(scalar: "I'm A2's B"),
                    objectC: ObjectC(scalar: "I'm A2's C")
                )
            ]
        )
    }
}
private class TestAPI<Resolver, ContextType>: API {
    public let resolver: Resolver
    public let schema: Schema<Resolver, ContextType>

    init(resolver: Resolver, schema: Schema<Resolver, ContextType>) {
        self.resolver = resolver
        self.schema = schema
    }
}

class ReportedTests: XCTestCase {
    func testReportedError() throws {
        let testSchema = try Schema<TestResolver, NoContext> {
            Interface(InterfaceA.self) {
                Field("interfaceAField", at: \.interfaceAField)
            }
            Interface(InterfaceB.self) {
                Field("interfaceBField", at: \.interfaceBField)
            }
            
            Type(ParentObject.self, interfaces: [InterfaceA.self, InterfaceB.self]) {
                Field("interfaceAField", at: \.interfaceAField)
                Field("interfaceBField", at: \.interfaceBField)
                Field("objects", at: \.objects, as: [ObjectA].self)
            }
            Type(ObjectA.self, interfaces: [InterfaceA.self]) {
                Field("interfaceAField", at: \.interfaceAField)
                Field("objectB", at: \.objectB, as: ObjectB?.self)
                Field("objectC", at: \.objectC, as: ObjectC?.self)
            }
            Type(ObjectB.self) {
                Field("scalar", at: \.scalar)
            }
            Type(ObjectC.self) {
                Field("scalar", at: \.scalar)
            }
            
            Query {
                Field("parentObject", at: TestResolver.parentObject)
            }
        }
        let api = TestAPI<TestResolver, NoContext>(
            resolver: TestResolver(),
            schema: testSchema
        )

        let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
        defer { try? group.syncShutdownGracefully() }

        print(
            try api.execute(
                request: """
                query {
                  parentObject {
                    interfaceAField
                    interfaceBField
                    objects {
                        interfaceAField
                        objectB {
                            scalar
                        }
                        objectC {
                            scalar
                        }
                    }
                  }
                }
                """,
                context: NoContext(),
                on: group
            ).wait()
        )
//        Prints:
//        {
//          "data": {
//            "parentObject": {
//              "interfaceAField": "ParentObject is A",
//              "interfaceBField": "ParentObject is B",
//              "objects": [
//                {
//                  "interfaceAField": "ObjectA1 is A",
//                  "objectB": {
//                    "scalar": "I'm A1's B"
//                  },
//                  "objectC": {
//                    "scalar": "I'm A1's C"
//                  }
//                },
//                {
//                  "interfaceAField": "ObjectA2 is A",
//                  "objectB": {
//                    "scalar": "I'm A2's B"
//                  },
//                  "objectC": {
//                    "scalar": "I'm A2's C"
//                  }
//                }
//              ]
//            }
//          }
//        }
    }
}

from graphiti.

cshadek avatar cshadek commented on May 17, 2024

I was able to fix the issue by reordering some of the declarations, and I'm still not sure why the issue was happening.

It's still a problem with ConnectionTypes right? I haven't checked in a while - I still have a Types block with all my ConnectionTypes.

from graphiti.

NeedleInAJayStack avatar NeedleInAJayStack commented on May 17, 2024

@cshadek Yeah, there used to be some weird ordering requirements but they should have been resolved by #84 and #90

As for ConnectionTypes, I'm not sure. I wasn't able to recreate the issue. If you can get me a reproducer, I'd be happy to debug.

from graphiti.

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.