使用find时遇GraphQL错误Expected Iterable,求Apollo/Node.js/Sequelize解决
Hey there! Let's break down this issue you're facing with your Apollo/GraphQL + Node.js + Sequelize setup. That "Expected Iterable, but did not find one for field" error almost always boils down to a mismatch between your GraphQL schema definition and the data your resolver is returning—let's walk through the most common fixes:
1. Double-check your GraphQL schema field types
First, confirm whether the field throwing the error is defined as a list (e.g., [Recipe!]!) or a single object (e.g., Recipe!).
For example:
If your schema has:
type Query { myRecipes: [Recipe!]! # Expects an array of recipes }But your resolver returns a single
Recipeinstance (instead of an array), GraphQL will throw that "Expected Iterable" error because it was expecting a list, not a single object.Conversely, if you define a field as
Recipe!but your resolver returns an array, you'll hit a similar type mismatch error.
2. Verify your Sequelize query method
Sequelize methods return different data types:
Recipe.findOne()→ Returns a single model instance (or null)Recipe.findAll()→ Returns an array of instances (empty array if no matches)
Make sure your resolver uses the right method for your schema's field type:
- Wrong for a list field:
myRecipes: (_, __, context) => { // Returns a single object, but schema expects an array return context.models.Recipe.findOne({ where: { UserId: context.user.id } }); } - Correct for a list field:
myRecipes: (_, __, context) => { // Returns an array (even empty), which is an Iterable return context.models.Recipe.findAll({ where: { UserId: context.user.id } }); }
3. Check your association resolvers
Since you have a Recipe belongs to User association, make sure your resolvers for related fields are using the correct Sequelize association methods:
- For a
Recipefield that links to its parentUser(single object):Recipe: { user: (parent) => parent.getUser(); // Returns single User instance } - For a
Userfield that links to theirRecipes (list):User: { recipes: (parent) => parent.getRecipes(); // Returns array of Recipe instances }
Mixing up getUser() vs getUsers() (or getRecipe() vs getRecipes()) will cause type mismatches.
4. Ensure your query returns valid data
If your query is returning null instead of an empty array (e.g., when a user has no recipes), that will also trigger the error. findAll() safely returns an empty array when no matches are found, which is a valid Iterable—stick to that instead of methods that return null.
Example of a working setup
Here's a quick snippet tying it all together:
GraphQL Schema
type User { id: ID! username: String! recipes: [Recipe!]! # List of recipes } type Recipe { id: ID! title: String! user: User! # Single user } type Query { myRecipes: [Recipe!]! # Current user's recipes (list) }
Resolvers
const resolvers = { Query: { myRecipes: (_, __, context) => { return context.models.Recipe.findAll({ where: { UserId: context.user.id }, include: [{ model: context.models.User }] }); } }, Recipe: { user: (parent) => parent.getUser() }, User: { recipes: (parent) => parent.getRecipes() } };
The key takeaway here is strict type matching: whatever your schema defines (list or single object), your resolver must return exactly that type. Iterable means any array-like structure—so lists need arrays, single objects need individual instances.
内容的提问来源于stack exchange,提问作者starsneverfall

