You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Express+Apollo调用Anilist GraphQL API遇Resolver类型错误求助

解决Apollo Server调用Anilist API时的Resolver类型错误

我尝试用Express+Apollo Server搭建后端,调用Anilist公开API查询动漫详情时,遇到错误:(Graphql) The resolver value isn't of type object。以下是我的代码和报错信息:

const {ApolloServer} = require("apollo-server-express");
const express = require("express");
const app = express();
const {gql} = require("apollo-server-express");

// Schema
let typeDefs = gql`
query { # Define which variables will be used in the query (id)
Media (id: $id, type: ANIME) { # Insert our variables into the query arguments (id) (type: ANIME is hard-coded in the query)
    id
    title {
      romaji
      english
      native
    }
  }
}
`;

// Resolver
let resolvers = {
    id: 15125
};


// Server
const server = new ApolloServer({typeDefs, resolvers});

// Define the config we'll need for our Api request
var url = 'https://graphql.anilist.co',
    options = {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        },
        body: JSON.stringify({
            typeDefs: typeDefs,
            resolvers: resolvers
        })
    };

// Make the HTTP Api request
fetch(url, options).then(handleResponse)
                   .then(handleData)
                   .catch(handleError);

function handleResponse(response) {
    return response.json().then(function (json) {
        return response.ok ? json : Promise.reject(json);
    });
}

function handleData(data) {
    console.log(data);
}

function handleError(error) {
    alert('Error, check console');
    console.error(error);
}

// Apollo
async () => {
    await server.start();
    server.applyMiddleware({app});
};

// Express
app.get("/",(req,res) => res.send("Response from the GET request"));
//app.get("/graphql",(req,res) => res.send("Response from the GET request"));

app.listen({port: 4000}, () => {
    console.log(`Server running on localhost:4000${server.graphqlPath}`);
});

报错信息:

throw new Error(`"${typeName}" defined in resolvers, but has invalid value "${resolverValue}". The resolver's value must be of type object.`);

错误原因分析

代码存在多个核心问题,直接导致了这个错误:

  • TypeDefs语法错误:查询未正确定义变量,不符合GraphQL Schema规范。正确的查询需要明确声明变量,而非直接写query {}。
  • Resolvers结构完全错误:Apollo的Resolvers必须是嵌套对象,对应Schema中的类型(如Query)和字段,而非简单的键值对id: 15125。
  • 错误调用Anilist API:Anilist的GraphQL API接收的是查询字符串和变量,而非Apollo Server的typeDefs和resolvers对象,直接发送这两个对象完全不符合API要求。
  • Apollo Server未正确启动:编写的async箭头函数未执行,server.start()和applyMiddleware根本没有运行。

修正后的完整代码

const { ApolloServer, gql } = require("apollo-server-express");
const express = require("express");
const fetch = require("node-fetch"); // 需执行 npm install node-fetch
const app = express();

// 1. 修正TypeDefs:定义规范的类型和查询
const typeDefs = gql`
  type MediaTitle {
    romaji: String
    english: String
    native: String
  }

  type Media {
    id: Int
    title: MediaTitle
  }

  type Query {
    getAnime(id: Int!): Media
  }
`;

// 2. 修正Resolvers:在Resolver中调用Anilist API获取数据
const resolvers = {
  Query: {
    getAnime: async (_, { id }) => {
      const url = "https://graphql.anilist.co";
      const query = `
        query GetAnime($id: Int!) {
          Media(id: $id, type: ANIME) {
            id
            title {
              romaji
              english
              native
            }
          }
        }
      `;

      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify({
          query,
          variables: { id },
        }),
      });

      const data = await response.json();
      return data.data.Media;
    },
  },
};

// 3. 正确启动Apollo Server并挂载到Express
async function startServer() {
  const server = new ApolloServer({ typeDefs, resolvers });
  await server.start();
  server.applyMiddleware({ app });

  app.listen({ port: 4000 }, () => {
    console.log(`Server running on localhost:4000${server.graphqlPath}`);
  });
}

// 启动服务器
startServer();

// 保留Express的GET路由
app.get("/", (req, res) => res.send("Response from the GET request"));

关键修正说明

  • TypeDefs规范:明确定义MediaTitle、Media和Query类型,getAnime查询接收必填的id参数,返回Media类型,符合GraphQL Schema要求。
  • Resolvers结构:按照Query类型下的getAnime字段编写 resolver 函数,内部负责构造符合Anilist要求的查询请求,获取数据后返回给客户端。
  • 正确调用Anilist API:在resolver中传递查询字符串和变量,而非错误的Apollo配置对象,符合Anilist API的调用规则。
  • 启动逻辑修复:用可执行的async函数启动Apollo Server,确保server.start()和applyMiddleware被正确执行。

内容的提问来源于stack exchange,提问作者Kurokishin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 00:20:38