首页 > web前端 > js教程 > 如何使用 Encore.ts 和 React 构建实时仪表板

如何使用 Encore.ts 和 React 构建实时仪表板

Linda Hamilton
发布: 2025-01-08 07:40:41
原创
996 人浏览过

实时仪表板在各种应用程序中都非常有用,从跟踪网站分析到监控实时财务数据,甚至密切关注物联网设备。

?在本教程中,我们将向您展示如何使用 ReactEncore.ts 构建一个。您将学习创建一个可即时传输更新的动态仪表板,使您能够做出快速、明智的决策。

要了解我们将构建的内容,请在此处查看成品的 GIF 和源代码。让我们深入了解一下!

How to Build a Real-Time Dashboard with Encore.ts and React

先决条件

在我们开始之前,请确保您的计算机上安装了这些东西

  • Node.js(v18 或更高版本)
  • Npm(v10 或更高版本)

什么以及为什么安可

Encore.ts 是一个开源框架,可帮助您使用 TypeScript 构建后端,确保类型安全。它轻量且快速,因为它没有任何 NPM 依赖项。

在开发分布式后端系统时,往往很难在本地复制生产环境,导致开发者体验不佳。您最终可能会处理很多复杂性,只是为了让事情以合理的方式在本地运行,这需要时间来专注于构建实际的应用程序。 Encore.ts 通过提供用于构建分布式系统的完整工具集来解决这个问题,包括:

  • 本地环境与云匹配
  • 跨服务类型安全
  • 类型感知基础设施
  • 自动 API 文档和客户端
  • 本地测试追踪
  • 还有更多

好的,我们讨论了 Encore 是什么以及它如何帮助我们构建后端服务。在下一节中,我们将在本地安装 Encore 并开始构建。

安装安可

要使用 Encore,我们需要安装 CLI,这使得创建和管理本地环境变得非常容易。

# macOS
brew install encoredev/tap/encore

# Windows
iwr https://encore.dev/install.ps1 | iex

# Linux
curl -L https://encore.dev/install.sh | bash
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

创建 Encore 应用程序

创建 Encore 应用程序非常简单,只需运行命令即可。

encore app create
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

您将被问到以下问题,因此请相应地选择您的答案。

Select language for your applicatio : TypeScript
Template: Empty app
App Name : real-time-dashboard
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

应用程序创建后,您可以在 encore.app 中验证应用程序配置

{
    "id":   "real-time-dashboard-<random-id>",
    "lang": "typescript"
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

好的,我们已经创建了 Encore 应用程序。我们下一节讨论 Encore 中的 Streaming API。

什么是Encore 中的流式 API

在讨论流式 API 之前,我们先讨论一下 Encore 中的 API。在 Encore 中创建 API 端点非常容易,因为它提供了 encore.dev/api 模块中的 api 函数来定义类型安全的 API 端点。 Encore 还内置了对传入请求的验证。 API 的核心是具有请求和响应架构结构的简单异步函数。 Encore 会在编译时解析代码并生成样板,因此您只需专注于定义 API。

流 API 是允许您向应用程序发送数据和从应用程序接收数据的 API,从而允许双向通信。

Encore 提供三种类型的流,每种流用于不同的数据流方向:

  • StreamIn:使用它将数据流式传输到您的服务中。
  • StreamOut:使用它从您的服务中流式传输数据。
  • StreamInOut:使用它可以将数据流入和流出您的服务。

当您连接到流式 API 端点时,客户端和服务器使用 HTTP 请求执行握手。如果服务器接受此请求,则会为客户端和 API 处理程序创建一个流。这个流实际上是一个允许发送和接收消息的 WebSocket。

好吧,现在我们知道了 Encore 中的 API 和 Streaming API,让我们在下一节中使用 Streaming API 端点创建仪表板服务来实时存储和检索数据。

创建仪表板服务

让我们创建一个仪表板服务,我们将在其中定义销售 API 以将数据传入和传出我们的销售仪表板。

在根级别创建一个名为dashboard的文件夹,然后添加一个 encore.service.ts 文件。此文件将告诉 Encore 将仪表板文件夹及其子文件夹视为服务的一部分。

# macOS
brew install encoredev/tap/encore

# Windows
iwr https://encore.dev/install.ps1 | iex

# Linux
curl -L https://encore.dev/install.sh | bash
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

然后将以下代码添加到 encore.service.ts 文件中。我们从 encore.dev/service 导入 Service 类,并使用“dashboard”作为服务名称创建它的实例。

encore app create
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

现在让我们创建一个仪表板.ts 文件并设置销售 API。

Select language for your applicatio : TypeScript
Template: Empty app
App Name : real-time-dashboard
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

How to Build a Real-Time Dashboard with Encore.ts and React

在设置API之前,我们首先设置数据库来存储销售数据。我们将使用 encore.dev/storage/sqldb 模块中的 SQLDatabase 来创建 Encore 支持的 PostgreSQL 数据库。

我们需要将 SQL 定义为迁移,当我们执行命令 encore run 时,Encore 将拾取该迁移。

在仪表板文件夹中创建一个名为migrations的文件夹,然后创建一个名为1_first_migration.up.sql的文件。确保遵循命名约定,以 number_ 开头并以 up.sql 结尾。

# macOS
brew install encoredev/tap/encore

# Windows
iwr https://encore.dev/install.ps1 | iex

# Linux
curl -L https://encore.dev/install.sh | bash
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

在这里,我们创建一个名为 sales 的表,包含四列:

  • id:自增,为主键
  • 促销:促销标题
  • 总计:销售总额
  • 日期:销售日期

接下来,将以下代码添加到dashboard.ts 文件中。

encore app create
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

在这里,我们创建一个 SQLDatabase 实例,将其命名为仪表板并指定迁移文件夹的路径。

我们正在使用 postgres 包来监听并通知数据库中的更改。

接下来,添加这些类型和内存中的映射来保存连接的流(websocket 连接)。

Select language for your applicatio : TypeScript
Template: Empty app
App Name : real-time-dashboard
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

接下来,让我们设置一个销售流端点,以便在发生新销售时发送更新。

{
    "id":   "real-time-dashboard-<random-id>",
    "lang": "typescript"
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

这里我们使用 api.streamOut 函数来定义 API,它接受两个参数:

  • 流选项:
    • expose:设置为 true 以使端点公开,否则为 false
    • auth:设置为 true 以通过身份验证保护端点,否则为 false
    • 路径:/sale
  • 函数:需要两个参数
    • 握手:用于建立流连接
    • stream:流对象

我们在connectedStreams映射中保持连接,并使用Postgres客户端监听new_sale通道。当新的销售发生时,我们会将更新发送到所有连接的流。

接下来,我们将定义添加销售 API 端点,我们从请求正文中获取销售数据,并使用数据库实例插入新的销售记录。

# create dashboard folder
mkdir dashboard

# switch to dashboard folder
cd dashboard

# create encore.service.ts file inside dashboard folder
touch encore.service.ts
登录后复制
登录后复制
登录后复制
登录后复制

在这里,将新的销售记录添加到数据库后,我们使用 Postgres 客户端向 new_sale 通道发送包含销售数据的通知。这样,new_sale 通道侦听器就会收到通知并可以采取行动。

最后,让我们设置 API 端点以返回销售记录列表。

import { Service } from 'encore.dev/service';

export default new Service('dashboard');
登录后复制
登录后复制
登录后复制
登录后复制

这里,我们使用db实例方法查询来获取数据,然后处理它以列表的形式返回。

太好了,我们现在已经定义了所有 API 端点。让我们在下一节中探索 Encore 开发仪表板。

探索开发仪表板

我们有带有数据库设置的 API 端点,但是我们如何测试和调试服务呢?不用担心,因为 Encore 提供了本地开发仪表板,可以让开发人员的生活更轻松并提高生产力。

它包含多种功能来帮助您设计、开发和调试应用程序:

  • Service Catalog 和 API Explorer,可轻松对本地后端进行 API 调用
  • 分布式跟踪,实现简单而强大的调试
  • 用于分享知识和回答问题的自动 API 文档
  • Encore Flow 用于可视化您的微服务架构

当您更改应用程序时,所有这些功能都会实时更新。

要访问仪表板,请使用 encore run 启动 Encore 应用程序,它会自动打开。

# macOS
brew install encoredev/tap/encore

# Windows
iwr https://encore.dev/install.ps1 | iex

# Linux
curl -L https://encore.dev/install.sh | bash
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

这就是仪表板的外观,您可以在投入生产之前在本地测试所有内容。这使得测试微服务架构变得更加容易,而无需外部工具。

How to Build a Real-Time Dashboard with Encore.ts and React

以下是使用 API 浏览器添加新销售的示例。当您单击“调用 API”按钮时,您将收到响应和日志。右侧可以看到请求的痕迹。

How to Build a Real-Time Dashboard with Encore.ts and React

单击跟踪链接时,您将获得数据库查询、响应和日志等详细信息。

How to Build a Real-Time Dashboard with Encore.ts and React

好了,这就是本地开发仪表板的全部内容。您可以探索其他选项,例如服务目录、流程等。在下一节中,我们将生成具有 TypeScript 类型安全性的客户端,以在前端服务(React 应用程序)中使用,以与仪表板服务 API 进行通信。

生成客户端

Encore 可以使用 TypeScript 或 JavaScript 生成前端请求客户端,保持请求/响应类型同步并帮助您无需手动操作即可调用 API。

在根目录下创建一个名为 frontend 的文件夹,然后运行以下命令使用 Vite 设置 React 项目。

encore app create
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

接下来,在 src 目录中创建一个 lib 文件夹,添加一个名为 client.ts 的新文件,并将其留空。

Select language for your applicatio : TypeScript
Template: Empty app
App Name : real-time-dashboard
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

然后,在 package.json 文件中添加一个名为 gen-client 的新脚本。

{
    "id":   "real-time-dashboard-<random-id>",
    "lang": "typescript"
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

接下来,运行脚本在 src/lib/client.ts 中创建客户端。

# create dashboard folder
mkdir dashboard

# switch to dashboard folder
cd dashboard

# create encore.service.ts file inside dashboard folder
touch encore.service.ts
登录后复制
登录后复制
登录后复制
登录后复制

src/lib/client.ts 文件应包含生成的代码。

import { Service } from 'encore.dev/service';

export default new Service('dashboard');
登录后复制
登录后复制
登录后复制
登录后复制

接下来,在lib目录中创建一个名为getRequestClient.ts的文件并添加以下代码。这将根据环境返回 Client 实例。

# make sure you are in dashboard folder
touch dashboard.ts
登录后复制
登录后复制
登录后复制

好了,现在我们有了可以在 React 应用程序中使用的客户端来调用仪表板 API。在下一节中,我们将创建前端服务并为实时销售仪表板构建 UI。

创建前端服务

在上一节中,我们使用 React 应用程序设置了一个前端文件夹,现在我们希望将其设为服务。让我们创建一个 encore.service.ts 文件并添加以下代码来告诉 Encore 将前端文件夹视为“前端”服务。

# macOS
brew install encoredev/tap/encore

# Windows
iwr https://encore.dev/install.ps1 | iex

# Linux
curl -L https://encore.dev/install.sh | bash
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

我们有两个选择:

  • 分别提供仪表板和前端服务
  • 将所有内容作为一个捆绑包提供(我们将在本教程中使用这种方法)

为了服务 React 应用程序,我们需要在 Encore 中将其构建并作为静态资产提供。让我们在前端文件夹中设置 static.ts 文件。

在 Encore.ts 中提供静态文件与常规 API 端点类似,但我们使用 api.static 函数代替。

encore app create
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

这里有两件重要的事情需要注意:我们正在传递路径和目录选项。

  • path: /!path 确保它充当后备路由并且不会与其他端点冲突。
  • dir:./dist 是 React 应用程序的构建版本的目录。

太好了,静态端点已设置。现在,让我们为 React 应用程序安装一些依赖项

  • 反应路由器-dom
  • uuid
  • 顺风CSS
Select language for your applicatio : TypeScript
Template: Empty app
App Name : real-time-dashboard
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

然后使用以下代码更新 main.tsx。

{
    "id":   "real-time-dashboard-<random-id>",
    "lang": "typescript"
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

接下来,让我们设置 Tailwind CSS 并更新一些文件。

# create dashboard folder
mkdir dashboard

# switch to dashboard folder
cd dashboard

# create encore.service.ts file inside dashboard folder
touch encore.service.ts
登录后复制
登录后复制
登录后复制
登录后复制

更改 tailwind.config.js 中的内容部分

import { Service } from 'encore.dev/service';

export default new Service('dashboard');
登录后复制
登录后复制
登录后复制
登录后复制

和带有以下代码的index.css。

# make sure you are in dashboard folder
touch dashboard.ts
登录后复制
登录后复制
登录后复制

现在让我们为销售仪表板创建一些组件。

  • SalesTable:以表格形式显示销售数据。
# 1_first_migration.up.sql

CREATE TABLE sales (
    id BIGSERIAL PRIMARY KEY,
    sale VARCHAR(255) NOT NULL,
    total INTEGER NOT NULL,
    date DATE NOT NULL
);

登录后复制
登录后复制

这里,我们从生成的客户端导入类型,以匹配仪表板服务类型并确保类型安全。

  • SalesMetrics:显示一些销售数字,例如总销售额、最低销售额和平均销售额。
# dashboard.ts

import { SQLDatabase } from 'encore.dev/storage/sqldb';
import postgres from 'postgres';

const db = new SQLDatabase('dashboard', {
  migrations: './migrations',
});

const client = postgres(db.connectionString);
登录后复制
登录后复制
  • RoleSelector:为了让用户为仪表板选择角色,我们将显示两个选项:
    • 查看者:可以查看销售仪表板
    • 经理:可以查看和创建新的销售
# dashboard.ts

...

// Map to hold all connected streams
const connectedStreams: Map<string, StreamOut<Sale>> = new Map();

interface HandshakeRequest {
  id: string;
}

interface Sale {
  sale: string;
  total: number;
  date: string;
}

interface ListResponse {
  sales: Sale[];
}

登录后复制
  • GenerateSales:显示生成销售按钮并包含生成销售的逻辑。

为了产生销售额,我们需要一些模拟数据,所以让我们创建一个 src/constant.ts 文件并添加模拟数据

# dashboard.ts
...

import { api, StreamOut } from 'encore.dev/api';
import log from 'encore.dev/log';

...

export const sale = api.streamOut<HandshakeRequest, Sale>(
  { expose: true, auth: false, path: '/sale' },
  async (handshake, stream) => {
    connectedStreams.set(handshake.id, stream);

    try {
      await client.listen('new_sale', async function (data) {
        const payload: Sale = JSON.parse(data ?? '');

        for (const [key, val] of connectedStreams) {
          try {
            // Send the users message to all connected clients.
            await val.send({ ...payload });
          } catch (err) {
            // If there is an error sending the message, remove the client from the map.
            connectedStreams.delete(key);
            log.error('error sending', err);
          }
        }
      });
    } catch (err) {
      // If there is an error reading from the stream, remove the client from the map.
      connectedStreams.delete(handshake.id);
      log.error('stream error', err);
    }
  }
);
登录后复制
# dashboard.ts
...
...

export const addSale = api(
  { expose: true, method: 'POST', path: '/sale/add' },
  async (body: Sale & { id: string }): Promise<void> => {
    await db.exec`
      INSERT INTO sales (sale, total, date)
      VALUES (${body.sale}, ${body.total}, ${body.date})`;

    await client.notify(
      'new_sale',
      JSON.stringify({ sale: body.sale, total: body.total, date: body.date })
    );
  }
);

登录后复制

在这里,我们导入 getRequestClient,然后从仪表板服务调用 addSale 端点。它非常简单,并且 addSale 是类型安全的,因此如果您尝试传递任何不允许的属性,您将收到错误。

接下来,让我们创建一个 SalesDashboard 组件来显示包含销售指标、近期销售和历史销售的仪表板视图。

# macOS
brew install encoredev/tap/encore

# Windows
iwr https://encore.dev/install.ps1 | iex

# Linux
curl -L https://encore.dev/install.sh | bash
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

SalesDashboard 采用一个名为 role 的道具,它决定是否显示GenerateSales 组件。

saleStream 将保存活动流引用并且是强类型的。

encore app create
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

安装组件时,我们使用仪表板服务的销售端点创建流连接。然后,我们监听套接字打开和关闭事件,并根据这些事件运行适当的逻辑。

我们从 saleStream.current 中读取销售数据并将其存储在centreSalesData 状态中。

当组件卸载时,我们清理并关闭当前流。

Select language for your applicatio : TypeScript
Template: Empty app
App Name : real-time-dashboard
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

此代码使用仪表板服务中的 listSales 端点获取存储的销售额,并将其保存在 salesData 状态中。

{
    "id":   "real-time-dashboard-<random-id>",
    "lang": "typescript"
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

此代码计算近期销量和历史销量数据。

# create dashboard folder
mkdir dashboard

# switch to dashboard folder
cd dashboard

# create encore.service.ts file inside dashboard folder
touch encore.service.ts
登录后复制
登录后复制
登录后复制
登录后复制

最后,使用此代码更新 App.tsx 文件。

import { Service } from 'encore.dev/service';

export default new Service('dashboard');
登录后复制
登录后复制
登录后复制
登录后复制

这里,我们根据角色查询参数是否可用来显示 SalesDashboard 和 RoleSelector 组件。

现在,让我们通过在前端根目录中运行以下命令来构建 React 应用程序。

# make sure you are in dashboard folder
touch dashboard.ts
登录后复制
登录后复制
登录后复制

成功运行命令后,将在前端目录中创建 dist 文件夹。

太好了,现在在下一部分中,让我们运行应用程序并从头到尾对其进行测试。

运行应用程序

运行 encore 应用程序很简单;只需使用下面的命令即可。

# 1_first_migration.up.sql

CREATE TABLE sales (
    id BIGSERIAL PRIMARY KEY,
    sale VARCHAR(255) NOT NULL,
    total INTEGER NOT NULL,
    date DATE NOT NULL
);

登录后复制
登录后复制

成功运行命令后,您将在终端中看到如下日志:

# dashboard.ts

import { SQLDatabase } from 'encore.dev/storage/sqldb';
import postgres from 'postgres';

const db = new SQLDatabase('dashboard', {
  migrations: './migrations',
});

const client = postgres(db.connectionString);
登录后复制
登录后复制

在浏览器中访问http://127.0.0.1:4000,您将看到如下屏幕。

How to Build a Real-Time Dashboard with Encore.ts and React

接下来,在一个选项卡中选择“查看器”,在另一个选项卡中选择“管理器”。

  • 观众

How to Build a Real-Time Dashboard with Encore.ts and React

  • 经理

How to Build a Real-Time Dashboard with Encore.ts and React

在检查开发仪表板时,我们创建了一条销售记录,并将其保存在数据库中,因此在 UI 中也可见。

现在,从经理视图中,单击“生成销售”按钮,并观看仪表板上的两个选项卡实时更新。

How to Build a Real-Time Dashboard with Encore.ts and React

概括

在本教程中,我们使用 React 和 Encore.ts 创建了一个实时销售仪表板。该应用程序会立即更新新的销售和库存商品,有助于快速决策。我们使用开源框架 Encore.ts 来使用 TypeScript 构建后端,以实现安全、流畅的编码。 Encore 的主要特点是:

  1. 类型安全:确保所有 API 端点和数据结构都是安全的,减少错误并使代码更可靠。
  2. Streaming API:允许通过 StreamIn、StreamOut 和 StreamInOut 进行实时数据流,从而实现客户端和服务器之间的双向通信。
  3. 本地开发仪表板:提供用于测试和调试的工具,例如服务目录、API Explorer 和分布式跟踪,从而提高生产力。
  4. 自动客户端生成:使用 TypeScript 或 JavaScript 创建前端请求客户端,保持请求/响应类型一致。
  5. 简化的微服务:让您可以构建具有多个服务的应用程序,而无需通常的复杂性,从而提供更简单的方法来处理微服务。

这些功能结合在一起,可以更轻松地构建和管理复杂的应用程序,从而提供出色的开发人员体验。

相关链接

  • GitHub 上的 Star Encore
  • 查找此示例的源代码
  • 加入我们的 Discord 社区

以上是如何使用 Encore.ts 和 React 构建实时仪表板的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板