前提
- dockerとdocker-composeインストール済み
- prisma cli インストール済み
どのような物を作るか?
単純にHello World!
などのメッセージ一覧を返したり
メッセージを新規作成したり更新、削除したりといった
GraphQLのCRUD APIサーバーを構築します。
#gqlkitをgit cloneし、コンテナを起動する
まずは、gqlkitというdockerアプリケーションフレームワークをgit cloneし、コンテナを起動しましょう。
これで、半分は作業が完了しました!
git clone git@github.com:gqlkit-lab/gqlkit.git
cd gqlkit
cp .env.example .env
docker-compose up -d
PostgreSQLに、データの雛形をマイグレートする
今回、どのようなデータモデルをマイグレートするのかを確認しておきましょう。
gqlkit-server/prisma/schema.prismaを開くと下記のようになっています。
このファイルを編集してprisma migrate
してやる事で
データベースにデータモデルを作ることができます。
datasource db {
provider = "postgresql"
url = "postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
}
model messages {
id String @default(cuid()) @id
text String
created_at String
updated_at String
}
今回は、このままの内容をマイグレートするのでファイルの内容は編集せず下記を実行します。
これでPostgreSQLにmessages
テーブルが作成されました。
prisma migrate save --experimental
prisma migrate up --experimental
ちなみにschema.prisma
に書くモデル名の注意点ですが
gqlkitはgormを採用しているので「messages」のように複数形で「s」が最後に来るように気をつけましょう。
2単語以上の場合はsnake_caseで書いてやります。
GraphQLサーバーを起動する
次の流れとしては、gqlkit-server/graph/schema.graphqlを編集し
gqlkit-server/graph/schema.resolvers.goにリゾルバを書いていくのですが
gqlkitはデフォルトのサンプルとして
messagesのCRUDサンプルはgqlgenでジェネレート済みとなっています。
なので、ここではさらっと
schema.graphqlの中身とschema.resolvers.goの中身を確認だけしておきます。
type Query {
readMessages: [Message!]!
}
type Mutation {
createMessage(text: String!): Message!
updateMessage(id: ID!, text: String!): Message!
deleteMessage(id: ID!): Message!
}
type Message {
id: ID!
text: String!
created_at: String
updated_at: String!
}
package graph
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
import (
"context"
"fmt"
"gqlkit/env"
"gqlkit/graph/generated"
"gqlkit/graph/model"
"time"
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
uuid "github.com/satori/go.uuid"
)
func (r *mutationResolver) CreateMessage(ctx context.Context, text string) (*model.Message, error) {
db, err := gorm.Open("postgres", env.DB_CONNECT)
defer db.Close()
if err != nil {
return nil, fmt.Errorf(err.Error())
}
id := uuid.Must(uuid.NewV4(), nil)
loc, _ := time.LoadLocation("Asia/Tokyo")
now := time.Now().In(loc).Format("2006-01-02T15:04:05+09:00")
r.message = &model.Message{
ID: id.String(),
Text: text,
CreatedAt: &now,
UpdatedAt: now,
}
db.Create(&r.message)
return r.message, nil
}
func (r *mutationResolver) UpdateMessage(ctx context.Context, id string, text string) (*model.Message, error) {
db, err := gorm.Open("postgres", env.DB_CONNECT)
defer db.Close()
if err != nil {
return nil, fmt.Errorf(err.Error())
}
loc, _ := time.LoadLocation("Asia/Tokyo")
now := time.Now().In(loc).Format("2006-01-02T15:04:05+09:00")
db.Where("id = ?", id).First(&r.messages)
r.message = r.messages[0]
db.Model(&r.message).Where("id = ?", id).Update("text", text)
db.Model(&r.message).Where("id = ?", id).Update("updated_at", now)
return r.message, nil
}
func (r *mutationResolver) DeleteMessage(ctx context.Context, id string) (*model.Message, error) {
db, err := gorm.Open("postgres", env.DB_CONNECT)
defer db.Close()
if err != nil {
return nil, fmt.Errorf(err.Error())
}
db.Where("id = ?", id).First(&r.messages)
r.message = r.messages[0]
db.Where("id = ?", id).Delete(&r.messages)
return r.message, nil
}
func (r *queryResolver) ReadMessages(ctx context.Context) ([]*model.Message, error) {
db, err := gorm.Open("postgres", env.DB_CONNECT)
defer db.Close()
if err != nil {
return nil, fmt.Errorf(err.Error())
}
db.Order("created_at").Find(&r.messages)
return r.messages, nil
}
// Mutation returns generated.MutationResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }
// Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
実際に、任意のアプリを開発する際は、
schema.graphql
を編集する
↓
go run github.com/99designs/gqlgen
でリゾルバをジェネレートする
↓
schema.resolvers.go
を編集する
という感じの流れで開発していきます。
という事で最後に、下記を実行してGraphQLプレイグラウンドを立ち上げましょう!
http://localhost:8080/ でGraphQLプレイグラウンドが立ち上がっています。
cd gqlkit-server
go run server.go
まとめ
現在、マークアップエンジニアからwebエンジニアへと
ステップアップ転職を目指しているのですが
何を思ったか求人の多いRubyに手を出さず
先にGoに手を出してしまいました。
すると、Goのなんと楽にバックエンド開発が終了してしまう事か
これは、下手をするとfirebase + nuxtでアプリ作ってた時以上に楽です。
Goに触れたのは幸なのか不幸なのか
その後、Railsの学習に手をつけてみようと何度かトライするのですが
Goの圧倒的すぎるシンプルさ、簡単さ、スッキリさ、に引きずられてしまい
どうしても、わざわざ学ぼうという意欲が出ないでいます。
Laravelも同じく...
求人は多いのに...(泣)
Goめ!実に罪深い!(褒め言葉)