设置Node.js API,带Prisma,Typescript和PostgreSQL
#node #postgres #prisma

课程将覆盖什么

  • 如何用docker-compose产生码头容器
  • 如何将Prisma Express应用程序连接到PostgreSQL数据库
  • 如何将Prisma Express应用程序连接到REDIS数据库

先决条件

要与本教程一起遵循,请确保您有以下内容:

软件

vs代码扩展

  • Docker(可选) - 直接在VS代码中管理Docker容器
  • Prisma添加了语法突出显示,格式化,自动完成和填充.prisma文件。

假定知识

  • 您已经知道JavaScript,Typescript和Node.js的基础知识
  • 您对SQL,PostgreSQL,Redis,Prisma和Docker有基本知识

如何使用Express,PostgreSQL,Redis和Prisma设置Node.js。

使用Docker-Compose创建PostgreSQL和REDIS数据库

在计算机上运行PostgreSQL和REDIS数据库的最明显方法是使用Docker和Docker-Compose。

假设您已经在计算机上安装了DockerDocker-compose

在根目录中创建一个docker-compose.yml文件,然后将下面的配置粘贴到其中。

docker-compose.yml

version: '3'
services:
  postgres:
    image: postgres:latest
    container_name: postgres
    ports:
      - '6500:5432'
    volumes:
      - progresDB:/data/postgres
    env_file:
      - ./.env

  redis:
    image: redis:alpine
    container_name: redis
    ports:
      - '6379:6379'
    volumes:
      - redisDB:/data
volumes:
  progresDB:
  redisDB:

在整个教程系列中,我们将使用此VS代码扩展名来查看存储在PostgreSQL或REDIS数据库中的数据。

Image

要提供PostgreSQL Docker Image所需的凭据(用户名,密码和数据库名称),我们需要在root Directory中创建一个.env文件。

您可以将.env文件添加到.gitignore文件中,以从git提交中省略它。我将在example.env文件中包含一些.envfile内容,以便您可以看到.env文件的外观。

.env

PORT=8000
NODE_ENV=development

POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=6500
POSTGRES_USER=admin
POSTGRES_PASSWORD=password123
POSTGRES_DB=node_prisma

这是环境变量在大写中的约定。

一旦我们拥有以上配置,请运行此命令来产生Docker容器。

docker-compose up -d

设置环境变量

我们应用程序中最重要的部分是设置环境变量。这使我们可以存储敏感信息(API键,密码等),并且我们可以轻松地将它们排除在git提交中。

将使用流行的库dotenv从.env文件加载环境变量。

另外,我将使用配置库来设置和访问环境变量。配置库可帮助我们为环境变量提供打字稿类型

使用此命令初始化一个新的Typescript Node.js项目:

yarn init -y && yarn add -D typescript @types/node && npx tsc --init

删除tsconfig.json文件中的配置并将这些配置粘贴到其中。

{
  "compilerOptions": {
    "target": "es2016",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "strictPropertyInitialization": false,
    "skipLibCheck": true,
    "outDir": "./build",
    "rootDir": "."
  }
}

运行此命令安装dotenv和Config packages

yarn add config dotenv && yarn add -D @types/config

在根目录中创建一个config文件夹,在配置目录中创建两个名为default.tscustom-environment-variables.ts的文件。

将下面的代码片段复制并粘贴到其各自的文件中。

default.ts

export default {
  origin: 'http://localhost:3000'
};

custom-environment-variables.ts

export default {
  port: 'PORT',
  nodeEnv: 'NODE_ENV',
};

验证环境变量

忘记添加环境变量会导致意外的错误,这会导致您的应用程序出现故障。

为了防止这种情况,我们将使用Enkalid软件包来验证环境变量

yarn add envalid

在根目录中和src文件夹中创建一个src文件夹,创建另一个名为utils的文件夹。

utils文件夹中创建一个validateEnv.ts文件。

src/utils/validateEnv.ts

import { cleanEnv, port, str } from 'envalid';

const validateEnv = () => {
  cleanEnv(process.env, {
    NODE_ENV: str(),
    PORT: port(),
    POSTGRES_HOST: str(),
    POSTGRES_PORT: port(),
    POSTGRES_USER: str(),
    POSTGRES_PASSWORD: str(),
    POSTGRES_DB: str(),
  });
};

export default validateEnv;

如果我们在.env文件中没有任何定义变量,或者如果它们是错误的类型,则Enkalid软件包将丢弃错误。

用ExpressJS初始化Prisma项目

prisma带有一个CLI工具,我们可以用来执行不同的操作,例如从我们的模式定义中创建迁移并将生成的迁移代码推向首选数据库。

为此,您需要将prisma CL​​I工具作为依赖关系安装。

yarn add -D prisma 

现在运行此命令以使用Prisma CLI创建基本的Prisma设置:

npx prisma init --datasource-provider postgresql

--datasource-provider标志告诉Prisma cli使用什么数据库。我使用了postgresql,因为这是本教程中写的。

在Root Directory和prisma文件夹中创建一个新的prisma文件夹,您会找到一个schema.prisma文件。 schema.prisma文件是将包含您数据库架构的主要Prisma配置文件。

另外,如果您打开了.env文件,则应该看到Prisma Cli创建的PostgreSQL数据库连接URL。

更改Prisma CLI创建的URL中的默认凭据,并使用我们提供给Docker Postgresql image的凭据。

.env

POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=6500
POSTGRES_USER=admin
POSTGRES_PASSWORD=password123
POSTGRES_DB=node_prisma

您的连接URL现在应该看起来像这样,假设您使用了我提供的配置。

.env

DATABASE_URL="postgresql://admin:password123@127.0.0.1:6500/node_prisma?schema=public"

使用Prisma创建数据库架构

打开/prisma/schema.prisma文件时,您会找到一个准骨架构:

prisma/schema.prisma

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

datasource字段中,您可以看到Prisma使用postgresql作为数据库提供商,并且我们重新加载了数据库连接URL URL构成.env文件。

另外,在generator块中,provider = "prisma-client-js"告诉Prisma基于我们的数据模型生成Prisma客户端。

定义用户模型

prisma/schema.prisma

model User{
  @@map(name: "users")

  id String  @id @default(uuid())
  name String  @db.VarChar(255)
  email String 
  photo String? @default("default.png")
  verified Boolean? @default(false) 

  password String
  role RoleEnumType? @default(user)

  verificationCode String? @db.Text

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@unique([email, verificationCode])
  @@index([email, verificationCode])
}

enum RoleEnumType {
  user
  admin
}

在上面,我们定义了User模型,而@@map(name: "users")告诉Prisma将users用作数据库表名称。

模型中的每个字段都有一个名称,后跟类型和可选字段属性。

id字段上的@id属性指定它是users表的主要键。另外,@default(uuid())attribute设置了一个默认的uuid(普遍唯一的标识符)。

默认情况下需要所有字段,因此在字段类型之后添加?指定它是可选的。

RoleEnumType枚举表示用户是否是管理员。

@@unique([email, verificationCode])指定数组中提供的emailverificationCode字段应在数据库中具有唯一的约束。

最后,@@index([email, verificationCode])在数据库中的emailverificationCode字段上定义了索引。

数据库迁移与Prisma

要创建一个新的迁移,请运行以下命令

PostgreSQL Docker容器必须运行才能正常工作。

npx prisma migrate dev --name user-entity --create-only

the--name标志给迁移一个名称,而--create-only告诉Prisma仅在不使用它的情况下创建迁移。

现在运行此命令以安装Prisma客户端。下一步需要。

yarn add @prisma/client

要在数据库中创建users表,请运行以下命令:

npx prisma db push

如何将ExpressJS应用程序连接到Redis

运行以下命令以安装Express和Redis

yarn add express redis && yarn add -D @types/express

utils文件夹中创建一个connectRedis.ts文件,然后在下面添加代码段。

src/utils/connectredis.ts

import { createClient } from 'redis';

const redisUrl = 'redis://localhost:6379';

const redisClient = createClient({
  url: redisUrl,
});

const connectRedis = async () => {
  try {
    await redisClient.connect();
    console.log('Redis client connect successfully');
    redisClient.set('try', 'Welcome to Express and TypeScript with Prisma');
  } catch (error) {
    console.log(error);
    setTimeout(connectRedis, 5000);
  }
};

connectRedis();

export default redisClient;


我在redis实例上使用.set()方法将带有try键的消息添加到REDIS数据库中。

接下来,在src文件夹中创建一个app.ts文件,然后将代码片段粘贴到下面。

src/app.ts

require('dotenv').config();
import express, { Response } from 'express';
import config from 'config';
import validateEnv from './utils/validateEnv';
import { PrismaClient } from '@prisma/client';
import redisClient from './utils/connectRedis';

validateEnv();

const prisma = new PrismaClient();
const app = express();

async function bootstrap() {
  // Testing
  app.get('/api/healthchecker', async (_, res: Response) => {
    const message = await redisClient.get('try');
    res.status(200).json({
      status: 'success',
      message,
    });
  });

  const port = config.get<number>('port');
  app.listen(port, () => {
    console.log(`Server on port: ${port}`);
  });
}

bootstrap()
  .catch((err) => {
    throw err;
  })
  .finally(async () => {
    await prisma.$disconnect();
  });


这是我在app.ts文件中所做的事情的分解:

  • 首先,我唤起了validateEnv()函数以验证.env文件中的环境变量。
  • 接下来,我创建了Prisma客户端的实例,并表达
  • 接下来,我创建了一个bootstrap函数,其中定义了应用程序逻辑。我创建了一个/api/healthchecker获取路线,以帮助我们检查我们提供的所有配置是否有效。

另外,我调用了listen()方法来启动服务器。

最后,在/api/healthchecker路由控制器中,我在redisClient实例上使用了.get()方法来获取我们存储在redis数据库中的消息。

现在,将以下脚本添加到您的package.json文件中。

{
"scripts": {
    "start": "ts-node-dev --respawn --transpile-only --exit-child src/app.ts",
    "migrate": "npx prisma migrate dev --name user-entity && npx prisma generate",
    "push": "npx prisma db push",
    "build": "tsc . -p"
  }
}

由于我们使用Typescript,因此我们需要一个包来自动重新启动文件时。

我推荐ts-node-dev,因为它优化了速度与nodemonts-node

运行此命令安装ts-node-dev软件包

yarn add ts-node-dev

安装了ts-node-dev,运行此命令以启动开发服务器。

yarn start

在您的浏览器中打开一个新选项卡,然后输入此URL http://localhost:8000/api/healthchecker,您应该在REDIS数据库中看到一个JSON响应。

与MySQL VS代码扩展连接到PostgreSQL和Redis

连接到redis docker容器

单击侧栏上的NOSQL选项卡,然后单击创建连接蓝色按钮。

Image

我们不需要提供任何凭证来连接到Redis容器,因此请单击连接按钮。

Image

展开下拉列表,然后单击try键,以查看我们存储在Redis数据库中的消息。

Image

连接到PostgreSQL Docker容器

单击VS代码左侧栏上的数据库选项卡,然后单击 创建连接 按钮。

Image

从可用服务器类型中选择PostgreSQL,然后提供.env文件中包含的数据库凭据,然后单击 '连接 按钮。

Image

假设连接成功,请在左侧展开下拉列表,然后单击users表以查看我们使用Prisma定义的列。

Image

结论

恭喜您达到了终点。在本文中,您了解了如何使用ExpressJS,Redis,Prisma,Postgresql和Docker设置Node.js项目。