为Apollo在线聊天Node.js创建一个后端应用程序

不久前,我正在开发一个移动应用程序,其功能包括便捷的在线聊天。 现在,我决定写一篇文章,其中简要说明了如何在后端使用apollo服务器和node.js创建聊天,以及如何在客户端响应本机和apollo客户端。

文章分为两部分,以方便阅读。 第一部分包含用于创建应用程序后端的指南,第二部分包含用于创建应用程序前端的指南。

如果您懒于阅读,则可以在此处此处立即在Github'e中查看代码。

作为实现的主要技术,我选择了node.js koa框架, postgresql数据库以及GraphQL服务器-apollo -server-koa

首先,生成了一个空的koa2项目,为此,我通过在终端中执行以下命令使用了一个简单的koa-generator

$ koa <project name> 

然后安装了必要的依赖关系,我使用yarn来完成,但是您可以使用npm。

 $ yarn add apollo-server-koa knex objection pg 

已安装所有必需的库,现在您可以编写代码


要连接到数据库,您需要描述两个文件,第一个是db.js,它将导出knex客户端实例并允许我们的模型处理来自数据库的数据,第二个是knexfile.js,其中包含用于创建和创建数据库的数据库连接设置。滚动迁移。

db.js代码如下所述,请注意,所有设置均取自环境变量:

 const db = require('knex')({ client: 'pg', connection: {   host : process.env.POSTGRES_HOST,   port: process.env.POSTGRES_PORT,   user : process.env.POSTGRES_USER,   password : process.env.POSTGRES_PASSWORD,   database : process.env.POSTGRES_DATABASE } }); module.exports = db; 

代码knexfile.js 在此处可用。

现在,您可以描述迁移以创建我们需要的两个表。


这些表本身将尽可能地简单,并且仅包含所需的最小字段集。 创建它们的命令如下:

 $ knex migrate:make migration_name 

您可以在此处查看迁移文件。

现在创建实体模型Message和User


 class Message extends Model { static get tableName() {   return 'messages'; } $beforeInsert() {   this.created_at = new Date().toISOString(); } static get relationMappings() {   return {     user: {       relation: Model.BelongsToOneRelation,       modelClass: User,       join: {         from: 'messages.user_id',         to: 'users.id'       }     }   }; } } 

最有趣的事情仍然存在-连接和配置apollo-server-koa,graphql方案和解析器的描述。

要连接apollo-server-koa,只需添加以下代码行


app.js:

 const { ApolloServer } = require('apollo-server-koa'); const graphqlSchema = require('./graphqlSchema'); … const apolloServer = new ApolloServer(graphqlSchema); apolloServer.applyMiddleware({ app }); 

网址:

 var { app, apolloServer } = require('../app'); ... apolloServer.installSubscriptionHandlers(server); 

除了连接apollo-server-koa外,我们还提供了与订阅一起使用的功能,以通知客户聊天中已收到新消息。

已连接Apollo-server-koa,下一步是对带有聊天所需类型的graphql图的描述


 input UserInput { username: String! } input MessageInput { text: String! user_id: ID! } type User { id: ID username: String } type Message { id: ID text: String created_at: String user: User } type Query { getLast100Messages: [Message] } type Mutation { findOrCreateUser(user: UserInput!): User createMessage(message: MessageInput!): Message } type Subscription { messageCreated: Message } 

电路已准备好,我们描述旋转变压器


用于发送新消息的解析器的示例:

 const Message = require('../../models/message'); const { pubsub, MESSAGE_CREATED } = require('../../utils'); module.exports = { createMessage: async (obj, { message }, context, info) => {   const createdMessage = await Message     .query()     .insert(message);   const resultMessage = await Message     .query()     .eager('user')     .findById(createdMessage.id);   pubsub.publish(MESSAGE_CREATED, { messageCreated: resultMessage });   return resultMessage; }, }; 

有趣的一点是,除了将消息保存在数据库中之外,这里还调用了publish()函数,该消息通知所有订阅者有关MESSAGE_CREATED事件,向他们发送新消息的对象(细心的阅读者会注意到发送者还将收到他的新消息的通知,我们将对此进行进一步处理。对于客户而言,在一个真实的项目中,有必要在后端进行处理,以免在不同客户之间重复逻辑。

其余解析器的代码可以在此处找到。

聊天的服务器端已准备就绪,如何验证一切正常?


在浏览器中打开主机 ,您将在其中看到graphql游乐场。

图片

在下一部分中,我们将创建一个移动应用程序。

Source: https://habr.com/ru/post/zh-CN470756/


All Articles