AccountsJs TypeORM用户创建异常:无报错但MongoDB无数据
你这情况典型得很——调用创建用户的Mutation没报错,数据库里却啥都没有,这种"静默失败"一般都是配置链里某一环没打通。结合你贴的代码,我整理了几个核心排查点和修复方案:
1. 让TypeORM自动同步实体到MongoDB
MongoDB不像SQL数据库会自动建表(集合),TypeORM需要开启synchronize选项才能自动生成AccountsJs所需的用户集合。你的数据库连接代码里缺了这个配置,导致实体无法映射到MongoDB的集合。
修改connectDatabase函数,添加同步配置(开发环境用这个很方便,生产环境建议用迁移工具):
export const connectDatabase = async (): Promise<Connection> => { const connection = await createConnection({ url: uri, type: "mongodb", database: "main", w: "majority", useNewUrlParser: true, useUnifiedTopology: true, logger: "advanced-console", logging: "all", entities: [ path.join(__dirname, "/../entities/**/*.*"), ...require("@accounts/typeorm").entities ], // 新增:开发环境自动同步实体到数据库 synchronize: process.env.NODE_ENV === "development" }); console.log(connection.options.entities); return connection; };
2. 修复Apollo Schema的合并逻辑
你的Schema合并方式有问题:buildTypeDefsAndResolvers合并了自定义Resolver,但后面创建可执行Schema时,只传入了schema.resolvers,没把Accounts的Resolver加进去。这就导致createUser这个Mutation的处理逻辑根本没注册,调用时看似成功,实则啥都没执行。
先导入mergeResolvers,然后修改Schema配置:
// 先补上导入 import { mergeTypeDefs, mergeResolvers } from "graphql-toolkit"; // ... 其他代码 ... const schema = await buildTypeDefsAndResolvers({ resolvers: [resolvers, CategoryResolver, accounts.resolvers] }); // 正确合并所有TypeDef和Resolver const executableSchema = makeExecutableSchema({ typeDefs: mergeTypeDefs([accounts.typeDefs, schema.typeDefs]), resolvers: mergeResolvers([accounts.resolvers, schema.resolvers]), // 这里必须合并Accounts的Resolver schemaDirectives: { ...accounts.schemaDirectives } }); const server = new ApolloServer({ schema: executableSchema, context: accounts.context, playground: true });
3. 验证AccountsServer的初始化有效性
虽然你的代码看起来没问题,但可以加个日志确认Accounts的实体是否被正确加载:
export const setUpAccounts = async (connection: Connection) => { const db = new AccountsTypeorm({ connection, cache: 1000 }); // 检查用户实体是否被TypeORM识别 const userRepo = connection.getRepository(require("@accounts/typeorm").entities.User); console.log("用户实体仓库已加载:", !!userRepo); const password = new AccountsPassword({ twoFactor: { appName: "Events" } }); const accountsServer = new AccountsServer( { db, tokenSecret: "terrible secret", siteUrl: "http://localhost:3000" }, { password } ); const accounts = AccountsModule.forRoot({ accountsServer, headerName: "x-events-token" }); return accounts; };
启动后如果控制台输出用户实体仓库已加载: true,说明这部分没问题。
4. 检查MongoDB Atlas的权限与连接配置
- 确认你的Atlas数据库用户拥有
readWrite权限,别只给了read权限; - 检查连接字符串里的数据库名是
main(你代码里配置的database: "main"),登录Atlas后看看main数据库是否存在; - 确保你的IP地址已经加入Atlas的IP白名单,有时候权限不足会导致写入静默失败,连报错都没有。
5. 开启AccountsJs的调试日志
给AccountsServer加上日志配置,看看创建用户时的内部流程:
const accountsServer = new AccountsServer( { db, tokenSecret: "terrible secret", siteUrl: "http://localhost:3000", // 开启调试日志 logger: { level: "debug", transport: { type: "console" } } }, { password } );
执行Mutation时,控制台会输出详细日志,能帮你定位到底是哪个环节卡住了。
按上面的步骤排查后,应该就能解决问题了。如果还是不行,可以看看Apollo Playground的返回数据,以及MongoDB Atlas的数据库日志,进一步缩小排查范围。
内容的提问来源于stack exchange,提问作者Imad Bloum

