はじめに
この数年フロントエンドドリブンな開発が盛んに行われており、バックエンド側の処理もTypeScriptで実装している記事や動きをよく見かけます。マイクロフロントエンドみたいな単語も出てきましたね。
GoQSystemでも新しい技術の情報収集やキャッチアップは常に行っています。私はバックエンドエンジニアですが、システム全体のアーキテクチャを検討する上でフロントエンド側の技術の情報収集やキャッチアップは常に行っています。
今回はPrismaのGitHubリポジトリにあるExampleを使用してGraphQLサーバー作成してみます。
使用技術
- TypeScript
- NestJS
- Prisma
- GraphQL
NestJSとは
効率的で信頼性が高く、スケーラブルなサーバーサイドアプリケーションを構築するためのプログレッシブNode.jsフレームワークです。
Prismaとは
オープンソースのORM(Object-relational mapping)です。
GraphQLとは
クエリ言語とスキーマ言語で構成されたWeb APIの規格です。GraphQLは、Facebook社によって2012年に開発がスタートし、2015年にオープンソース化されました。
開発環境
※ nodeやnpmはインストールされているものとします。
マシン:MacBook Pro (13インチ, 2020)(Apple M1, メモリ16GBモデル)
OS:macOS Ventura 13.0.1
npm -v
8.19.2
node -v
v18.12.1
使用するExample
GraphQLサーバーを作成する
1. Exampleダウンロードとnpm依存関係インストール
ExampleリポジトリをREADME通りに以下のコマンドでダウンロードします。
npx try-prisma --template typescript/graphql-nestjs
以下のように自動でパッケージをインストールするか聞かれるので今回はy
を選択し、自動でインストールしてもらいます。
? Should we automatically install packages for you? y
次に使用するパッケージマネジャーを選ぶ必要があるので、選択します。今回はnpm
を使用するのでこのままEnterを押します。
? Which package manager do you prefer? (Use arrow keys)
❯ npm
yarn
pnpm
次にプロジェクトの名前を聞かれるので入力します。今回はnestjs-prisma-graphql
とします。
? What should the project be named? nestjs-prisma-graphql
最後にフォルダの作成場所を聞かれるので、適当なパスを入力します。今回は.
とします。
? Where should the new folder be created? .
私は最終的にこのような出力となりました。
npx try-prisma --template typescript/graphql-nestjs
✔ Loaded 40 templates
? Should we automatically install packages for you? Yes
? Which package manager do you prefer? npm
? What should the project be named? nestjs-prisma-graphql
? Where should the new folder be created? .
✔ Downloaded and extracted the typescript/graphql-nestjs project.
✔ Installed packages.
The project is good to go! Next steps:
1. Navigate into the project directory:
cd ./nestjs-prisma-graphql
2. Create and execute initial migration based on `schema.prisma`:
npx prisma migrate dev
For more information about this project, visit:
https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-nestjs
If you have any feedback about this specific template, we want to hear it!
Submit any feedback here: https://pris.ly/prisma-examples-feedback
2. データーベースの作成とシード
以下のコマンドを実行すると、SQLiteを作成、User
とPost
テーブルを作成してくれます。
cd ./nestjs-prisma-graphql
npx prisma migrate dev --name init
このコマンドがデータベースとテーブル作成ファイルprisma/schema.prisma、シード実行ファイルprisma/seed.tsを実行しています。
※今回はPrismaのExampleなのでORMはPrismaを使用していますが、TypeORMも使用してみました。
TypeORMがNestJSのデファクト?なのだと思いますが、0.2系と0.3系の変更点が破壊的で情報が少なく少々苦労しました。個人的にはPrismaの方が使いやすいと感じました。(特に設定ファイルとマイグレーション関連)
実行すると以下のような出力になりました。
npx prisma migrate dev --name init
Prisma schema loaded from prisma/schema.prisma
Datasource "db": SQLite database "dev.db" at "file:./dev.db"
SQLite database dev.db created at file:./dev.db
Applying migration `20230115152921_init`
The following migration(s) have been created and applied from new schema changes:
migrations/
└─ 20230115152921_init/
└─ migration.sql
Your database is now in sync with your schema.
✔ Generated Prisma Client (4.8.1 | library) to ./node_modules/@prisma/client in 194ms
Running seed command `ts-node prisma/seed.ts` ...
Start seeding ...
Created user with id: 1
Created user with id: 2
Created user with id: 3
Seeding finished.
🌱 The seed command has been executed.
3. GraphQLサーバーの起動
以下のコマンドでNestJSを起動します。
npm run dev
以下のようなログがターミナル上に表示され、
npm run dev
...
🚀 Server ready at: http://localhost:3000/graphql
⭐️ See sample queries: http://pris.ly/e/ts/graphql-nestjs#using-the-graphql-api
http://localhost:3000/graphql にアクセスしGraphQL Playgroundが表示されればOKです。
GraphQLでデータを取得してみる
GraphQL Playgroundを使用してデータを取得してみます。
http://localhost:3000/graphql にアクセスし、以下のクエリーを使用して、posts
とそれに紐つくauthors
を取得します。
query {
feed {
id
title
content
published
author {
id
name
email
}
}
}
GraphQL Playgroundの左側へ上記クエリーを貼り付けて、画面真ん中のexecute
ボタンを押せばデータが取得できます。
他にもデータ作成(mutation
)、新しいモデルの作成(Prisma)方法などもExampleリポジトリにあるので是非試してみてください。
GraphQLの実現にはpackage.json
を確認したらわかるように、Apolloが使用されています。(src/app.module.ts
でApolloDriver
が読み込まれています。)
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
buildSchemaOptions: { dateScalarMode: 'timestamp' },
}),
],
controllers: [],
providers: [PrismaService, UserResolver, PostResolver],
})
そして、GraphQLのSchema定義はsrc/schema.gql
で行われています。
感想
今回は紹介しませんが、Exampleを使用せずに0からNestJSをインストールしてデフォルト機能を使用してREST APIを作成したり、SQLiteではなくDockerでPostgreSQLやMySQLを構築し使用したり、TypeORM使ったり、tRPCサーバー立ててみたりいろいろなことを試してみました。
シンプルな記述内容で簡単にAPIサーバーを作成することができるのでとても魅力的な技術だなと思っています。AWS CDKでTypeScriptを使用すれば、フロントエンド+バックエンド+インフラ全てTypeScriptで実現できますね。
上述したようにtRPCのサーバーも非常に簡単に作成できました。これらの技術を使用すれば非常に簡単にREST APIやGraphQL環境を作成できるのは魅力的です。
ただ、がっつりバックエンドAPIを作成するときにあえてNestJSというフレームワークを選択することはないのかなというのが正直な思いです。もう少し複雑な処理やアーキテクチャを組みたい時やスケールさせていくことを考えると特に思うところです。
しかしながら、組織・チームでの開発、保守運用を考慮するとフロントエンドエンジニアが慣れ親しんだ言語でバックエンド側の処理を構築できるのは魅力的だなと感じました。組織やチームにバックエンドエンジニアが不足している、いないなどの状況もあり得るのでその場合は選択する理由にはなるかと思います。
フロントエンドエンジニアからすると簡単にアプリケーションを構築するのであればT3 Stack、もしくはSvelteKitやSupabase(or Firebase)使用してといった選択になるのではないかと想像しています。
使い所はしっかりと検討しなければいけない技術ですが、どこかで採用していきたいとも感じました。いずれにしても、自分の専門外(TypeScript)の技術を触ると知見が広がって楽しかったです。
最後に
GoQSystemでは一緒に働いてくれる仲間を募集中です!
求人は出していませんが、SREやQAエンジニアも今後募集していこうと考えています!
ご興味がある方は以下リンクよりご確認ください。