后端开发通常需要编写多行代码来处理 CRUD、授权和业务逻辑。所有这些代码都需要在项目的整个生命周期内进行测试、调试和维护。这需要开发人员可以用来开发新功能的大量时间。在本文中,您将了解 Hasura 和 PostgreSQL 如何帮助您加快应用程序开发并以最少的工作快速启动后端。
Hasura是一个开源 GraphQL 引擎,它使用您的数据库模式生成的 GraphQL 和 REST API 端点。它支持数据建模、实时查询、事件编程、基于角色的授权以及通过 GraphQL 运行自定义业务逻辑的操作。
PostgreSQL是一种流行且功能强大的开源、面向对象的关系数据库,它提供与 Oracle 数据库和 Microsoft SQL Server 类似级别的企业级功能。据StackShare 称,PostgreSQL 被 Netflix、Instagram、Uber 和 Spotify 等大型国际公司使用。
在本文中,我们将介绍 Hasura 提供的主要功能,这些功能使其适用于开发和启动 Web 和移动应用程序的可扩展后端。我们还将了解如何利用 PostgreSQL 的功能来执行各种计算和分析任务,只使用 SQL 将正确的数据传递到您的前端,而无需编写自定义代码。
请注意,Hasura 也支持其他数据库,例如 Microsoft SQL Server、Amazon Aurora 和 Google BigQuery。我们将专注于 PostgreSQL,因为它对大多数企业和组织都是免费且可访问的。对MySQL的支持即将推出,如果您有兴趣。
如果您是 GraphQL 新手,请查看我们的教程以了解更多信息。让我们从为什么 PostgreSQL 可以从成为您项目的完美选择开始。
为什么选择 PostgreSQL
与其他类型的数据库相比,关系数据库具有许多明显的优势,因为您可以使用严格的模式和表关系对数据进行建模。执行 JOIN 和执行 ACID 事务的能力是大多数行业中许多应用程序的主要要求。这些功能对于在任何给定时间促进业务数据的完整性和一致性至关重要。
与 MySQL 等其他关系型数据库相比,PostgreSQL 还具有以下优势:
- 您可以使用表继承对数据进行建模
- 对多用户环境有更好的并发控制(可以更高效地写入海量数据)
- 它具有容错性,不易损坏数据
- 它支持许多独特的数据类型,例如JSON和Spatial,这对于金融和研究相关的应用程序很有用
PostgreSQL 不仅仅是一个数据存储服务。它也是一个能够运行自定义函数和触发器以执行各种计算和分析任务的服务器。在 PostgreSQL 上线运行逻辑更有效,因为它不需要编写自定义服务器代码。您可以使用以下方法在 PostgreSQL 中定义逻辑:
- 视图,一种可以帮助简化复杂查询的存储查询
- 函数和运算符,例如日期格式化、模式匹配、算术运算
- Extensions,扩展 PostgreSQL 功能的插件(例如PostGIS)
- Procedural Languages,用于编写用户定义函数、存储过程、触发器和扩展标准 SQL 的编程语言(例如PL/pgSQL)
当您在 PostgreSQL 中实现逻辑时,Hasura 能够通过 GraphQL 查询和突变将它们公开给前端应用程序。这是通过pgAdmin界面看到的 PostgreSQL 服务器的顶级视图:
学习利用 PostgreSQL 功能可以帮助您轻松解决复杂问题,而无需编写服务器代码。以下是您可以使用的 PostgreSQL 执行哪些操作的几个示例:
例 1
您可以使用视图检索当前处于活动状态的在线用户列表:
CREATE OR REPLACE VIEW "public"."online_users" AS
SELECT users.id,
users.last_seen
FROM users
WHERE (users.last_seen >= (now() - '00:00:30'::interval));
例 2
使用PostGIS 功能,您可以列出位于 1,000 米半径内的所有商店。有关详细说明,请参阅此地理定位教程:
SELECT id, name, address, geom
FROM Seattle_Starbucks
WHERE ST_DWithin(geom, ST_MakePoint(-122.325959,47.625138)::geography, 1000);
在下一节中,我们将重点介绍 Hasura 的功能。
什么是哈苏拉?
Hasura 是一个开源的实时 GraphQL 引擎,可为您的数据库生成 GraphQL 和 REST API 端点。它带有一个 Web 控制台,可以让您:
- 为您的数据库模式建模
- 查看、插入、更新和删除数据
- 实施基于角色的访问控制策略
- 运行 GraphQL 查询和突变
- 创建 REST 端点
- 运行 SQL 代码
- 定义动作和触发器
Hasura 不支持用户身份验证,因此您需要将 Hasura 和您的前端应用程序提供程序集成,例如:
- 文员
- 授权0
- AuthGuardian
- 火力基地
- 魔法
也没有文件存储服务,您需要将您的应用程序与第三方存储提供商集成。如果您希望使用 Hasura 获得更多开箱即用的集成体验,您可以查看NHost,我们将在稍后的部署部分讨论。
在下一节中,我们将了解如何在本地和云中运行 Hasura。
启动 Hasura
有几种方法可以快速启动和运行 Hasura 实例:
1. 码头工人
推荐使用 Docker 在本地机器上运行 Hasura 来设置开发环境。使用此设置,API 请求没有速率限制,并且当您与 Hasura 的 Web 控制台交互时,没有 Internet 连接限制您的体验。您在本地执行的任何工作都可以轻松迁移到登台和生产环境。我们将在后面的“迁移和环境”部分讨论如何完成此操作。
假设您已经在您的机器上安装了Docker和Docker Compose,您可以按照本指南提供的说明在您的机器上运行 Hasura:
# create new directory
mkdir my-hasura
cd my-hasura
# download docker-compose.yml
curl https://raw.githubusercontent.com/hasura/graphql-engine/stable/install-manifests/docker-compose/docker-compose.yaml -o docker-compose.yml
# start hasura and postgresql container instances
docker-compose up -d
您可以通过执行命令确认您的 Hasura 和 PostgreSQL 容器实例正在运行docker ps。您应该可以通过浏览器访问您的本地 Hasura 实例
http://localhost:8080/console。要完成设置,您需要连接到 PostgreSQL 数据库,该数据库与 Hasura 一起作为容器运行。
连接数据库后,您将能够使用 Web 控制台创建表、定义关系并对数据执行 CRUD 操作。请注意,使用默认 Docker 设置时,您的数据是公开的。您可以通过简单地取消注释文件中以开头的行
HASURA_GRAPHQL_ADMIN_SECRET并docker-compose.yml重新启动 Hasura 容器来保护它。
2. 云
一个更简单的入门方法是通过Hasura Cloud。这是开源 Hasura 的重新设计版本,专为可扩展性、可用性、安全性
和全球分发而设计。
Hasura Cloud 带有几个开源版本中没有的新功能,包括:
- 监控仪表板的错误、连接、订阅、慢查询和其他操作
- GraphQL 缓存可提高服务器和客户端数据获取性能
- 防止恶意用户和 DDoS 攻击损害您的 API 的速率限制
- 运行测试套件的回归测试,例如根据生产实例检查开发实例中的更改
要开始使用 Hasura Cloud,您需要注册一个免费帐户。请注意,免费帐户的速率限制为每分钟 60 个请求。创建帐户后,您需要:
- 创建一个项目(Hasura 实例)
- 连接到 PostgreSQL 数据库
为方便起见,Hasura Cloud 提供一键式安装和连接到免费的 Heroku Cloud 数据库实例。您还可以连接到可通过 Internet 访问的任何其他 PostgreSQL 数据库。您可以使用许多 PostgreSQL 提供程序。其中包括云服务,例如:
- AWS
- 天蓝色
- 数字海洋
- TimescaleDB 云
- 裕嘉数据库
如果您需要更清楚地了解上述步骤,可以按照本指南进行操作。默认情况下,Hasura Cloud 使用管理员密钥限制来自公众的数据访问。我们将在接下来的部分中对此进行更多讨论。
哈苏拉特点
在本节中,我将简要概述 Hasura 提供的无需编写代码即可构建自定义后端的功能。
数据管理器
Hasura 带有一个可视化设计器,用于对数据层进行建模。这使您可以:
- 创建表
- 定义关系(一对一、一对多、多对多)
- 执行 CRUD 操作
- 创建视图
- 运行任何 SQL 语句
- 使用 PostgreSQL 的 DDL 约束实现数据验证
- 定义触发器
在列方面,Hasura 支持一组丰富的数据类型,其中包括:
- 整数、数字和浮点数
- 序列号和 UUID
- 字符和文本
- 日期和时间
- 布尔值
- 几何——例如线、框、路径、多边形和圆
- JSON
您还可以使用CREATE TYPESQL 命令添加自定义类型。接下来,我们将看看 Hasura 中数据是如何被授权的。
授权
Hasura 中的访问控制是基于角色的。默认情况下,有一个名为admin对您的数据具有完全 CRUD 访问权限的角色。要限制对其他用户的访问,您需要创建其他角色,例如user、public或accountant。
对于您创建的每个角色,您需要为以下操作定义访问策略:
- 插入
- 选择
- 更新
- 删除
您可以定义三种类型的策略:
- 完全访问,没有限制
- 部分访问,带有基于条件的限制
- 无法访问
以下示例演示了角色的select授权策略。user设置下面定义的规则是为了确保 auser只能查询自己的记录或标记为公共的记录:
查询
设计架构和定义权限后,您可以直接在 Hasura 的 API 仪表板中测试 GraphQL 查询。只要启用了跟踪,就可以查询您定义的每个表、视图和关系。
您可以执行的查询类型包括:
- 简单查询:返回一个或多个对象的 SELECT 查询。
- 嵌套查询:基于外键关系以嵌套格式返回对象的 JOIN 查询。
- 聚合查询:SELECT 查询,其中对结果执行了算术运算,例如求和或平均。它也可以应用于嵌套对象。
- 过滤/搜索查询:在一个或多个字段上使用比较运算符过滤数据的 WHERE 查询。它们还可用于使用模式或模糊匹配执行搜索。
GraphQL 查询结果可以排序、分组和分页。还支持基于光标的分页。 基本上,任何可以在 PostgreSQL 上运行的 SQL 语句都可以通过 GraphQL 查询公开。在下一节中,我们将研究突变。
突变
GraphQL 突变是用于修改数据的语句。以下是您可以执行的突变类型:
- 插入:创建一行或多行数据: mutation insert_single_article {insert_article_one( object: { title: "Article 1" content: "Sample article content" author_id: 3 } ) { id title } }
- Upsert:创建,更新冲突。在下面的示例中,该列value具有唯一约束:mutation upsert_single_tag { insert_tags( objects: { value: "Java" }on_conflict: { constraint: tags_value_key, update_columns: value } ) {returning { id value } } }
- 更新:更新一行或多行数据。还有用于处理数据类型int的特殊运算符。jsonb下面的示例更新所有评分小于或等于2 的文章。突变将返回受影响的行数,并将这些行列为对象数组: mutation update_article { update_article( where:{ rating: { _lte: 2 } } _set: { rating: 1, is_published: false } ) { affected_rows returning { id title content rating is_published } } }
- 删除:删除一行或多行数据。以下示例按主键删除文章: mutation delete_an_object { delete_article_by_pk(id: 1) { id title user_id } }
- 交易:在一个突变块中执行多个突变。如果其中一个失败,则该块中所有先前执行的突变都将回滚。以下示例首先删除属于某个作者的所有文章。在第二个突变中,作者的名字被更新: mutation reset_author {delete_article(where: { author_id: { _eq: 6 } }) { affected_rows }update_author(where: { id: { _eq: 6 } }, _set: { name: "Cory" }) { returning { id name articles { id title } } } }
订阅
Hasura 的订阅是通过WebSocket 协议执行的实时查询。这是一种用于从数据库中获取实时数据的协议。任何 GraphQL 查询都可以通过简单地将关键字替换为订阅。默认情况下,此类查询每秒运行一次 SQL 语句。这是一个可配置的设置,可以对其进行调整以在数据库负载和延迟之间提供适当的平衡。如果基础数据发生变化,则将新值推送到客户端。querysubscription
以下示例演示了跟踪车辆位置的 GraphQL 订阅:
# $vehicleId = 3
subscription getLocation($vehicleId: Int!) {
vehicle(where: { id: { _eq: $vehicleId } }) {
id
vehicle_number
locations(order_by: { timestamp: desc }, limit: 1) {
location
timestamp
}
}
}
使用订阅的其他用例包括:
- 送餐跟踪
- 聊天消息
- 在线民意调查
远程模式
通常在构建现代应用程序时,您需要与第三方 API 集成:
- 提供不在您的数据库中的数据,例如体育赛事比分或股票价格
- 提供业务逻辑——例如支付处理或预订航班
这些第三方 API 通常直接从客户端应用程序访问。使用 Hasura,您可以将这些 API 与您的数据库合并以创建统一的 GraphQL API。这创造了新的机会,您可以在其中实现授权并定义表/视图与远程 API 之间的远程关系。 您还可以创建基于此类关系执行特定任务的操作。
拥有统一的 GraphQL API 可以让前端开发人员更轻松地构建应用程序。在下一节中,我们将了解 Hasura Actions 是什么。
行动
Hasura 中的自定义业务逻辑通过 webhook 在微服务或无服务器功能上进行外部处理。这意味着您可以使用您喜欢的任何语言编写自定义逻辑,例如 Node.js、Python、Go 或 Ruby on Rails。Hasura 中的 Action 只是一个自定义 GraphQL 查询或突变,它映射到定义输入和输出接口的 webhook。
动作定义由以下部分组成:
- 类型:查询或突变
- 动作名称
- 输入和输出的自定义类型
- 标题
- 处理程序 URL
让我们看一个简单的“Hello, World!” 例子。首先,我们定义一个 Action 查询如下:
type Query {
hello(name: String!): HelloResponse
}
上面的 Action 定义了一个名为的函数,该函数hello接受一个称为name输入的字符串变量。该函数返回一个HelloResponse对象,它是一个自定义类型,定义如下:
type HelloResponse {
message: String!
}
定义好接口后,剩下的就是实现 webhook 服务和 Hasura 实例可访问的 URL。这是在 Hasura 的 CodeGen 助手的帮助下为 Express.js 编写的实现:
// Request Handler
app.post("/hello", async (req, res) => {
// get request input
const { name } = req.body.input;
// success
return res.json({
message: `Hello, ${name}!`,
});
});
事件触发器
在 Hasura 中,您可以使用称为事件驱动编程的软件架构来构建应用程序。这是一种设计模式,将复杂的状态管理与单一后端分离,并将其交给执行业务逻辑的单个微服务或无服务器功能。这允许构建高度健壮和可扩展的应用程序。
通过事件编程,您可以轻松处理许多用例,例如:
- 发送电子邮件
- 发送推送通知
- 将新数据发送到您的Algolia 搜索索引
在 PostgreSQL 中,您可以创建触发器,以在诸如INSERT、UPDATE或等事件DELETE发生时执行 SQL 语句或存储过程。触发器与表或视图相关联,可以在事件之前或之后触发。
在 Hasura 中,事件触发器的定义类似,用于在触发事件时调用web 挂钩。这个上下文中的 web hook 与我们刚刚在“操作”部分讨论的非常相似。事件触发器也可以通过控制台或 API 手动调用。
以下是 YAML 格式的事件触发器定义示例:
- table:
schema: public
name: author
event_triggers:
- name: author_trigger
definition:
enable_manual: false
insert:
columns: "*"
update:
columns: "*"
webhook: https://httpbin.org/post
事件触发器可以使用标头定义(用于身份验证),并且通常包含发送到 webhook 服务以进行数据处理的有效负载。唯一期望的响应是200状态。如果需要,实际结果会通过不同的路径发回——例如发布 GraphQL 突变,或发送电子邮件通知等。
前端应用可以通过 GraphQL 订阅进行查询来接收结果。这种架构可以轻松构建具有出色用户体验的非阻塞交互式实时应用程序。代码库也更容易为开发人员维护、测试和扩展。
预定触发器
计划触发器是基于时间的事件,通过 webhook 执行自定义业务逻辑。您可以定义两种类型:
- CRON 触发器:用于定期发生的周期性事件
- 一次性预定事件:用于一次性执行
可以通过 Web 控制台或元数据 API 创建计划的触发器。下面的屏幕截图显示了 Web 控制台示例。
元数据 API 允许使用应用程序代码创建计划事件。下面的示例显示了如何使用 API 构建一次性事件的创建:
{
"type": "create_scheduled_event",
"args": {
"webhook": "https://my-awesome-serverless-fn.com/send-email",
"schedule_at": "2022-07-20T12:45:00Z",
"payload": {
"email": "bob@ross.com"
}
}
}
Hasura 提供了许多容错机制来确保计划的触发器成功运行。例如,假设计划在下午 2:00 进行的事件未处理,因为 Hasura 在下午 1:59 关闭。当 Hasura 重新上线时,它将根据可自定义的容差配置重新处理事件并重新运行错过的预定触发器。默认设置为六小时。
Hasura 还提供了灵活的重试配置,以防 HTTP 失败。您可以配置重试次数和每次重试之间的超时时间。每次触发调用都会被记录——您可以稍后访问以进行检查。
预定触发器的用例包括:
- 发送提醒
- 生成日终报告
- 删除过去 90 天内未验证其电子邮件地址的非活动用户
迁移和环境
任何软件项目的理想开发工作流程是为开发、登台和生产设置多个环境。此工作流程简化了测试并确保开发人员在部署其软件的新版本时不会意外删除或损坏生产数据。
为了将开发环境的状态转移到登台和生产,需要迁移文件。使用 Hasura,您将需要:
- 数据库/SQL 迁移文件
- Hasura 元数据
Hasura 元数据由配置文件的快照组成,这些文件跟踪:
- 关系
- 权限
- 触发器
- 行动
- GraphQL 架构
- 远程模式
您需要安装Hasura CLI才能创建这些迁移文件并将其应用到不同的 Hasura 实例。这些迁移文件可以在开发过程中随着模式的变化而进行版本控制和增量更新。
使用命令创建和应用 SQL 迁移文件hasura migrate,而使用命令处理元数据迁移文件hasura metadata。CLI 命令还使您能够:
- 回滚应用的迁移
- 创建种子数据迁移
- 重置迁移文件
- squash 迁移文件——也就是说,用一个主要更新替换小的增量更新
Hasura 有一个特殊的 Docker cli-migration 镜像,可以在服务器启动时自动应用迁移。此图像还包含Hasura CLI工具,可用于在您的工作流程中运行 CI/CD 脚本。
部署
将 Hasura 部署到生产环境的最简单方法是使用Hasura Cloud。这是推荐的选项,因为您可以获得开源版本中不可用的企业功能。 幸运的是,与大多数后端即服务提供商 (BaaS) 不同,Hasura 不会将您锁定在他们的平台上。您可以在以下平台中利用一键部署服务提供商:
- Heroku
- 数字海洋
- 使成为
- 天蓝色
您还可以在任何Kubernetes 平台上部署 Hasura,例如Google Cloud。AWS也受支持,但您必须通过许多步骤才能使其正常工作。外部托管确实为您提供了自由和更多的定价选择。但是,以上所有选项都要求您为以下各项设置附加服务:
- 验证
- 贮存
- 自定义业务逻辑
在下一节中,我们将简要介绍如何使用 NHost 来进一步简化 Hasura 后端应用程序的开发。
使用 NHost 部署
NHost 是一家开源 BaaS 提供商,旨在与Firebase等平台竞争。他们的后端堆栈包括:
- PostgreSQL 数据库
- Hasura GraphQL 引擎
- 身份验证服务
- MinIO , S3 兼容的对象存储服务
- 无服务器功能(目前处于测试阶段)
该平台带有一个名为的客户端库nhost-js-sdk,用于前端身份验证和文件管理。存储服务支持图片优化,免去了我们为图片集成其他服务的麻烦。
在撰写本文时,NHost 目前为其服务提供 14 天的试用期。免费层将很快推出。有一个名为Hasura Backend Plus的 Docker 版本,您可以在本地机器上部署它。
概括
总而言之,Hasura GraphQL 引擎和 PostgreSQL 数据库在为移动和 Web 应用程序构建后端的速度方面是相当革命性的,而无需编写代码行。大部分计算和分析逻辑可以由 PostgreSQL 处理,而其余的自定义业务逻辑可以使用微服务或无服务器功能来实现。
采用 Hasura 意味着您将能够更快地启动并构建高性能、安全、容错、可扩展且易于维护的产品。没有基础设施的麻烦也将降低您的运营成本,让您专注于前端开发和应用程序中面向用户的部分。
尽管 Hasura 不像Parse 平台等其他开源替代品那样功能丰富,但它支持版本控制和环境分级,这是 CI/CD 开发工作流的关键要求。因为它是开源的,所以您可以免受供应商锁定带来的风险。
如果本文对你有帮助,别忘记给我个3连问 ,点赞,转发,评论,,咱们下期见。
收藏 等于白嫖,点赞才是真情。
学习更多JAVA知识与技巧,关注与私信博主
免费学习领取JAVA 课件,源码,安装包等等