所有文章 > 如何集成API > 使用 TypeScript、PostgreSQL 和 Prisma 构建后端:持续集成与部署

使用 TypeScript、PostgreSQL 和 Prisma 构建后端:持续集成与部署

在本系列的第四部分内容里,我们将借助GitHub Actions来配置持续集成(CI)与持续部署(CD),以此测试后端并将其部署至Heroku上。

介绍

该系列的目标是通过解决一个具体问题:在线课程的评分系统,探索和演示现代后端的不同模式、问题和架构。选择这个问题是因为它涉及多种关系类型,而且复杂度足够,能够很好地反映现实世界的应用场景。

上面提供了实时流的录制内容,其内容与本文相同。

该系列将涵盖哪些内容

该系列将重点关注数据库在后端开发各个方面的作用,包括:

话题部分
数据建模第 1 部分
增删改查第 1 部分
聚合第 1 部分
REST API 层第2部分
验证第2部分
测试第2部分
无密码认证第三部分
授权第三部分
与外部 API 集成第三部分
持续集成第 4 部分(当前)
部署第 4 部分(当前)

在第一篇文章中,您为问题域设计了一个数据模型,并编写了一个使用Prisma Client将数据保存到数据库的种子脚本。

在本系列的第二篇文章中,您基于第一篇文章所介绍的数据模型和Prisma架构,成功构建了一个REST API。您使用Hapi构建了 REST API,它允许通过 HTTP 请求对资源执行 CRUD 操作。

在本系列的第三篇文章中,您实现了基于电子邮件的无密码身份验证和授权,并使用JSON Web 令牌 (JWT)和 Hapi 来保护 REST API。此外,您还实现了基于资源的授权机制,以明确用户被允许执行的具体操作。

学到的内容

在本文中,您将通过定义运行测试并将后端部署到 Heroku(您将在其中托管后端和 PostgreSQL 数据库)的工作流程,将 GitHub Actions 设置为 CI/CD 服务器。

Heroku 是一个平台即服务(PaaS)提供商。与无服务器部署模型有所不同,在 Heroku 上,即使当前没有向您的应用程序发出请求,应用程序也会保持运行状态。虽然无服务器具有许多优势,例如更低的成本和更少的运营开销,但这种方法避免了无服务器方法常见的数据库连接扰动和冷启动的挑战。

注意:在整个指南中,您将找到各种检查点,使您能够验证是否正确执行了这些步骤。

先决条件

要将带有 GitHub Action 的后端部署到 Heroku,您将需要以下内容:

  • Heroku帐户。
  • Heroku CLI已安装。
  • 用于发送电子邮件的SendGrid API令牌,您在本系列的第 3 部分中创建了该令牌。

持续集成和持续部署

持续集成(CI)是一种技术手段,旨在将单个开发人员的工作成果整合到主代码库中,以便及时发现集成过程中可能出现的错误,并促进开发团队之间的协作与效率提升。通常,CI 服务器连接到 Git 存储库,每次将提交推送到存储库时,CI 服务器都会运行。

持续部署 (CD) 是一种涉及自动化部署过程的方法,以便可以快速、一致地部署更改。

尽管CI和CD各自承担着不同的职责,但它们之间是相互关联的,并且通常我们会利用相同的工具来执行这两个过程。在本文中,您将使用 GitHub Actions 来处理 CI 和 CD。

持续集成管道

通过持续集成,主要构建块是管道。管道是您定义的一组步骤,用于确保您的更改不会引入错误或回归。例如,管道可能包含运行测试、代码检查和 TypeScript 编译器的步骤。如果其中一个步骤失败,CI 服务器将停止并向 GitHub 报告失败的步骤。

在团队协作中,若采用拉取请求来引入代码更改,那么CI(持续集成)服务器通常会被设定为对每个拉取请求自动执行相应的管道流程。

您在前面的步骤中编写的测试通过模拟对 API 端点的请求来工作。由于这些端点的处理程序与数据库交互,因此在测试期间您将需要一个具有后端架构的 PostgreSQL 数据库。在接下来的步骤中,您需要配置GitHub Actions,以便在运行CI时能够启动测试数据库并执行迁移操作,从而确保测试数据库的结构与您的Prisma架构保持一致。

注意: CI 的好坏取决于您编写的测试。如果您的测试覆盖率较低,通过测试可能会产生错误的自信感。

使用 GitHub Actions 定义工作流程

GitHub Actions 是一个可用于持续集成的自动化平台。它提供了一个 API,用于根据 GitHub 中的事件编排工作流程,并可用于从 GitHub 构建、测试和部署代码。

要配置 GitHub Actions,您可以使用 yaml 定义工作流程。工作流可以配置为在不同的存储库事件上运行,例如,当提交被推送到存储库时或当创建拉取请求时。

每个工作流可以包含多个作业,而每个作业又由多个步骤所组成。在这些作业中,每一个步骤都代表着一个命令,并且这些命令能够访问到正在进行测试的特定提交所对应的源代码。

注意: CI 服务对管道使用不同的术语;例如,GitHub Actions 使用术语“工作流程”来指代同一事物。

在本文中,您将使用存储库中的grading-app工作流。

让我们看一下工作流程:

name: grading-app
on: push

jobs:
test:
runs-on: ubuntu-latest
# Service containers to run with `container-job`
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps TCP port 5432 on service container to the host
- 5432:5432
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/grading-app
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- run: npm ci
# run the migration in the test database
- run: npm run db:push
- run: npm run test
deploy:
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/master' # Only deploy master
needs: test
steps:
- uses: actions/checkout@v2
- run: npm ci
- name: Run production migration
run: npm run migrate:deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
- uses: akhileshns/heroku-deploy@v3.4.6
with:
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
heroku_app_name: ${{ secrets.HEROKU_APP_NAME }}
heroku_email: ${{ secrets.HEROKU_EMAIL }}

grading-app工作流有两个作业:testdeploy

测试作业将执行以下操作:

  1. 查看存储库。
  2. 配置节点。
  3. 安装依赖项。
  4. 在使用 启动的测试数据库中创建数据库架构services
  5. 运行测试。

注意: services可用于运行附加服务。在上面的测试作业中,它用于创建测试 PostgreSQL 数据库。

部署作业将执行以下操作:

  1. 查看存储库
  2. 安装依赖项
  3. 针对生产数据库运行迁移
  4. 部署到 Heroku

注意: on: push 会为每次代码推送到仓库时触发相应的工作流程。而 if: github.event_name == 'push' && github.ref == 'refs/heads/master' 这个条件则确保了名为 deploy 的作业仅在代码被推送到 master 分支时才会被触发执行。

分叉存储库并启用工作流程

首先分叉GitHub 存储库,以便您可以配置 GitHub 操作。

注意:如果您已经对仓库进行了分叉,那么请将原始仓库中master分支的更改合并到您的分叉仓库中。

分叉后,转到Github 上的操作选项卡:

单击启用按钮启用工作流程:

现在,当您将提交推送到存储库时,GitHub 将运行工作流程。

Heroku CLI 登录

确保您已使用 CLI 登录到 Heroku:

heroku login

创建 Heroku 应用程序

要将后端应用程序部署到 Heroku,您需要创建一个 Heroku 应用程序。从克隆存储库的文件夹中运行以下命令:

cd real-world-grading-app
heroku apps:create YOUR_APP_NAME

注意:使用您选择的唯一名称而不是YOUR_APP_NAME

检查点Heroku CLI 应记录应用程序已成功创建:

Creating ⬢ YOUR_APP_NAME... done

在 Heroku 上配置 PostgreSQL 数据库

使用以下命令创建数据库:

heroku addons:create heroku-postgresql:hobby-dev

检查点:要验证数据库是否已创建,您应该看到以下内容:

Creating heroku-postgresql:hobby-dev on ⬢ YOUR_APP_NAME... free
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pg:copy
Created postgresql-closed-86440 as DATABASE_URL

注意: Heroku 会自动设置DATABASE_URL应用程序运行时的环境变量。Prisma 客户端会使用与在 Prisma 架构的 DATABASE_URL 中所配置的环境变量相匹配的那个环境变量。

在 GitHub 中定义构建的机密

为了在 GitHub Actions 中执行生产数据库的迁移操作以及将后端部署到 Heroku,您需要在 GitHub 中创建四个机密,这些机密将在工作流程中被引用。

注意:构建时机密和运行时机密之间存在区别。构建时机密将在 GitHub 中定义并在 GitHub Actions 运行期间使用。另一方面,运行时秘密将在 Heroku 中定义并由后端使用。

密语

  • HEROKU_APP_NAME:您在上一步中选择的应用程序的名称。
  • HEROKU_EMAIL:您注册 Heroku 时使用的电子邮件。
  • HEROKU_API_KEY:Heroku API 密钥
  • DATABASE_URL:Heroku 上的生产 PostgreSQL URL,需要在部署之前运行生产数据库迁移。

获取生产

要获取DATABASE_URLHeroku 在配置数据库时设置的 , 请使用以下 Heroku CLI 命令:

heroku config:get DATABASE_URL

检查点:您应该在输出中看到 URL,例如,postgres://username:password@ec2-12.eu-west-1.compute.amazonaws.com:5432/dbname

得到的HEROKU_API_KEY

您可以从自己的Heroku帐户设置页面中获取Heroku API密钥:

Heroku 账户设置中的 Heroku API 密钥

在 GitHub 中创建机密

要创建四个机密,请转到存储库设置并打开“机密”选项卡:

GitHub 存储库的秘密

单击“新建密钥”,使用名称字段作为密钥名称,例如,HEROKU_APP_NAME并设置值:

检查点:创建四个秘密后,您应该看到以下内容:

GitHub 存储库的秘密

在 Heroku 上定义环境变量

后端需要三个密钥,这些密钥将在运行时作为环境变量传递给应用程序:

  • SENDGRID_API_KEY:SendGrid API 密钥。
  • JWT_SECRET:用于签署 JWT 令牌的秘密。
  • DATABASE_URL:Heroku 自动设置的数据库连接 URL。

注意:您可以JWT_SECRET通过在终端中运行以下命令来生成:

node -e "console.log(require('crypto').randomBytes(256).toString('base64'));"

要使用 Heroku CLI 设置它们,请使用以下命令:

heroku config:set SENDGRID_API_KEY="REPLACE_WITH_API_KEY" JWT_SECRET="REPLACE_WITH_SECRET"

检查点:为了确认环境变量是否已经正确设置,您应该能够看到如下内容:

Setting SENDGRID_API_KEY, JWT_SECRET and restarting ⬢ YOUR_APP_NAME... done, v7

触发工作流程来运行测试和部署

配置工作流程、在 Heroku 上创建应用程序以及设置所有机密后,您现在可以触发工作流程来运行测试和部署。

为了触发构建流程,您可以创建一个空提交并将其推送。

git commit --allow-empty -m "Trigger build"
git push

推送提交后,转到 GitHub 存储库的“操作”选项卡,您应该会看到以下内容:

单击表中包含提交消息的第一行:

查看日志

要查看作业的日志test,请单击test相应的按钮,您可以查看每个步骤的日志。例如,在下面的屏幕截图中,您可以查看测试结果:

验证 Heroku 的部署

要验证该deploy作业已成功部署到 Heroku,请单击deploy左侧的Deploy to Heroku并展开该步骤。您应该在日志末尾看到以下行:

remote: https://***.herokuapp.com/ deployed to Heroku

若要从浏览器中访问API,请在已克隆的存储库文件夹内执行以下Heroku CLI命令:

heroku open

这将打开指向https://YOUR_APP_NAME.herokuapp.com/的浏览器。

检查点:您应该在浏览器中看到由状态端点{"up":true}提供的服务。

查看后端日志

要查看后端日志,请从克隆的存储库文件夹中使用以下 Heroku CLI 命令:

heroku logs --tail -a YOUR_APP_NAME

测试登录流程

要测试登录流程,您需要对 REST API 进行两次调用。

首先获取 API 的 URL:

heroku apps:info

使用curl 对登录端点进行POST 调用:

curl --header "Content-Type: application/json" --request POST --data '{"email":"your-email@prisma.io"}' https://YOUR_APP_NAME.herokuapp.com/login

检查您电子邮件中收到的8位数令牌,并据此执行下一步操作。

curl -v --header "Content-Type: application/json" --request POST --data '{"email":"your-email@prisma.io", "emailToken": "99223388"}' https://YOUR_APP_NAME.herokuapp.com/authenticate

检查点:响应应具有 200 成功状态代码并包含Authorization带有 JWT 令牌的标头:

< Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbklkIjo4fQ.ea2lBPMJ6mrPkwEHCgeIFqqQfkQ2uMQ4hL-GCuwtBAE

概括

您的后端已经成功部署并正在运行中。做得非常好!

您通过定义 GitHub Actions 工作流程配置持续集成和部署,创建 Heroku 应用程序,配置 PostgreSQL 数据库,并使用 GitHub Actions 将后端部署到 Heroku。

当您向仓库提交代码并推送更改以引入新功能时,测试和TypeScript编译器将会自动执行。如果一切顺利,后端将会被部署。

您可以通过进入 Heroku 仪表板来查看内存使用情况、响应时间和吞吐量等指标。这对于深入了解后端如何处理不同的流量非常有用。例如,后端负载增加可能会导致响应时间变慢。

通过将TypeScript与Prisma Client结合使用,您可以在编译阶段就消除一类通常在运行时才会发现且需要调试的类型错误。

您可以在GitHub上找到后端的完整源代码。

尽管Prisma的设计初衷是为了简化关系数据库的使用,但深入了解底层数据库以及Heroku的具体细节仍然是非常有益的。

原文链接:https://www.prisma.io/blog/backend-prisma-typescript-orm-with-postgresql-deployment-bbba1ps7kip5

#你可能也喜欢这些API文章!