如何使用 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"
    }
  }
}