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

getting "Cannot complete value of unexpected type X" error with children #10

Closed
jaredh159 opened this issue Aug 25, 2021 · 5 comments
Closed

Comments

@jaredh159
Copy link
Contributor

jaredh159 commented Aug 25, 2021

I'm having trouble resolving the children of a model. I definitely might be doing something super dumb though. What's odd is, in my other vapor/graphql app (yes, I have two now...) I haven't hit this problem, but I use parent/children a decent bit. Anyway, I have models like this:

final class Order: Model, Content {
  static let schema = "orders"

  @ID(key: .id)
  var id: UUID?

  @Field(key: "email")
  var email: String

  @Children(for: \OrderItem.$order)
  var items: [OrderItem]

  init() {}
}

final class OrderItem: Model, Content {
  static let schema = "order_items"

  @ID(key: .id)
  var id: UUID?

  @Parent(key: "order_id")
  var order: Order

  @Field(key: "title")
  var title: String

  init() {}
}

The schema looks like this:

let AppSchema = try! Graphiti.Schema<Resolver, Request> {
  Scalar(UUID.self)

  Type(Order.self) {
    Field("id", at: \.id)
    Field("email", at: \.email)
    Field("items", with: \.$items)
  }

  Type(OrderItem.self) {
    Field("title", at: \.title)
    Field("order", with: \.$order)
  }

  Query {
    Field("getOrder", at: Resolver.getOrder) {
      Argument("id", at: \.id)
    }
  }
}

And the resolver looks like this:

final class Resolver {
  struct IdentifyEntityArgs: Codable {
    let id: UUID
  }

  func getOrder(
    request: Request,
    args: IdentifyEntityArgs
  ) throws -> Future<Order> {
    return Order.query(on: request.db)
      .with(\.$items)
      .filter(\.$id == args.id)
      .first()
      .unwrap(or: Abort(.notFound))
  }
}

But when I send a graphql query like so:

query {
  order: getOrder(id: "FBF9C172-E57E-49A8-8806-85F6C923E55A") {
    id
    items {
      title # <-- trying to get one of the children causes the error, without this, it works
    }
  }
}

I get the error Cannot complete value of unexpected type \"OrderItem\".

I feel like I'm missing something stupid. I think I'm sort of following your examples for users/todos in the readme.

If the code above isn't clear enough, I've created a super minimal reproduction repository using an in-memory sql-lite db. If you want to take a look, you can just clone the repo, then run swift run and (in another terminal tab) try bash ./test-error.sh to send the query shown above.

@jaredh159 jaredh159 changed the title getting "Cannot complete value of unexpected type getting "Cannot complete value of unexpected type X" error with children Aug 25, 2021
@jaredh159
Copy link
Contributor Author

I accidentally created the issue before I described the problem, fixed now. Sorry about that.

@alexsteinerde
Copy link
Owner

I haven't had this issue before. Bug I could reproduce it (The example repo was very handy!) and I fixed it.
This GraphQL Swift api is a bit confusing.
By using the Order type in the query this type is registered automatically (implicitly).
The type OrderItem is not implicitly registered.
You can explicitly register the type OrderItem by adding this line to the bottom of your schema: Types(OrderItem.self) (Example: https://github.com/GraphQLSwift/Graphiti/blob/af903a243862c6427935677b91f67df0c21f2a71/Tests/GraphitiTests/StarWarsAPI/StarWarsAPI.swift#L101).
I hope this can help you.

@jaredh159
Copy link
Contributor Author

jaredh159 commented Aug 26, 2021 via email

@jaredh159
Copy link
Contributor Author

Sure enough, that completely fixes it. Although I can't say that I understand fully why. It seems like there's a very explicit registration of the OrderItem type in the schema, when I define it as a GraphQL type using Type(OrderItem.self) { ... on this line. But I'm probably still missing a something.

Really appreciate the help, as always.

@alexsteinerde
Copy link
Owner

I agree, this doesn't seem perfect from an API perspective. But I also don't know enough about the Graphiti implementation so I can't explain the reason for this.
Maybe there will be a better way in the future.

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

2 participants