Javascript 阿波罗服务器联盟未解析?
首先感谢您阅读本文,我花了最后一天的时间来研究这个我根本无法理解的bug。我以前让它工作过,但由于某种原因它停止了。基本上,所有独立服务都能按预期工作。但是,一旦我尝试引用另一封邮件(假设我正在使用配置文件服务并希望从帐户服务中提取电子邮件),它只会返回null。没有错误消息,什么也没有。我已经添加了重要的代码片段,不过如果您想查看整个代码库,请告诉我,我会将其推送到github 账户类型定义:Javascript 阿波罗服务器联盟未解析?,javascript,node.js,apollo-server,apollo-federation,Javascript,Node.js,Apollo Server,Apollo Federation,首先感谢您阅读本文,我花了最后一天的时间来研究这个我根本无法理解的bug。我以前让它工作过,但由于某种原因它停止了。基本上,所有独立服务都能按预期工作。但是,一旦我尝试引用另一封邮件(假设我正在使用配置文件服务并希望从帐户服务中提取电子邮件),它只会返回null。没有错误消息,什么也没有。我已经添加了重要的代码片段,不过如果您想查看整个代码库,请告诉我,我会将其推送到github 账户类型定义: import { gql } from 'apollo-server'; const typeDe
import { gql } from 'apollo-server';
const typeDefs = gql`
# SCALARS
"""
An ISO 8601-encoded UTC date string...
"""
scalar DateTime
# OBJECTS
"""
An account is an Auth0 user that provides authentication details.
"""
type Account @key(fields: "id") {
"The unique Auth0 ID associated with the account."
id: ID!
"The date and time the account was created."
createdAt: DateTime!
"The email associated with the account (must be unique)."
email: String
"Whether the account is blocked."
isBlocked: Boolean
"Whether the account has a moderator role."
isModerator: Boolean
}
extend type Account @key(fields: "id") {
id: ID! @external
"Metadata about the user that owns the account."
profile: Profile
}
type Profile @key(fields: "id") {
"The unique MongoDB document ID of the user's profile."
id: ID!
"The Auth0 account tied to this profile."
account: Account!
"The URL of the user's avatar."
avatar: String
"A short bio or description about the user (max. 256 characters)."
description: String
"Other users that the user follows."
following(
first: Int
after: String
last: Int
before: String
orderBy: ProfileOrderByInput
): ProfileConnection
"The full name of the user."
fullName: String
"The URL of the user's GitHub page."
githubUrl: String
"The user's pinned GitHub repositories and gists."
pinnedItems: [PinnableItem]
"The unique username of the user."
username: String!
"Whether the currently logged in user follows this profile."
viewerIsFollowing: Boolean
}
帐户解析程序:
Account: {
__resolveReference(reference, { dataSources }, info) {
return dataSources.accountsAPI.getAccountById(reference.id);
},
id(account, args, context, info) {
return account.user_id;
},
createdAt(account, args, context, info) {
return account.created_at;
},
isModerator(account, args, context, info) {
return (
account.app_metadata &&
account.app_metadata.roles &&
account.app_metadata.roles.includes('moderator')
);
},
isBlocked(account, args, context, info) {
return account.blocked;
},
},
轮廓类型定义:
import { gql } from 'apollo-server';
const typeDefs = gql`
# SCALARS
"""
An ISO 8601-encoded UTC date string...
"""
scalar DateTime
# OBJECTS
"""
An account is an Auth0 user that provides authentication details.
"""
type Account @key(fields: "id") {
"The unique Auth0 ID associated with the account."
id: ID!
"The date and time the account was created."
createdAt: DateTime!
"The email associated with the account (must be unique)."
email: String
"Whether the account is blocked."
isBlocked: Boolean
"Whether the account has a moderator role."
isModerator: Boolean
}
extend type Account @key(fields: "id") {
id: ID! @external
"Metadata about the user that owns the account."
profile: Profile
}
type Profile @key(fields: "id") {
"The unique MongoDB document ID of the user's profile."
id: ID!
"The Auth0 account tied to this profile."
account: Account!
"The URL of the user's avatar."
avatar: String
"A short bio or description about the user (max. 256 characters)."
description: String
"Other users that the user follows."
following(
first: Int
after: String
last: Int
before: String
orderBy: ProfileOrderByInput
): ProfileConnection
"The full name of the user."
fullName: String
"The URL of the user's GitHub page."
githubUrl: String
"The user's pinned GitHub repositories and gists."
pinnedItems: [PinnableItem]
"The unique username of the user."
username: String!
"Whether the currently logged in user follows this profile."
viewerIsFollowing: Boolean
}
配置文件解析程序:
Profile: {
account(profile, args, context, info) {
return { __typename: 'Account', id: profile.account_id };
},
}
在写这篇文章的时候,我意识到了问题所在,所以我将把它贴在这里,这样你们就不会浪费时间了。我还不明白为什么,我将很快跟进,但出于某种原因,我拥有的权限(使用grahpql shield)。打破了一切,在创建联邦服务时对其进行了注释之后,它神奇地开始工作,对于那些好奇的人来说,这是我的权限 帐户权限
import { and, or, rule, shield } from 'graphql-shield';
import getPermissions from '../../lib/getPermissions';
const canReadAnyAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('read:any_account');
});
const canReadOwnAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('read:own_account');
});
const canEditOwnAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('edit:own_account');
});
const canBlockAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('block:any_account');
});
const canPromoteAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('promote:any_account');
});
const isReadingOwnAccount = rule()(
(parent, { id }, { user }, info) => user.sub === id,
);
const isEditingOwnAccount = rule()(
(parent, { where: { id } }, { user }, info) => user.sub === id,
);
const permissions = shield(
{
Query: {
account: or(
and(canReadAnyAccount, isEditingOwnAccount),
canReadAnyAccount,
),
accounts: canReadAnyAccount,
},
Mutation: {
changeAccountBlockedStatus: canBlockAccount,
changeAccountModeratorRole: canPromoteAccount,
deleteAccount: and(canEditOwnAccount, isEditingOwnAccount),
updateAccount: and(canEditOwnAccount, isEditingOwnAccount),
},
},
{ debug: process.env.NODE_ENV === 'development' },
);
export default permissions;
配置文件权限:
import { and, or, rule, shield } from 'graphql-shield';
import getPermissions from '../../lib/getPermissions';
const canReadAnyAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('read:any_account');
});
const canReadOwnAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('read:own_account');
});
const canEditOwnAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('edit:own_account');
});
const canBlockAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('block:any_account');
});
const canPromoteAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('promote:any_account');
});
const isReadingOwnAccount = rule()(
(parent, { id }, { user }, info) => user.sub === id,
);
const isEditingOwnAccount = rule()(
(parent, { where: { id } }, { user }, info) => user.sub === id,
);
const permissions = shield(
{
Query: {
account: or(
and(canReadAnyAccount, isEditingOwnAccount),
canReadAnyAccount,
),
accounts: canReadAnyAccount,
},
Mutation: {
changeAccountBlockedStatus: canBlockAccount,
changeAccountModeratorRole: canPromoteAccount,
deleteAccount: and(canEditOwnAccount, isEditingOwnAccount),
updateAccount: and(canEditOwnAccount, isEditingOwnAccount),
},
},
{ debug: process.env.NODE_ENV === 'development' },
);
export default permissions;
我还要感谢8位出版社的曼迪,因为她是我用她那本很棒的书学习graphql的原因。这里或那里可能会有一些错误(目前还不确定,因为我很容易出错,如果没有,这可能是一个错误,对其他阅读本书的人来说会很有用),但我确实建议任何想要学习阿波罗的人去看看
在写这篇文章时,我意识到了问题所在,所以我将把它贴在这里,这样你们就不会浪费时间了。我还不明白为什么,我将很快跟进,但出于某种原因,我拥有的权限(使用grahpql shield)。打破了一切,在创建联邦服务时对其进行了注释之后,它神奇地开始工作,对于那些好奇的人来说,这是我的权限 帐户权限
import { and, or, rule, shield } from 'graphql-shield';
import getPermissions from '../../lib/getPermissions';
const canReadAnyAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('read:any_account');
});
const canReadOwnAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('read:own_account');
});
const canEditOwnAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('edit:own_account');
});
const canBlockAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('block:any_account');
});
const canPromoteAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('promote:any_account');
});
const isReadingOwnAccount = rule()(
(parent, { id }, { user }, info) => user.sub === id,
);
const isEditingOwnAccount = rule()(
(parent, { where: { id } }, { user }, info) => user.sub === id,
);
const permissions = shield(
{
Query: {
account: or(
and(canReadAnyAccount, isEditingOwnAccount),
canReadAnyAccount,
),
accounts: canReadAnyAccount,
},
Mutation: {
changeAccountBlockedStatus: canBlockAccount,
changeAccountModeratorRole: canPromoteAccount,
deleteAccount: and(canEditOwnAccount, isEditingOwnAccount),
updateAccount: and(canEditOwnAccount, isEditingOwnAccount),
},
},
{ debug: process.env.NODE_ENV === 'development' },
);
export default permissions;
配置文件权限:
import { and, or, rule, shield } from 'graphql-shield';
import getPermissions from '../../lib/getPermissions';
const canReadAnyAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('read:any_account');
});
const canReadOwnAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('read:own_account');
});
const canEditOwnAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('edit:own_account');
});
const canBlockAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('block:any_account');
});
const canPromoteAccount = rule()((parent, args, { user }, info) => {
const userPermissions = getPermissions(user);
return userPermissions && userPermissions.includes('promote:any_account');
});
const isReadingOwnAccount = rule()(
(parent, { id }, { user }, info) => user.sub === id,
);
const isEditingOwnAccount = rule()(
(parent, { where: { id } }, { user }, info) => user.sub === id,
);
const permissions = shield(
{
Query: {
account: or(
and(canReadAnyAccount, isEditingOwnAccount),
canReadAnyAccount,
),
accounts: canReadAnyAccount,
},
Mutation: {
changeAccountBlockedStatus: canBlockAccount,
changeAccountModeratorRole: canPromoteAccount,
deleteAccount: and(canEditOwnAccount, isEditingOwnAccount),
updateAccount: and(canEditOwnAccount, isEditingOwnAccount),
},
},
{ debug: process.env.NODE_ENV === 'development' },
);
export default permissions;
我还要感谢8位出版社的曼迪,因为她是我用她那本很棒的书学习graphql的原因。这里或那里可能会有一些错误(目前还不确定,因为我很容易出错,如果没有,这可能是一个错误,对其他阅读本书的人来说会很有用),但我确实建议任何想要学习阿波罗的人去看看