使用TypeScript + Nexus + Prisma来构建了一个GraphQL(用于MySQL)环境
首先
初次见面。虽然完全无关,但最近我背叛了Vue,开始写React。
好吧,上一次我們使用TypeORM來構建了一個Node.js的GraphQL環境,但實際上TypeORM和GraphQL的相容性並不好,結果後續的開發並沒有大幅推進。
而在這種情況下,我們現在的團隊需要在Node.js上構建一個GraphQL的API服務器,並且還有一些有參考價值的現有資源,所以我們試著用Nexus + Prisma來實現。
我对以下的文章深表感谢,并已经认真地参考了它。
我亲自试过了。
普利司玛 (pǔ lì sī mǎ)
下一代的Node.js和TypeScript对象关系映射器(ORM)
正如官方所述,这是一个ORM库。
请安装。
请预先准备好 package.json 文件。
$ npm i @prisma/client@2.23
刚开始使用2系,是因为最初使用3系进行构建和测试时出现了错误 ???
接下来,将自动生成所需的初始代码。执行以下操作。
$ npx prisma init
由于生成了 prisma,因此需要修改其中的 .env 和 schema.prisma。
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#using-environment-variables
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server and MongoDB (Preview).
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="mysql://${username}:${password}@${host}:${port}/${db_name}"
接下来,我们将进行连接和模式定义。
以下是一个示例。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Company {
id Int @id @default(autoincrement())
name String
address String
accounts Account[]
}
model Account {
id Int @id @default(autoincrement())
name String
email String @unique
companyId Int
company Company @relation(fields: [companyId], references: [id])
}
修改连接设置和模式文件后,生成迁移文件。接下来执行以下命令。
由于版本差异的原因,此处的命令与原文章时的命令有所不同。
$ npx prisma migrate dev --name ${migration_file_name} --create-only
检查是否存在类似于 prisma/2021xxxxxxxxxx_${migration_file_name} 的目录,然后确认其中是否存在 .mysql 文件。
如果执行以下操作,迁移将会运行。
$ npx prisma migrate dev
(省略)
✔ Generated Prisma Client (2.30.3) to ./node_modules/@prisma/client in 159ms
如果最后能够输出这样的日志,那就是成功了。
如果您可以直接從終端機登錄MySQL,請實際檢查資料表。
然后,我们将根据上述定义的 Schema 信息生成 prisma-client 的类型。
$ npx prisma generate
阿波罗服务器
进行配置以在 Express 中运行 Apollo Server。
Apollo Server 是一个开源的符合规范的 GraphQL 服务器,与所有 GraphQL 客户端(包括 ApolloClient)兼容。
顺便说一下,上面只是官方英文的翻译。
最初使用2系的原因是因为在尝试构建和运行3系时出现了错误。 ???
$ npm i -D ts-node-dev typescript @types/express
$ npm i express apollo-server-express@2
创建 tsconfig.json 文件。内容可根据您的喜好自行设定。
$ touch tsconfig.json
创建服务器的入口点等。
这些部分基本上是抄袭了原文的代码。
import * as express from 'express';
import { ApolloServer } from 'apollo-server-express';
import { createContext } from './context';
import schema from './schema';
const PORT = 4000;
const app = express();
const apollo = new ApolloServer({ schema, context: createContext });
apollo.applyMiddleware({ app });
app.listen({ port: PORT }, () =>
console.log(`? Server ready at http://localhost:4000${apollo.graphqlPath}`)
);
import { PrismaClient } from '@prisma/client';
import { Request } from 'apollo-server-express';
const prisma = new PrismaClient();
export interface Context {
request: Request;
prisma: PrismaClient;
}
export function createContext(request: Request): Context {
return {
request,
prisma,
};
}
请在package.json中添加以下内容。
{
...
"scripts": {
"dev": "ts-node-dev --no-notify --respawn --transpile-only src/server.ts",
"build": "tsc -p .",
"start": "node dist/server.js",
}
...
}
Nexus(中文释义)
听说这是一个用于在Node.js中构建类型安全的GraphQL模式的库。
安装。
$ npm i graphql
$ npm i @nexus/schema nexus nexus-plugin-prisma
在代码中添加Schema。
与原文不同的是,将自动生成的代码输出目录设置为src/gen/。
import * as path from 'path';
import { makeSchema } from '@nexus/schema';
import { nexusPrisma } from 'nexus-plugin-prisma';
import * as types from './types';
const schema = makeSchema({
types,
plugins: [
nexusPrisma({
experimentalCRUD: true,
}),
],
outputs: {
schema: path.join(__dirname, './gen/graphql/schema.graphql'),
typegen: path.join(__dirname, './gen/nexus/types.ts'),
},
});
export default schema;
export * from './models';
export * from './resolvers';
// e.g.
export * from './User'
import { objectType } from '@nexus/schema';
// e.g.
export const User = objectType({
name: 'User',
definition(t) {
t.int("id")
},
});
export * from './Query';
export * from './Mutation';
import { queryType } from '@nexus/schema';
// e.g.
export const Query = queryType({
definition(t) {
t.crud.user();
},
});
import { mutationType } from '@nexus/schema';
// e.g.
export const Mutation = mutationType({
definition(t) {
t.crud.createOneUser();
},
});
在package.json中添加以下内容:
{
...
"scripts": {
"generate:nexus": "ts-node --transpile-only src/schema"
}
...
}
生成 Nexus 的类型定义。
$ npm run generate:nexus
GraphQL 游乐场
运行GraphQL Playground。
$ npm run dev
如果您能够通过浏览器访问并且成功显示了预期的构架等内容,则表示操作成功。
最后
在使用TypeORM強行構建GraphQL的時候,相比起以前,這邊有一些機制可以自動產生出頻繁出現的Query模式,因此感覺這邊更加方便。
初次設置也比之前的文章內容要簡單,明顯地引入也更容易。而且,相較於TypeORM,似乎有更多關於日語的參考文章。
我还没有编写实际运行级别的代码,比如认证系统的集成,但如果你准备开始使用 Node.js 构建 GraphQL 服务器,我认为你可能更好地选择这种方法。
结束了。