reactjs - Apollo graphql 正在为 mongodb 中的空子文档返回空数据
问题描述
我在我的 apollo graphql 突变中添加了另一个字段(联系人),但是在检索该字段时它会产生错误数据。即使匹配的 mongodb 字段是否有真实数据,graphql 也会返回具有空值的多个字段。
我已经尝试在 apollo 客户端 graphql 选项中删除 __typename ,但它没有帮助。当前堆栈是:
reactjs 16.8.5
react-apollo 2.5.2
mongodb 3.6.11
mongoose 5.3.6
apollo-server 2.3.1
我不明白为什么这样做,因为我有另一个几乎相同但返回正确的子文档。
// CLIENTSIDE
// APOLLO SETUP
const cache = new InMemoryCache({
dataIdFromObject: object => object.key || null
})
const AuthLink = (operation, forward) => {
const token = cookies._uid
operation.setContext(context => ({
...context,
headers: {
...context.headers,
authorization: token
}
}))
return forward(operation)
}
const httpLink = new HttpLink({
uri:"/graphql",
credentials: "include"
})
// mutation
export const LOGIN_MUTATION = gql`
mutation loginMutation($email: String!, $password: String!) {
login(input: {email: $email, password: $password}) {
token
user {
_id
contacts { // This is the subfield in question
_id
username
}
subscriptions { // This subfield returns corretly
_id
title
levels {
_id
}
}
}
error {
path
message
}
}
}
`
// SERVERSIDE
// APOLLO SETUP
const baseSchema = `
schema {
query: Query,
mutation: Mutation
}
`
const schema = makeExecutableSchema({
typeDefs: [
userTypeDefs,
],
resolvers: merge(
{},
userResolvers,
)
})
const {ObjectId} = mongoose.Types
ObjectId.prototype.valueOf = function() {
return this.toString()
}
export default new ApolloServer({
introspection: true,
credentials: true,
schema,
context: ({req, res}) => ({
url: req.protocol + "://" + req.get("host"),
req
})
})
// USER MONGOOSE MODEL
export const UserSchema = new mongoose.Schema(
{
contacts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}
],
firstName: {
type: String
},
lastName: {
type: String
},
username: {
type: String,
lowercase: true,
unique: true,
required: [true, "can't be blank"],
match: [/^[a-zA-Z0-9]+$/, "is invalid"],
index: true
},
sentRequests: [
{
username: {
type: String,
default: ""
}
}
],
subscriptions: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Course"
}
],
password: {
default: "",
required: [true, "can't be blank"],
type: String
}
},
{timestamps: true}
)
UserSchema.plugin(uniqueValidator, {message: "is already taken."})
export default mongoose.model("User", UserSchema)
// USER GRAPHQL SCHEMA
type User {
_id: ID
contacts: [User]
email: String!
username: String
subscriptions: [Course]
createdAt: String
updatedAt: String
}
type AuthPayload {
token: String
user: User
error: [Error]
}
input LoginInput {
email: String!
password: String!
}
type Mutation {
login(input: LoginInput): AuthPayload
}
// USER RESOLVER
const login = async (parent, args, ctx, info) => {
let email = args.email
let user = await User.findOne({email})
.populate("subscriptions")
.populate("contacts")
.exec()
if (!user) {
arrayOfErrors.push({
path: "email",
message: "invalid email"
})
} else if (user) {
console.log("user: ", user)
return {
user,
error: arrayOfErrors
}
}
Mutation: {
login
}
// CONSOLE LOG CLIENTSIDE
user:
confirmed: true
contacts: Array(3) // returns an array of 3 items?? It's [] in mongodb
0: {_id: null, username: null}
1: {_id: null, username: null}
2: {_id: null, username: null}
length: 3
__proto__: Array(0)
subscriptions: Array(1)
0: {_id: "5cd36fc1c8d1e222b99d9c58", title: "Korean Class 101 Study",
length: 1
__proto__: Object
__proto__: Object
// CONSOLE LOG SERVERSIDE
POST /graphql 200 64.359 ms - -
user: {
contacts: [ ],
subscriptions:
[ { _id: 5cd6f7f8212af32c75555d4b,
subscribers: 2,
owner: 5cd36edec8d1e222b99d9c57,
createdAt: 2019-05-09T00:09:37.845Z,
updatedAt: 2019-05-11T16:36:14.661Z,
__v: 23 } ],
password: '$2b$10$bkjiazklcoqlkJSJSAioxoAqkoajsdjnqjkiaallaadfadfp7zS',
_id: 5cd36edec8d1e222b99d9c57,
email: 'example@test.com',
username: 'example',
createdAt: 2019-05-09T00:05:50.314Z,
updatedAt: 2019-05-29T17:23:21.545Z,
__v: 32
}
我希望一个空数组返回 [ ],而不是 graphql 返回一个包含 3 个具有空值的项目的数组。即使我将真实联系人添加到数据库中,它仍会返回 3 个具有空值的项目。订阅正确返回,但它几乎与联系人字段相同,只是在猫鼬模型中是“课程”类型而不是“用户”类型。
解决方案
我怀疑任何人都会遇到这种类型的错误,但如果你这样做,这里有一个解决方案。在开发过程中,我将此代码放在解析器中以进行测试。删除它解决了这个问题。
// USER RESOLVER
...
Query: {...},
/* code to remove
User: {
contacts: user => {
return ["Mo", "Larry", "Curly"]
}
}
*/
Mutation: {...}
一件非常微不足道的事情,但几个月没有出现在这个实际代码中,所以很难发现。我从没想过这三个傀儡会让我如此头疼。
推荐阅读
- merge - Jsonnet 中的 + 运算符和 std.mergePatch 有什么区别?
- c - 'g' 在此函数中使用未初始化 [-Wuninitialized]
- python - 如何在我们绘制列表平均值并显示其余范围的列表中绘制键的字典? [Python]
- python - 更快的 datetime.strptime
- php - Magento 2 搜索显示 404 Not Found
- jquery - JQuery 文本搜索:无法获得正确的标签/元素来搜索表格文本
- azure-service-fabric - Service Fabric - 如何在我的本地开发集群上启用 BackupRestoreService
- bluetooth - BLE 设备中可能的连接数
- .net-core - 使用 Microsoft Graph SDK 列出我组织中所有组的计划
- css - 为什么我的 VS code live sass 编译器编译单独的 css 文件?