如何让 UserApi 中的 User 实体连接到数据库?
我有一个带有 redis 缓存的 apollo-express-server。 这是index.ts:
const main = async () => {
const app = express();
app.use(
cors({
credentials: true,
origin: process.env.CLIENT_URL,
})
);
const router = express.Router();
const store = await createConnection();
const redis = new Redis({
port: Number(process.env.REDIS_PORT),
host: process.env.REDIS_HOST,
//password: process.env.REDIS_PASSWORD,
});
const RedisStore = connectRedis(session);
const redisStore = new RedisStore({
client: redis,
});
app.use(bodyParser.json());
app.use(
session({
store: redisStore,
name: process.env.COOKIE_NAME,
sameSite: "Strict",
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: false,
maxAge: 1000 * 60 * 60 * 24,
},
} as any)
);
app.use(router);
const dataSources = () => ({
// @ts-ignore
userAPI: new UserAPI({ store }),
});
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
dataSources,
context: ({ req, res }: any) => ({ req, res }),
});
await apolloServer.start();
apolloServer.applyMiddleware({ app, cors: false });
app.listen({ port: process.env.SERVER_PORT }, () => {
console.log(
`Server ready at http://localhost:${process.env.SERVER_PORT}${apolloServer.graphqlPath}`
);
});
};
main().catch((err) => {
console.error(err);
});
我的 UserApi 类包含登录方法的实现(为了简单起见),位于此处:
export class UserAPI extends DataSource {
private readonly store: DataSource;
private context: any;
constructor(store: { store: DataSource }) {
super();
// @ts-ignore
this.store = store;
}
initialize(config: { context: any }) {
// @ts-ignore
this.context = config.context;
console.log("Context from initialize: ", config.context);
}
async login(email: string, password: string): Promise<UserResult> {
//this User throws an error DataSource is not set for this entity.
const user = await User.findOne({ where: { email } });
...
}
}
在以前版本的 apollo 服务器中,我可以在没有数据源的情况下使用。 像这样:
解析器中的index.ts
...
const schema = makeExecutableSchema({ typeDefs, resolvers });
const apolloServer = new ApolloServer({
schema,
context: ({ req, res }: any) => ({ req, res }),
});
...
我定义了登录函数,它使用我的自定义UserRepo中的另一个函数。
...
login: async (
obj: any,
args: { email: string; password: string },
ctx: GqlContext,
info: any
): Promise<string> => {
let user: UserResult;
// login is from UserRepo.ts
user = await login(args.email, args.password);
},
...
UserRepo.ts
...
export const login = async (
email: string,
password: string
): Promise<UserResult> => {
const user = await User.findOne({ where: { email } });
// some code ...
};
...
一切正常。但对于新版本的 apollo 服务器,我不知道该怎么做。 我正在使用
"apollo-server-express": "^3.6.4",
"express": "^4.17.3",
"express-session": "^1.17.2",
"graphql": "^15.8.0",
"graphql-middleware": "^6.1.18",
"graphql-subscriptions": "^2.0.0",
"graphql-tools": "^8.2.1",
"ioredis": "^4.28.5",
"pg": "^8.7.3",
"typeorm": "^0.3.1",
"typescript": "^4.6.2",
我可以通过这种方式从数据库获取我的用户
const userRepository = getRepository(User);
let b = await userRepository.findOne({ where: { email } });
但是如果我想更改用户的话又会这样。假设我想为保存登录功能提供新的登录日期,
user.lastModifiedOn = new Date("new date");
await user.save();
但我得到了相同的错误。
I have an apollo-express-server with redis cache.
This is the index.ts:
const main = async () => {
const app = express();
app.use(
cors({
credentials: true,
origin: process.env.CLIENT_URL,
})
);
const router = express.Router();
const store = await createConnection();
const redis = new Redis({
port: Number(process.env.REDIS_PORT),
host: process.env.REDIS_HOST,
//password: process.env.REDIS_PASSWORD,
});
const RedisStore = connectRedis(session);
const redisStore = new RedisStore({
client: redis,
});
app.use(bodyParser.json());
app.use(
session({
store: redisStore,
name: process.env.COOKIE_NAME,
sameSite: "Strict",
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: false,
maxAge: 1000 * 60 * 60 * 24,
},
} as any)
);
app.use(router);
const dataSources = () => ({
// @ts-ignore
userAPI: new UserAPI({ store }),
});
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
dataSources,
context: ({ req, res }: any) => ({ req, res }),
});
await apolloServer.start();
apolloServer.applyMiddleware({ app, cors: false });
app.listen({ port: process.env.SERVER_PORT }, () => {
console.log(
`Server ready at http://localhost:${process.env.SERVER_PORT}${apolloServer.graphqlPath}`
);
});
};
main().catch((err) => {
console.error(err);
});
my UserApi class that contains implementations of a login method(for simplicity) is here:
export class UserAPI extends DataSource {
private readonly store: DataSource;
private context: any;
constructor(store: { store: DataSource }) {
super();
// @ts-ignore
this.store = store;
}
initialize(config: { context: any }) {
// @ts-ignore
this.context = config.context;
console.log("Context from initialize: ", config.context);
}
async login(email: string, password: string): Promise<UserResult> {
//this User throws an error DataSource is not set for this entity.
const user = await User.findOne({ where: { email } });
...
}
}
In previous versions of the apollo server I could use without the dataSource.
Like this:
index.ts
...
const schema = makeExecutableSchema({ typeDefs, resolvers });
const apolloServer = new ApolloServer({
schema,
context: ({ req, res }: any) => ({ req, res }),
});
...
in resolvers I have defined the login function which uses another function from My custom UserRepo.
...
login: async (
obj: any,
args: { email: string; password: string },
ctx: GqlContext,
info: any
): Promise<string> => {
let user: UserResult;
// login is from UserRepo.ts
user = await login(args.email, args.password);
},
...
UserRepo.ts
...
export const login = async (
email: string,
password: string
): Promise<UserResult> => {
const user = await User.findOne({ where: { email } });
// some code ...
};
...
And everything is working. But with the new version of the apollo server I can't figure out how to do it.
I am using
"apollo-server-express": "^3.6.4",
"express": "^4.17.3",
"express-session": "^1.17.2",
"graphql": "^15.8.0",
"graphql-middleware": "^6.1.18",
"graphql-subscriptions": "^2.0.0",
"graphql-tools": "^8.2.1",
"ioredis": "^4.28.5",
"pg": "^8.7.3",
"typeorm": "^0.3.1",
"typescript": "^4.6.2",
I can get my user from db in this way
const userRepository = getRepository(User);
let b = await userRepository.findOne({ where: { email } });
But then again if I want to change the user. Let's say I want to give e new date for loging in the save login function
user.lastModifiedOn = new Date("new date");
await user.save();
I get the same error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将 tsconfig.json 中的
"target"
更改为"es6"
:Change
"target"
in you tsconfig.json to"es6"
: