令和最初の入社ブログ
令和最初の入社ブログ
この記事は書き手である bannzai が「令和最初の入社ブログってエモいなあ」と思い 令和最初の入社ブログ というタイトルのブログを書きたいがために書く入社ブログである。
個人的なご報告含めて書いていきます。
株式会社DeNAに入社しました
令和最初の日である2019年5月1日から株式会社DeNAに入社しました。と言っても初出社はGW明けなのでまだ働いていないのですが。
DeNA
では マンガボックス
というサービスに携わります。 今までは iOS
アプリの開発で Swift
をメインに書いていたのですが、次の職場でのメインポジションは Go
を用いた API
開発者をになっていきます。
僕は知り合いからの紹介経由で面接したのでここから募集したわけじゃないのですが、募集内容としてはきっとこれですね。
なんでiOSエンジニア辞めたの?
正確にはおそらく iOS
もチョット書くのかな。と思っています。
メインポジションが Go
のエンジニアと記載した意図としては、今までもメインは iOS
をやりつつ Rails
や Go
等を使用した開発は業務でやっていました。今回の転職を機に比率が逆転しGo
の方が書くことが多くなる。と想定しています。
別に会社からどっちもやってと求められているとかではなく性格的に「なんか違うことしたい」って思うとやりたくなる性格なんですよね。iOS
は自分の得意なパートでもあるので勝手に気分転換でやっているだろうなー。って予想です。
で、なんでiOSエンジニア辞めたの?
なのですが、理由は全然なくて マンガボックス
チームに入ってみたいな。空いているポジションは Go
のポジションか。サーバーサイドもたまにはガッツリやってみるか。とかこのくらいのノリです。良く言えばこだわりがなくて、悪くいうといいかげんな理由ですね笑
あとは Go
はマルチプラットフォームでツールを作るのには最適な手段だと思っているので Go
により慣れてツールづくりのスキルも伸ばせるのは楽しみですね。 Go
製の OSS
書いて スター乞食
しにいきたいですね。
転職先の決め手
まず、DeNA
という会社に魅力を感じたのが、大きな企業ならではなのですがエンジニアの数が多いところが魅力だな。と思いました。以前は創業間もないスタートアップにいて小さな組織だったのですがその時に初めてエンジニアの数がほとんど居ない環境を味わいました。その時になんだか寂しいな。と思い、その点 DeNA
さんは人数も多いのはもちろん社内外で開催している勉強会もあり事業をまたいだ交流等も活発なのがとても印象がよかったです。もう少し具体的に言うと最近Swiftコンパイラ等のコンパイラ部分についての興味がだんだん強くなってきました。そういった社内勉強会みたいなのも最近定期的にやっていると聞きとてもいいな。楽しそうだな。という印象を受けました。あとこれに関連するかわからないのですが、僕が配属するチームでは社外勉強会への参加への金銭面でのサポートおよび周りからの理解もありそうでとても嬉しかったです。
マンガボックス
チームに関しては@koooootakeさんとお話する機会があり、チームの雰囲気ややり方を詳しく聞けてこのチームは楽しそう。自分が課題に感じていたことも積極的に行えてすごいチームだ。そう思えました。話してもらった内容はDeNA Tech Confというイベントで話していた内容を話してもらいました。このときは僕はこのトークを聞きそびれていたのですが、逆に当事者に逐一質問もできてあった時にはないができてよかったと思います。
他にも DeNA
さんには何人か知り合いが居て特にtarappoには社内全体についてどういう風になっているのかは教えてもらえたと思います。外から見ても余裕のある組織である一方新しい事業も立ち上げたりして活発な組織だなと思っていました。外から見た印象や中での様子・エンジニアとしての動きやすさ。といった部分でも大いに参考にさせてもらいました。
最後に
ネタブログのつもりが割と真面目なことを書いてしまった。。。 (2度目)
本当は 2019/05/01
に 令和最初の入社ブログ
を書いて公開しようと思ったのですが平成最後に急にやりたいこと
ができてしまって予定通りに行きませんでした。
これが 令和最初の入社ブログ
でありますように。
おしまい\(^o^)/
平成最後の退職ブログ
平成最後の退職ブログ
この記事は書き手である bannzai が「平成最後の退職ブログってエモいなあ」と思い 平成最後の退職ブログ というタイトルのブログを書きたいがために書く退職ブログである。
株式会社Asobicaを辞めました。
2018年1月から創業したスタートアップ 株式会社Asobica を 平成最後の日 である 2019/04/30
をもって退職する事になりました。
最終出社という点では有給消化やGWもありもっと前に終わっているのですが、平成最後の日 であるこの日が正式な退職日となります。
Asobica
やそこで開発しているサービスである fever についてはおそらく知名度はさほど高くはなく、ナニソレ感があるかもしれませんがここで事業内容を説明する気はないので、興味がある方はggってください。とはいえ少し驚いたのが国内ではあまり開拓されていない領域でありながら案外サービスが知られているな。って驚いたことも数回あったのでもしかしたらご存知の方はいるかも知れませんね。
何をやっていたの
さて、私が Asobica
, ひいては fever
というサービス開発で行ってきたことをつらつらと書いていきます。
ちなみにAsobica
に転職する前は違う会社に居ました。その時の退職ブログをnoteの方に書いてあるので良かったらどうぞ。(若い頃の俺こんな事書いてたんだ)
株式会社マネーフォワードを退職して新しい環境でチャレンジします
このブログでも軽く書いてあるのですが働き方としてはリモートワークで開発に集中できる環境でした。 コミュニケーションも週に1度出社してそこで取っていきました。僕は基本オンラインベースでコミュニケーションを取っていくってスタンスで働いていきました。 技術スタックについてはサービスに関してのことを広くやっていきました。
- iOS
- GCP(GAE, CloudSQL...etc)
- Golang(GraphQL)
- Ruby on Rails(Web・OpenAPI)
- jQuery
- Bitrise
- CircleCI
- Docker
まあスタートアップあるあるなのですが、技術者で言うと一つのことをガッツリ深掘りする。というよりはメイン(iOS)はあるけど、必要であれば他の部分も適宜手伝いないし主軸となって開発する。と言った具合の環境でした。しかし、なんでもやる。というよりは僕だったら技術部分に関しては手広く手を付ける。ビジネスサイドや法律周りもウォッチはしていましたが、他のメンバーがそれを担ってくれていました。iOSアプリについてはデザイナーが居ない状態だったため僕の裁量に大体任されていたってiOSアプリのフロント部分を作っていきました。
まだ導入事例が少ないときにGraphQLを使用してのAPI設計やクライアントアプリの実装を共にでき。Goを使ってのサーバーサイドアプリケーションの設計、Dockerを用いた開発。といった内容をチャレンジさせてもらってとても技術的に楽しめた1年でした。
一人でこなす量や範囲が広い分普段そんなにやってなかったことを業務レベルでやれたことはとても良かったです。
僕は技術者として技術やコーディングを楽しみたいと考えています。
その点でいうと Asobica
では比較的自分のペースでやらせてもらえたし、上述したように技術に対しての裁量は任せてもらえて満足しています。
なんで辞めたの
これがすべてではないのですが、あえて創業期間もないスタートアップにジョインしたという点に注目してお話します。
まず Asobica
に入った大きなきっかけの一つに fever
という当時はエッジが効いていたサービス内容に惹かれた部分がありました。
しかし、何度かサービスの方針が変わったりとか諸々の事情ピボットを繰り返しました。本来想定していたサービスとは表面上は結構異なる部分が出てきて少し寂しさを覚えてしまった部分があります。表面上 と言ったのはサービスとして解決したい課題は CEO
の中ではブレずにチャレンジをしていったとは思うのでこういう言葉を使用しています。
また小さな組織の楽しさの一つに相談事をパッと相談してパッと決める。決めた内容はもちろん敬意含めて記録しておくのですが、小さい組織故に大掛かりなMTGを開く機会も必要なく、それでいて全体の状況をなんとなくでも把握して置けるのはとてもやりやすく自分も何か思いついた時に発言できるのはとても良いものだ。と思っていました。
ただ、これは僕にも原因はあると思うのですが、ほとんど僕はフルリモートで働いていてコーディング等にはとても集中できたのですが、いかんせん社内で直接会話したような決定事項に付いて追いつくことができていませんでした。これは創業間もない会社にフルリモートの社員と出勤する社員がいるなかで求めすぎた要件だったかも知れないな。と今では思っています。会社にフルリモートを受け入れるくらい情報格差が生まれない仕組みを作ることができればよかったのですが、ここは少し後悔していますね。
とはいえ、学べることや後悔したこともあり次に活かそう。と考えていたり、自分はどういう組織だと動きやすいのか。と言った点がより言語化もできるような体験もできました。 Asobica
で経験したことを次に活かしたいと思います。
最後に
ネタブログのつもりが割と真面目なことを書いてしまった。。。
平成最後にやること多くて少し中途半端な終わり方ですが今後のこともどこかのタイミングで書いていこうと思います。
bannzai 先生の次回作にご期待下さい。
おしまい(^o^)/
平成最後のライブラリ
平成最後のライブラリ
みなさん今日で平成も終わりですね。というわけで 平成最後のライブラリ を作ったので紹介します。
EraCalculator
EraCalculator というライブラリを作りました。
機能は例えば 平成
をもし他の元号 大化
などで表した時に何年表記になるかを計算してくれる内容になっています。
大化
は645年始まりで 平成
は 1989年始まりなので 1989 - 645 = 1344
ですね。これを 1
足した結果を 大化 1345年
としています。
let converted = EraType.平成.convert(to: EraType.大化) print(converted.eraType) // 大化 print(converted.year) // 1345年 print(converted) // 大化 1345年
なんでこんなの作ったの
アヒージョ作ろうと思ってたら
別の世界線にいる 狂気のマッドサイエンティスト を喜ばせることになりました。
最後に
意外と新しい元号の発表盛り上がりましたね。 完全にこれにあやかったネタライブラリだったのですが、急ピッチで作る感覚がハッカソンみたいで楽しかったです。 これ書いて一つ知れたことは元号めっちゃあるやん。ということでした。興味があれば覗いてください。250個くらいあります。 ここから見れます。
え?需要があるかどうか?無いと思いますよ?何言ってるんですか?
需要は無いでしょうがスターはほしいです。
スターください
おしまい\(^o^)/
🍵を作りました
🍵を作りました
表題の通りOchaを作りました。
この記事ではOchaを紹介したいと思います。
Ochaについて
OchaはSwiftで作ったライブラリです。
しかし、iOS
やmacOS
のライブラリじゃなくてPCで動くプログラムになってます。
Ochaは指定した(1以上の)ファイルの変更を検知するプログラムです。
Ochaでできることはファイルの変更・保存・削除をもとに自分の任意のプログラムを走らせることができる。そういった役割のプログラムです。
たとえばファイル保存した時にインデントを整える。ファイル消した時に Delete file << FILE_PATH >>
の形式のコミットメッセージでgit add
, git commit
する。
といったことの実現を補助するためのライブラリになっています。
使い方
Ochaの使い方を簡単に紹介します。
まず、FileSystemのイベント監視をするためのクラス。 Watcher
クラスを作成します。この時に監視したいファイルパスも渡してあげましょう。
let watcher = Watcher(paths: [pathString])
次にFileSystemのイベントを検知を開始したい時にstart
メソッドを呼んであげましょう。このstart
メソッドの最後の引数のclosure
はイベントを検知した時に実行されます。
watcher.start { (events) in ... }
具体例
上述したような ファイル消した時にDelete file << FILE_PATH >>の形式のコミットメッセージでgit add, git commitする。
を実際に動かしている例をOchaのリポジトリにExampleとして載せています。
Exampleとして書かれているコードを下に載せます。こちらを見てもっと具体的な書き方を把握してみましょう。
import Foundation import Ocha import SwiftShell import PathKit print("You can confirm `Ocha.GitCommitExample` when removed file. Try rm -rf Package.swift and conform git history(e.g git show. You can got new commit for it message of 'Delete file [Package.swift] path'. ") let path = Path( #file.components(separatedBy: "/") .dropLast() // main.swift .dropLast() // GitCommitExample .dropLast() // Sources .joined(separator: "/") ) let pathString = path.absolute().string main.currentdirectory = pathString let watcher = Watcher(paths: [pathString]) watcher.start { (events) in let removedEventPaths = events .filter { $0.flag.contains(.removedFile) } .map { $0.path } removedEventPaths.forEach { path in main.run(bash: "git add \(path)") main.run(bash: "git commit -m \"Delete file \(path)\"") } } RunLoop.current.run()
なんとなく何がやりたいかは読めるのではないかと思います。後半のwatcher.start
の内容を少し整理しながら見ていきましょう。
先程も説明したようにFileSystemを監視したいタイミングでwatcher.start
を呼びます。
次にCLIでrm -f Package.swift
を実行します。この時に消すファイルは Package.swift
である必要はありませんが、Watcher
に渡しているディレクトリ配下である必要があります。ちなみにFinder上からのGUI上からの削除はゴミ箱の移動
扱いになり、削除とはまた違う扱いになるためこのExampleはうまく機能しません。
rm -f Package.swift
を行ったにstart
の最後の引数であるclosure
が実行されます。この時にどのようなイベントが発生したか、どのファイルが対象か。といった情報を詰め込んだ構造体が引数として渡ってきます。このevents
をもとにどういったことを行いたいかを記述していきます。今回だとファイルが削除された場合に
、git add << FILE_PATH >>, git commit -m "Delete file << FILE_PATH >>
を実行をしたいです。
Event
にはflag
があり、これを用いてremovedFile
のイベント対象となったファイルパスを取得しています。
そしてこのファイルパスの配列を用いてgit
コマンドを実行する流れになっています。
モチベーション
Ochaを作ったモチベーションは主にファイル保存時に特定のコードフォーマッタかけたいなあ。かけれたらいいな。
ブログをローカルで書いているときにコミットメッセージはどうでもいいからファイル保存時にコミットとりあえず積んで安心感を得たい。ちょうどいいタイミングでsquash
等を行ってきれいなログにする運用にしたい。などなど思ったのがきっかけでした。
Swift
のライブラリという点では、僕はSwift
を書くEditorとしてXcode
を使っているのですが、Xcode
ではファイルイベントに応じてスクリプトを実行するような機能は用意されていません(僕の知る限りでは)。Compile
の前後等のタイミングでScript
を挟めたりするのですが、このタイミングだとやりたいことに対してタイミングが遅いと感じる場合もあると思います。
そういった課題を感じたためOcha
というライブラリを作りました。
なぜ 🍵 なのか
Watcher(監視者) の響きを日本語にしたときの アナグラム になっています。
うぉっちゃー → おっちゃー → おちゃ
以上。
技術について
Ochaの技術については本ブログでは紹介しません。代わりに(?)Ochaで使用されている技術の解説本を技術書典6で販売します。 SwiftKotlin愛好会というサークルで執筆者の一人としてSwift
でどのようにFileSystemを監視するか。と言ったことをOchaのコードベースに書いていきます。
サークル名: SwiftKotlin愛好会
URL: https://techbookfest.org/event/tbf06/circle/71750003
興味がある方は是非お越しください。複数人での共著なのでSwift・Kotlinネタが他にも載っている一冊となります。
素敵なロゴを描いてもらいました
OchaのREADMEを見るとわかるのですが素敵なロゴが載っています。
井上乃彩 / Noa Inoueさんに描いていただきました。とても可愛くて素敵なロゴをいただきました。見るたびに少し見とれてしまいます。
経緯を話すと Ochaにロゴが欲しい & 最近デザインツールを個人で触っていて他の人はどういう情報を元に作るんだろう。と気になりそれで声をかけて関わっていただきました。本当に素敵で感謝です。
噂のロゴです。
まとめ
Swift
はまだApple
プラットフォーム、特にGUIアプリケーション開発に頻繁に用いられる開発言語と言えるでしょう。
Ochaも実はCocoa
依存なのでmacOS
上でのみ動くコマンドラインツールなのですが、それでも普段開発しているようなiOS
アプリ等の開発とは毛色が違います。今回はFileSystemを監視する。というテーマのライブラリを作りました。Ocha
は単体では機能せず処理内容は自分で記述する必要があります。が、 Ocha自体は小さなライブラリとなっておりExample
もシンプルで比較的応用例も浮かびやすいのかな。と思っています。普段GUIアプリケーションを開発している方でもCLIツール作成して便利なツールを作りたい方はOcha
を利用するのも是非ご検討してください。
このライブラリが便利!最高!クール!ロゴかわいい!と思ったそこの貴方へ
スターください 🍵
おしまい \(^o^)/
connpass で勉強会を主催している皆様へ
connpass で勉強会を主催している皆様へ
connpass で勉強会を主催している皆様へ、運営しているconnpassのグループに対する 参加, キャンセル, お問い合わせ のアクションがあった場合にSlackに通知するGAS(Google Apps Script)を書いてOSSにしたのでご報告申し上げます。
https://github.com/bannzai/connpass-notification
なぜつくったのか
僕はDXELという勉強会の主催をやっており、connpassを使って参加者の募集を行っています。connpassでイベントの運営メンバーだと参加者の 参加・キャンセル・お問い合わせ などのアクションが発生した場合にメールで通知を受け取ることができます。しかし、(僕は)メールってあまり見ないし、connpassのこういった内容はGmailのラベルを付けてGmailからの通知の対象から外してしまっていたりしています。
とはいえ、こういった動きがあった場合状況をなんとなく把握したいな。お問い合わせもSlackのpublicなチャンネルに通知されれば自分ができない場合も誰かが対応してくれるだろう。 そういった要望が内外であったのでconnpass-notificationをつくりました。
connpass-notification
connpass-notification は比較的汎用的に作りました。
なので、connpassで会を主催する方でそれ専用のSlackのworkspaceがある方には使えるツールになっているかと思います。このツールを使いたいモチベーションはおそらく僕と一緒なようなモチベーションを持って導入するのだろうと予想しています。このツールを使える人の前提があります。
Gmail
アドレスを使用してconnpassのアカウントを作っている。Slack
使っている。- イベント専用の
Slack
の workspace があるとなおよし
- イベント専用の
上記が必須条件かと思います。
つけくわえるとするならconnpass-notification は汎用的に使っていると言いましたが、自分たちが使っている Gmail
や Slack
に対する設定を行う必要があります。また、 このツールを実際に稼働させるためにGoogleが提供している clasp というツールも用います。
これらの手順はgithubに手順書としてREADMEに記載があります。
設定に関しては Configureセクション
ツールの稼働に関してはDeployセクション に記載してあります。
こちらを見ながら自分で動かせる人である。そういう人が身の回りにいる。必要があります。
実際に動かしている感じ
下の画像は運営しているイベントへの 参加・キャンセル が発生した場合のSlackです。
この画像は運営しているイベントへの お問い合わせ が発生した場合のSlackです。
絵文字や色についてはEventsで定義してあるのでこちらもカスタマイズしたい場合は自由に変更できます。よくみるとところどころリンクがあるので、仮にユーザーページ見たいな(あまりないとは思うけど)とか、送られてきた Gmail
のリンク開いてメッセージの全文みたいな。ってなった場合は比較的楽にアクセスできると思います。本文を流すことも考えたのですが、最初はコンパクトな通知で運用していこうと思ってこうしています。課題に感じたら本文も流そうかと。
DXELでの運用形式
設定
READMEのConfigureを見るとわかるのですが、設定ファイルに各アクション(参加・キャンセル・お問い合わせ)に対してそれぞれ別のChannelに通知ができるような設定ファイルになっています。もちろん同じチャンネルにも通知ができます。
function settings(): _Settings { return { 'appName': 'Gmail', 'searchWord': 'from: no-reply@connpass.com', 'registerWebHookURL': 'https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ', 'registerNotificationChannel': '#registerOrCancel-channel', 'cancelWebHookURL': 'https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ', 'cancelNotificationChannel': '#registerOrCancel-channel', 'contactWebHookURL': 'https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ', 'contactNotificationChannel': '#contact-channel' }
registerXXXX
・cancelXXXX
・contactXXXX
がそれぞれ 参加・キャンセル・お問い合わせ に対応しています。
別チャンネルにした場合は個別に WebHook URL を用意したりすればおkです。
DXELではお問い合わせだけは別チャンネルにしています。 参加・キャンセルはそんなに重要じゃないというかなんとなく流れて把握できればいいな。とは思うのですが、お問い合わせは見逃しにくい状態が好ましいなと思い(僕が勝手に)そうしました。お問い合わせは公開日に一気に登録や開催前にキャンセルが発生する傾向にあるわけでもないので、自分の未読管理もしやすく専用チャンネルによってメンバーもそこには注目しやすくなるはずです。
自動化
connpass-notification は Google Apps Script(GAS)
で作成しました。 細かく言うなら clasp
で typescript
を使用して作ったものを gs
に変換して使っているといった具合です。 GAS
には一定間隔で定期実行してくれる設定があるのでWebページからその設定を行います。DXEL では無料プランの枠に留まる数分程度の間隔で適当にやっているのでリアルタイムの通知とまでいえるほどの頻度では実行はしていないです。 とはいえ、普段よく使っている Slack
に自動で流れてるのはとても嬉しいですね。
注意点
connpass-notification の細かい注意点として Slack
に通知された Gmail
のメール(正確にはスレッド)は既読状態にしています。
つまり、たとえば Gmail
のサービスでメールを実際開いてなくても Slack
に通知されたあとだとすでに読んだ状態になっているので未読のものでフィルタリングとかかけている場合はひっかからなくなります。
connpass-notification では、等間隔で定期実行するユースケースを想定して設計してあります。 通知までの原理は単純でGmail
の検索にひっかかったものを Slack
に通知します。その場合に前回通知したものからの差分で更新ということができたら理想なのですが、やれるかどうかいまいちわからなかったので、メールの既読・未読で判断することにしています。 未読のものは通知する必要があって、既読のものは通知がする必要がない。と言った判断基準にしています。
何かいい案(というかそういう機能がある)場合は GitHub
の issue
や、 bannzai のTwitterアカウントとかにでも連絡していただけると嬉しいです。
最後に
connpass-notification は DXEL でも使い始めたばかりです。実際良かったよ。と言った話はまだできないのですが、同じような要望がある方はぜひ使ってください。
PR・issue 等もお待ちしております。
僕が一番欲しいのはスターなので、スターください
おしまい \(^o^)/
gqlgenでTypeにプロパティを追加してみよう
gqlgenでTypeにプロパティを追加してみよう
前回ではgqlgenでサーバーをlocalhostに立ち上げて、GraphQL Playgroundから実際に Query
が実行されるところまで確認できました。
今回は一度コード生成された後にGraphQLのインタフェースを変えたい場合どう実装していくのか書いていこうと思います。
gqlgen
は Schema first でGraphQLなAPIを作るためのライブラリです。
schema.grpahql
を編集してGo
のコードを再生成するところまで確認していきましょう。
前回
まず前回までのまとめなのですが、下記のQueryを実行すると Todo.id
の一覧が取得できたことまで確認しました。
Query
query { todos { id } }
Response
{ "data": { "todos": [ { "id": "1" }, { "id": "2" }, { "id": "3" } ] } }
今回はこの Todo
に title
というプロパティを足していきたいと思います。
schema.graphqlの編集
初めに schema.graphql
を編集していきましょう。今回は Todo
にプロパティを追加していくので下記のスキームに注目します。
type Todo { id: ID! text: String! done: Boolean! user: User! }
上の type Todo
から始まるものはレスポンスの形式を表しています。 ID!
型の id
や String!
型の text
というプロパティがあるといった具合ですね。これは gqlgen generate
の後に models_gen.go
にコードが吐き出されます。
今のままの Todo
では id,text,done,user
の4つのフィールドはレスポンスとして返せますが title
は返すことができません。title
を返せるようにするためにまず schema.graphql
を編集して Todo
に title
を追加しましょう。
type Todo { id: ID! text: String! done: Boolean! user: User! title: String! # ここが追加 }
Scehma first
を謳っているgqlgen
ではスキーマファイルと実装するGraphQL
のインtらフェースが合うように開発を進めていきます。
先ほど、titlte: String!
の部分を追加しました。続いてこのschema
の情報をGo
のコードに反映させていきます。
Goのコードを生成する
前回ではgqlgen init
した結果、ExmapleのGo
のコードが作成されました。
追加したフィールドをGo
に反映させたい場合はgqlgen generate
を実行します。
$ gqlgen generate
ちなみに短縮して gqlgen
とだけ打って実行しても構いません。
$ gqlgen
実行後 generated.go
, models_gen.go
が変更されていれば成功です。
特に models_gen.go
の中身を確認してみましょう。
Todo
に Title
というプロパティが追加されていることが確認できると思います。
type Todo struct { ID string `json:"id"` Text string `json:"text"` Done bool `json:"done"` User User `json:"user"` Title string `json:"title"` }
次に前回と同様にresolver.go
の Todos
メソッドを編集していきましょう。
func (r *queryResolver) Todos(ctx context.Context) ([]Todo, error) { return []Todo{ Todo{ ID: "1", Title: "First", }, Todo{ ID: "2", Title: "Second", }, Todo{ ID: "3", Title: "Third", }, }, nil }
これで完了です。GraphQL Playgroundから結果を確認してみましょう。
$ go run ./server/server.go
サーバーが立ち上がったあら下記のQueryを貼り付けて実行してみましょう。
{ todos { id title } }
{ "data": { "todos": [ { "id": "1", "title": "First" }, { "id": "2", "title": "Second" }, { "id": "3", "title": "Third" } ] } }
画面はこのような具合になっていると思います。
終わりに
今回はプロパティの追加するというユースケースを通して gqlgen
の機能を使い Schema first
で実装をしていきました。
GitHubにここまでの内容を公開しています。
https://github.com/bannzai/gqlgen-demo
branchは fix/add/field
となっています。前回からの差分としてPRを一つ作ってあります。
https://github.com/bannzai/gqlgen-demo/pull/2
この記事がいいと思ったら、GitHubのスターください
おしまい \(^o^)/
gqlgenでGraphQLサーバーを立ててみる
gqlgenとは
gqlgenとはGraphQLのSchemaベースでGraphQLサーバーの開発を進めるためのライブラリです。最近ではでmercariがmercari tech conf 2018のサーバーのプログラムをGraphQLで書いていて、「お」と目を見張りました。今回はそんな gqlgen の導入部分を記載していきたいと思います
なおGraphQL自体についてはこの記事では割愛します。
GraphQLについて知りたい方は公式のページがあるのでこちらをご覧いただければと
本題に入る前に
導入部分を書く前にこの記事を書いた時点でのgqlgenの情報を載せておきます。
この記事を書く時点での最新のtree
この記事を書く時点での公式のドキュメント
本題
最新のドキュメントはここから確認できます。本記事でもこちらを参考にしながら話を進めます。が、多少割愛してまずはGraphQLとして機能するサーバーを立ち上げることを目標にします。Getting Startedをまず見ていきましょう。
まずライブラリのインストールです。 dep
等のパッケージマネージャーを使っている人は適宜変えてください。
$ go get -u github.com/99designs/gqlgen github.com/vektah/gorunpkg
さて、インストールが終わったら gqlgen init を実行してしまいましょう。あらかじめ用意しておいてGitリポジトリを使っている前提で git status
でどんなファイルができたか確認します。
$ gqlgen init Exec "go run ./server/server.go" to start GraphQL server $ git status On branch master Your branch is up to date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) generated.go gqlgen.yml models_gen.go resolver.go schema.graphql server/
gqlgen initの実行により下記のファイルたちが作られました。 それぞれの役割を簡単に記述していきます。
- schema.graphql
- generated.go
gqlgen generate
でこのファイルの中にGraphQLの処理に必要な処理が吐かれるschema.graphql
で記載したスキーマ情報やそれに沿ったResolver
やType
の情報
- gqlgen.yml
gqlgen generate
の際にプロダクションによってカスタマイズしたい場合に記載する設定ファイル- 何が設定できるかはここを参照
- models_gen.go
gqlgen generate
の際にGraphQLのType
等をGolang
のstruct
が書かれるschema.graphql
に記載されたものからコードが作られるResolver
以外のものがここに吐き出されると思ってもらえたらいいかも。Type
,Input
,Scalar
,Enum
and so on...
- resolver.go
gqlgen generate
の際にGraphQLのQuery
やMutation
の処理を書くためのResolver
が用意される。Resolver
は各Query(or Mutation)
を処理するためのメソッドを持っている。それを処理する役割と捉えてもらえると。他のフレームワークやライブラリでもこの用途でResolver
という名前で出てくる。Type
が 1つ以上のfieldを持つ場合もここに吐き出される。
- server/server.go
go run ./server/server.go
でサーバーを試せるようになっている
さて、これで実はデモを試す最低限の準備はできてしまいました。
gqlgen init
の時点でExampleに必要なSchemaやそれに沿ったGolangのコードが生成されています。
Todoという例でドキュメントには書かれています。今の状態でこれと同じものができています。便利。
ではローカルホストにサーバーを立ち上げ、 http:localhost:8080
にアクセスします。
$ go run ./server/server.go
下記のようなページが立ち上がれば成功です。
これはGraphQL PlaygroundをCDNを利用して立ち上げています。GraphQL PlaygroundはGraphQL IDE
という立ち位置みたいですね。このツールでQueryをインタラクティブに確認することができます。
というわけで下記のQueryを書いて動作を確認してみます。
query { todos { id } }
結果がjsonで帰ってきたのが右側の画面を見て確認できると思います。
しかし、実行してみると何やらエラーが出ています。エラーが起きずに正しくデータが取得できている場合はdata
の項目にtodos
の結果が返ってきて、errors
の方はフィールド自体が存在しないはずです。
なぜエラーが返ってきたのかなのですが、gqlgenではQueryを処理する役割のResolverのコードが生成された時点ではpanic
を呼ぶコードが埋め込まれています。当たり前のことなのですが、GraphQL
のインタフェースを通った後の内部の処理はその都度書く必要が出てきます。gqlgen
ではコード生成されたタイミングで下記のようなテンプレなコードが埋め込まれています。これは resolver.go
を見て確認することができます。
func (r *queryResolver) Todos(ctx context.Context) ([]Todo, error) { panic("not implemented") }
では、ここに[]Todo
型の値を返すようにコードを下記のように変更してあげましょう。
func (r *queryResolver) Todos(ctx context.Context) ([]Todo, error) { return []Todo{Todo{ID: "1"}, Todo{ID: "2"}, Todo{ID: "3"}}, nil }
雑ですが、配列で3つの要素を返してあげています。
$ go run ./server/server.go
を再度実行してみて動作を確認してみましょう。先ほど遠同じQueryを投げてみます。
下記のように表示されていれば成功です。
終わりに
これで gqlgen
を導入して GraphQLサーバーを立ち上げるところまでできました。次回は実際にschema.grpahqlを編集してgqlgen generate
でコード生成をするといったことも書けたらと思っています。
GitHubにここまでの内容を公開しています。
https://github.com/bannzai/gqlgen-demo
branchは introduction/gqlgen
となっています
https://github.com/bannzai/gqlgen-demo/tree/introduction/gqlgen
この記事がいいと思ったら、GitHubのスターください
おしまい \(^o^)/