奇怪的是,GraphQL 解析器 returns 某些字段为空

GraphQL resolver oddly returns some fields as null

在简要概述中,我正在尝试解析用户列表。我有一个 Apollo 服务器,可以将 accounts-js 模式与我自己的模式拼接起来。所以我扩展了 User 类型以包含一些额外的字段。虽然,在这种情况下,我只能 return SOME 字段,其余为空。

getUsers: async (_, __, ctx) => {
    let action = await usersModel.find();
    console.log(action)
    return action;  
},

我的 me 查询执行 return 所有数据,没有 return 单个空字段。

  extend input CreateUserInput {
    isAdmin: Boolean!
  }

  extend type User {
    isAdmin: Boolean
    profile: Profile
    keys: [Key]
  }

  type Profile {
    avatar: String
    bio: String
  }

  type Key {
    id: ID
    livenet: Boolean
    nickname: String
  }
    
  type Query {
    getUsers: [User]
    me: User
  }

不过,当我 console.log(action) 在我的查询 getUsers 的解析器中时,这些是在我的控制台中 return 编辑的文档。

[ { profile: { bio: 'haha' },
    _id: 5f0a901bdcf725204446c949,
    isAdmin: true,
    services: { password: [Object], email: [Object] },
    createdAt: 1594527771625,
    updatedAt: 1594691054105,
    username: 'ayooo',
    emails: [ [Object] ],
    keys: [ [Object], [Object] ] },
  { profile: { bio: 'testing' },
    _id: 5f0a9439abfce521aba79b2c,
    isAdmin: false,
    services: { password: [Object], email: [Object] },
    createdAt: 1594528825858,
    updatedAt: 1594762680766,
    username: 'lol',
    emails: [ [Object] ],
    keys: [ [Object] ] } ]

如果我下载我的整体 GraphQL 模式,它看起来是这样的:

directive @auth on FIELD_DEFINITION | OBJECT
input AuthenticateParamsInput {
  access_token: String
  access_token_secret: String
  provider: String
  password: String
  user: UserInput
  code: String
}

input CreateUserInput {
  isAdmin: Boolean!
  username: String
  email: String
  password: String
}

type CreateUserResult {
  userId: ID
  loginResult: LoginResult
}

type EmailRecord {
  address: String
  verified: Boolean
}

type ImpersonateReturn {
  authorized: Boolean
  tokens: Tokens
  user: User
}

input ImpersonationUserIdentityInput {
  userId: String
  username: String
  email: String
}

type Key {
  id: ID
  livenet: Boolean
  exchange: String
  nickname: String
  apiKey: String
  apiSecret: String
}

type LoginResult {
  sessionId: String
  tokens: Tokens
  user: User
}

type Mutation {
  setBio(bio: String): ID
  setAvatar(avatar: String): ID
  changeUsername(username: String): ID
  setKey(
    livenet: Boolean
    exchange: String
    nickname: String
    apiKey: String
    apiSecret: String
  ): ID
  createUser(user: CreateUserInput!): CreateUserResult
  verifyEmail(token: String!): Boolean
  resetPassword(token: String!, newPassword: String!): LoginResult
  sendVerificationEmail(email: String!): Boolean
  sendResetPasswordEmail(email: String!): Boolean
  addEmail(newEmail: String!): Boolean
  changePassword(oldPassword: String!, newPassword: String!): Boolean
  twoFactorSet(secret: TwoFactorSecretKeyInput!, code: String!): Boolean
  twoFactorUnset(code: String!): Boolean
  impersonate(
    accessToken: String!
    impersonated: ImpersonationUserIdentityInput!
  ): ImpersonateReturn
  refreshTokens(accessToken: String!, refreshToken: String!): LoginResult
  logout: Boolean
  authenticate(
    serviceName: String!
    params: AuthenticateParamsInput!
  ): LoginResult
  verifyAuthentication(
    serviceName: String!
    params: AuthenticateParamsInput!
  ): Boolean
}

type Profile {
  avatar: String
  bio: String
}

type Query {
  getUsers: [User]
  getProfile: Profile
  serverTime: String
  me: User
  twoFactorSecret: TwoFactorSecretKey
  getUser: User
}

type Tokens {
  refreshToken: String
  accessToken: String
}

type TwoFactorSecretKey {
  ascii: String
  base32: String
  hex: String
  qr_code_ascii: String
  qr_code_hex: String
  qr_code_base32: String
  google_auth_qr: String
  otpauth_url: String
}

input TwoFactorSecretKeyInput {
  ascii: String
  base32: String
  hex: String
  qr_code_ascii: String
  qr_code_hex: String
  qr_code_base32: String
  google_auth_qr: String
  otpauth_url: String
}

type User {
  username: String
  isAdmin: Boolean
  profile: Profile
  keys: [Key]
  id: ID!
  emails: [EmailRecord!]
}

input UserInput {
  id: ID
  email: String
  username: String
}

请注意,getUser 或我的查询 return 请求了所有数据。对于我需要在前端查询的重要内容,getUsers 只会 return 一点,大部分为 null。我试图在我的管理面板的 table 中列出用户。也许这不是最好的方法?有人告诉我!

与查询 megetUser 哪个 return 用户相反。 :/

type Query {
    getUsers: [User]
    me: User
  }

您的查询 getUsers returns User 类型的数组。

  extend type User {
    isAdmin: Boolean
    profile: Profile
    keys: [Key]
  }

为什么 extend?是否存在更早的 User 定义? ...无论如何 graphQL 服务器 return 仅在 return 类型 中定义的字段。您的 User 类型只有 isAdminprofilekeys 属性。只有那些字段会被 returned。

解决方案:扩展您的 User 类型定义以获取其他存在于数据库字段中的类型。

所以在敲了很多其他东西之后,我开始意识到这是因为我没有完全定义我的猫鼬模式!


mongoose.connect(process.env.MONGO_URI, {
  useNewUrlParser: true,
  useFindAndModify: false,
  useCreateIndex: true,
  useUnifiedTopology: true,
});

var usersSchema = new mongoose.Schema({
  username: String,
  isAdmin: Boolean,
  emails: [{ 
    verified: Boolean, 
    address: String 
  }],
  profile: {
    avatar: String,
    bio: String,
  },
  keys: [{ 
    nickname: String,
    exchange: String,
    livenet: Boolean,
    apiKey: String,
    apiSecret: String,
  }]
});

export const usersModel = mongoose.model('Users', usersSchema, 'users');