我有 2 个关于 GraphQL 的问题。
- 我使用创建了一个架构,
makeExecutableSchema
因此我可以创建一个executableSchema
. 我像这样导出executableSchema
和初始化服务器app.js
。
app.use('/graphql', graphqlHTTP({
schema: executableSchema,
rootValue: executableSchema,
graphiql: true,
customFormatErrorFn: (error) => ({
message: error.message,
locations: error.locations,
stack: error.stack ? error.stack.split('\n') : [],
path: error.path
})
}))
executableSchema
但我想知道这是否是同时传递schema
和的正确方法rootValue
?
- 我该如何实现该
resolveType
功能以及在哪里实现?
我收到一条错误消息
Error: Abstract type "LoginResult" must resolve to an Object type at runtime for field "Query.login" with value { __typename: "EmailNotFound" }, received "undefined". Either the "LoginResult" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.
一般来说,我创建了我LoginResult
的 as,union
以便我可以在前端收到更具体的错误消息,以处理不同的错误消息。
这就是我LoginResult
的schema
样子
type AuthData {
token: String!
refreshToken: String!
userId: String!
}
type EmailError {
message: String
}
type PasswordError {
message: String
}
type VerificationError {
message: String
}
union LoginResult = AuthData | EmailError | PasswordError | VerificationError
type Query {
login(email: String!, password: String!): LoginResult!
}
login
解析器方法看起来像这样
const resolvers = {
Query: {
login: async function ({ email, password }) {
try {
const user = await User.findOne({ email: email })
const errors = []
if(!user) {
const error = new Error('User not found.')
error.code = 404
errors.push('404')
return {
__typename: 'EmailNotFound'
}
// throw error
}
const isEqual = await bcrypt.compare(password, user.password)
if(!isEqual) {
const error = new Error('Password is incorrect.')
error.code = 401
errors.push('401')
// throw error
return {
__typename: 'PasswordIncorrect'
}
}
if(!user.isVerified) {
const error = new Error('Please verify your email address')
error.code = 403
errors.push('403')
// throw error
return {
__typename: 'NotVerified'
}
}
// if (errors.length > 0) {
// const error = new Error('Invalid input.')
// error.data = errors
// error.code = 422
// throw error
// }
const token = jwt.sign(
{
userId: user._id.toString(),
email: user.email
},
JWT_SECRET_KEY,
{ expiresIn: '30min' }
)
const refreshToken = jwt.sign(
{
userId: user._id.toString(),
email: user.email
},
JWT_SECRET_KEY,
{ expiresIn: '1h' }
)
return {
token,
refreshToken,
userId: user._id.toString(),
__typename: 'AuthData'
}
} catch(err) {
console.log(err)
}
}
}
}
这就是我从前端创建查询的方式
const graphqlQuery = {
query: `
query UserLogin($email: String!, $password: String!){
login(email: $email, password: $password) {
__typename
...on AuthData {
token
userId
}
...on EmailError {
message
}
...on PasswordError {
message
}
...on VerificationError {
message
}
}
}
`,
variables: {
email,
password
}
}
任何帮助都会得到帮助!