Comments (8)
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
Resolving other types within an Array
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.
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.
@NeedleInAJayStack, so I just checked and ConnectionTypes seem to work fine now without the Types block, so I'll close this issue.
from graphiti.
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 ConnectionType
s 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.
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.
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.
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.
@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)
- PartialSchema with coders HOT 1
- Federation N+1 query problem HOT 2
- Schema Introspection Failure HOT 2
- How to access the selectionSet from the Resolver ? HOT 3
- Renaming ConnectionTypes isn't working HOT 6
- Feature: Create better support for custom connections HOT 2
- PartialSchema error with argument in type field HOT 5
- Federation reference resolver with filtering
- Potential Bug with Input types HOT 2
- 'Identifiable' is only available in iOS 13.0 or newer HOT 2
- Decimal and NSDecimal HOT 3
- Bearer and basic authorization HOT 1
- Would it make sense to make NoArguments init public? HOT 2
- Is there a way to override the name of a Value in an Enum? HOT 2
- Coders with Date as Double in schema
- Improvements to SchemaBuilder and allowing sub schemas HOT 13
- PartialSchema Type extensions HOT 9
- How do you include a ConnectionType in a PartialSchema? HOT 2
- The order of PartialSchemas matters for Interfaces, Unions, and ConnectionTypes - is this intentional? HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphiti.