🥑

RedwoodJSに入門してみた(第1回: アプリ作成〜モデル作成)

2022/12/13に公開約5,300字

はじめに

今回から、全5回でRedwoodJSを使ってみて、その概要と所感などを公開していく。

RedwoodJSに入門してみた(第1回: アプリ作成〜モデル作成)
RedwoodJSに入門してみた(第2回: CRUD作成 API編)
RedwoodJSに入門してみた(第3回: CRUD作成 WEB編)
RedwoodJSに入門してみた(第4回: dbAuthによる認証)
RedwoodJSに入門してみた(第5回: 実際に触ってみて感じたこと)

RedwoodJSとは

JavaScript/TypeScriptのフルスタック Web フレームワークで、ReactGraphQLPrismaといった技術が使用されている。
冒頭から脱線するが、Redwoodの名前の由来が良い話だったので興味がある方はぜひ…!
https://github.com/redwoodjs/redwood/blob/main/README.md#why-is-it-called-redwood

なぜRedwoodJSなのか

普段はRailsで開発することが多いものの、フロントエンドではAction Viewを使わずにReact + TypeScriptを使用することも少なくない。その上、RailsReact + TypeScriptのやり取りをスムーズにするため、GraphQLを導入することも増えてきている。

結果的に技術スタックとしては、React, TypeScript, GraphQL(GraphQL Ruby / Apollo Client)という感じで、RedwoodJSのものと近くなっており、さらにサーバーサイドとフロントエンドの両方をTypeScriptで書けることにも魅力を感じ、RedwoodJSに入門してみることにした。

アプリを作成する

早速アプリを作成していく。

開発環境

今回は開発時点で最新のRedwoodのv3.2.1を使用する

Redwood requires Node.js (>=14.19.x <=16.x) and Yarn (>=1.15)

公式ドキュメントでこう書いてあるので下記バージョンで行う。

node.js 16.14.2
yarn 3.2.3

アプリを作成する

下記コマンドでアプリを作成できる。

yarn create redwood-app my-redwood-project --typescript

デフォルトはJavaScriptで作成されるので、TypeScript対応のため--typescriptを指定する。

作成されたアプリのディレクトリに移動する。

cd my-redwood-project

アプリのディレクトリ構成は下記のようになっている。

├── api
│   ├── db
│   │   └── schema.prisma
│   ├── dist
│   ├── src
│   │   ├── directives
│   │   │   ├── requireAuth
│   │   │   └── skipAuth
│   │   ├── functions
│   │   │   └── graphql.ts
│   │   ├── graphql
│   │   ├── lib
│   │   │   ├── auth.ts
│   │   │   ├── db.ts
│   │   │   └── logger.ts
│   │   └── services
│   └── types
│
├── scripts
│   └── seed.ts
│
└── web
    ├── public
    │   ├── favicon.png
    │   ├── README.md
    │   └── robots.txt
    └── src
        ├── components
        ├── layouts
        ├── pages
        │   ├── FatalErrorPage
        │   │   └── FatalErrorPage.tsx
        │   └── NotFoundPage
        │       └── NotFoundPage.tsx
        ├── App.tsx
        ├── index.css
        ├── index.html
        └── Routes.tsx

api配下にバックエンド、web配下にフロントエンドのコードが配置されていて、Yarnでは、これらをworkspaceという概念として扱う。

下記のようにworkspaceごとにパッケージを管理することになる。

yarn workspace web add <フロントエンドに追加したいパッケージ>
yarn workspace api add <バックエンドに追加したいパッケージ>

workspaceがなかったら、それぞれのディレクトリに移動してパッケージインストールすることになりそうなので、それをしなくて良いのは嬉しい。

開発用サーバーを起動する

下記コマンドでサーバーを立ち上げることができる。

yarn redwood dev

redwoodのエイリアスとしてrwも使用することもできる(以降は全てrwを使用する )

yarn rw dev

サーバーがうまく立ち上がっていたらhttp://localhost:8910/[1]にアクセスする(というか自動で開く)と下記のような表示が出る。

モデルの作成

Redwoodでは、DBとのやり取りにPrismaを使用している。

ここでは、yarn rw prismaといったコマンドを使用するが、これはPrisma CLIをラップしたものであり、Redwoodのドキュメントには最低限のコマンドしか載っていない。詳細はPrisma CLIのリファレンスを確認するのが良さそう。

https://www.prisma.io/docs/reference/api-reference/command-reference

マイグレーション

マイグレーションはschemaのァイルを編集して、migrateコマンドを実行という順番で行う。

Railsではschemaファイルを直接編集することはあまりないので、少しドキドキする…。

まずはapi/db/schema.prismaに下記を追加する。

api/db/schema.prisma
model Post {
  id        Int      @id @default(autoincrement())
  title     String
  body      String
  createdAt DateTime @default(now())
}

ちなみにid String @id @default(uuid())のように指定することで、idをUUIDにすることもできる。

migrateを実行する。

yarn rw prisma migrate dev

実行するとマイグレーションの名前を何にするか聞かれるので、create postなど、適当なマイグレーション名を入力するとPostモデルを作成するマイグレーションファイルが生成されて、同時にマイグレーションも実行される。

api/db/migrations/{YYYYMMDDHHMMSS}_create_posts/migration.sql
-- CreateTable
CREATE TABLE "Post" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "title" TEXT NOT NULL,
    "body" TEXT NOT NULL,
    "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);

作成された。

つまり、開発フローとしてはschema編集 → migrate実行という流れだが、prisma migrateの実行時、下記のような手続きが行われている。

  • すでにマイグレーションファイルがある場合はそれらを実行
  • その状態とschema.prismaとの差分をみて、追加で必要なマイグレーションファイルを作成(ここでマイグレーション名を聞かれる)
  • 追加したマイグレーションファイルの実行(今回はcreate postが実行された)

なるほど、Schemaをそのまま編集するのすごく便利…!

ちなみに、作成されたマイグレーションファイルを見ると分かるが、各カラムにはNull制約がデフォルトでついている。
型指定の部分でString?のように型名のあとに ?をつけることで null 制約を外すことができる。

Prisma Studio

PrismaにはStudioというツールがあり、下記コマンドを実行することで開くことができる。

yarn rw prisma studio

実行後http://localhost:5555が開き、データをGUIで閲覧・操作することができる。
DBクライアントいらずでめっちゃ便利。

参考

https://github.com/redwoodjs/redwood
https://www.prisma.io/docs/reference/api-reference/command-reference

次回

次回は作成したモデルで CRUD を作成する。

脚注
  1. 余談だが、port番号覚えにくいなーと思っていたら、8,9,10と順番になっている。敢えてなのかは分からない。(どっかで言いたいと思ったけど、言うタイミングがないので、ここに書いておく) ↩︎

GitHubで編集を提案

Discussion

ログインするとコメントできます