如何使用 OGM 结合订阅
Neo4j GraphQL 库可以与 OGM 结合使用,以扩展库的功能,或利用 @private
指令。
用法
本节介绍如何在自定义解析器中使用 OGM 结合订阅。
先决条件
使用以下类型定义
const typeDefs = `#graphql
type User {
email: String!
password: String! @private
}
`;
设置支持订阅的服务器。有关更多说明,请参阅 入门 页面。
添加 OGM
在 OGM 构造函数中启用订阅功能
const ogm = new OGM({
typeDefs,
driver,
features: {
subscriptions: true
},
});
创建 User
模型,它利用类型定义中 User
类型上标记为 @private
的字段。
const User = ogm.model("User");
在使用 OGM 实例之前对其进行初始化,方法是在 main()
函数中添加以下行
await ogm.init();
添加自定义解析器
自定义解析器可以用于多种原因,例如执行数据操作和检查,或与第三方系统交互。在本例中,您只需要创建一个 User
节点,并设置 password
字段。您可以通过添加注册突变来做到这一点
const resolvers = {
Mutation: {
signUp: async (_source, { username, password }) => {
const [existing] = await User.find({
where: {
username,
},
});
if (existing) {
throw new Error(`User with username ${username} already exists!`);
}
const { users } = await User.create({
input: [
{
username,
password,
},
],
});
return createJWT({ sub: users[0].id });
},
},
};
const typeDefs = `
type Mutation {
signUp(username: String!, password: String!): String!
}
`;
结论
总而言之,它应该如下所示
const driver = neo4j.driver(
"bolt://localhost:7687",
neo4j.auth.basic("neo4j", "password")
);
const typeDefs = `
type User {
email: String!
password: String! @private
}
type Mutation {
signUp(username: String!, password: String!): String! # custom resolver
}
`
const resolvers = {
Mutation: {
signUp: async (_source, { username, password }) => {
const [existing] = await User.find({
where: {
username,
},
});
if (existing) {
throw new Error(`User with username ${username} already exists!`);
}
const { users } = await User.create({
input: [
{
username,
password,
}
]
});
return createJWT({ sub: users[0].id });
},
},
};
const neoSchema = new Neo4jGraphQL({
typeDefs,
driver,
resolvers,
feature: {
subscriptions: true,
},
});
const ogm = new OGM({
typeDefs,
driver,
features: {
subscriptions: true
},
});
const User = ogm.model("User");
async function main() {
// initialize the OGM instance
await ogm.init();
// Apollo server setup with WebSockets
const app = express();
const httpServer = createServer(app);
const wsServer = new WebSocketServer({
server: httpServer,
path: "/graphql",
});
// Neo4j schema
const schema = await neoSchema.getSchema();
const serverCleanup = useServer(
{
schema,
context: (ctx) => {
return ctx;
},
},
wsServer
);
const server = new ApolloServer({
schema,
plugins: [
ApolloServerPluginDrainHttpServer({
httpServer,
}),
{
async serverWillStart() {
return Promise.resolve({
async drainServer() {
await serverCleanup.dispose();
},
});
},
},
],
});
await server.start();
app.use(
"/graphql",
cors(),
bodyParser.json(),
expressMiddleware(server, {
context: async ({ req }) => ({ req }),
})
);
const PORT = 4000;
httpServer.listen(PORT, () => {
console.log(`Server is now running on http://localhost:${PORT}/graphql`);
});
}
接收订阅事件
首先,运行以下订阅以接收 User
创建事件
subscription {
userCreated {
createdUser {
email
}
event
}
}
然后运行注册突变
mutation {
signUp(email: "jon.doe@xyz.com", password: "jondoe") {
email
password
}
}
结果应如下所示
{
"data": {
"userCreated": {
"createdUser": {
"email": "jon.doe@xyz.com",
"password": "jondoe"
},
"event": "CREATE"
}
}
}