はじめに
はじめまして。全然関係ないけど、最近は Vue を裏切って React 書いてます。
さて、前回、TypeORM を使って Node.js の GraphQL 環境を構築しましたが、ぶっちゃけ TypeORM と GraphQL との親和性があまり良くなくて、結局、その後の開発がそこまでドライブしませんでした。
そんな中、今のチームで Node.js で GraphQL の API サーバを新たに構築する必要があり、参考になる既存資産もあったので Nexus + Prisma でやってみました。
以下の記事を大いに参考にさせていただいております。
実際にやってみた
Prisma
Next-generation Node.js and 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}"
続いて、接続の定義と Schema 定義を行います。
以下はサンプルです。
// 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])
}
接続設定と Schema のファイルを修正したら migration ファイルを生成。以下コマンドを実行。
この辺は元記事時点とのバージョンの違いからコマンドに差異があります。
$ npx prisma migrate dev --name ${migration_file_name} --create-only
prisma/2021xxxxxxxxxx_${migration_file_name}
的なディレクトリができているので、その中に .mysql
ファイルがあることを確認。
以下を実行すると migration が走ります。
$ npx prisma migrate dev
(省略)
✔ Generated Prisma Client (2.30.3) to ./node_modules/@prisma/client in 159ms
最後にこんなログが出力されれば成功です。
ターミナルから MySQL に直接ログインできる方は実際にテーブルを確認してみてください。
次に、↑で定義した Schema 情報から prisma-client の型を生成します。
$ npx prisma generate
Apollo Server
Express で Apollo Server を動かすための設定を行います。
Apollo Server は、ApolloClient を含むすべての GraphQL クライアントと互換性のあるオープンソースの仕様準拠の GraphQL サーバーです。
ちなみに、上記はただ公式の英文を翻訳しただけです。
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 で Type-Safe に 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 Playground
GraphQL Playground を実行します。
$ npm run dev
ブラウザからアクセスしてみて、意図通りの Schema などが表示されていれば成功です。
おわりに
TypeORM を使って無理やり GraphQL を構築していた時よりも、Query の頻出パターンを自動で生成できるなどの仕組みがあるので、こっちの方が圧倒的に便利そうな気配がありました。
初期構築も、前回記事の内容よりも少ないので、明らかに導入も簡単です。そして、TypeORM より日本語の参考記事が多い、気がする。
認証系の組み込みなど、実運用レベルのコードをまだ書いてませんが、これから Node.js で GraphQL サーバの構築を始める方は たぶん こっち使った方がいいと思います。
おしまい。