GraphQL と Apollo Client / Server を学ぶためにやったこと
GraphQL と Apollo Client / Server を学んだので何をしたかを書いておく。
GraphQL
読んだ本
最初に「初めての GraphQL」で概要を掴んだ。ちなみにこの本は Apollo Client / Server についても書かれている。
併せて、設計パターンや実際の開発で課題となるテーマを把握した。(最初は気づかなかったが、設計ガイドは一部が「初めての GraphQL」 の付録にもなっている)
実装
「初めてのGraphQL」には簡単なWeb アプリを開発するチュートリアルがあるので、それを写経した。多分不完全。
GitHub - pokuwagata/photo-share-api
感想
- GraphQL + TypeScript はフロントとバックエンドの分業に良さそう。ただし適切なschema の設計と継続的な改善が必要で、経験がないと辛いことも多そう。
- クエリの書き方をよく忘れる
Apollo Client / Server
GraphQL の実装として、Apollo Client / Server がデファクトらしいので GraphQL を学ぶなら Apollo も必須となる。
読んだ本 / ドキュメント
Apollo については「初めての GraphQL」で概要は掴んだが、実際に手を動かすときに公式のドキュメントを参照することが多かった。
apollo-tooling は個人的に苦手な codegen という schema と クエリから TypeScript の型定義を生成するコマンドと格闘したためよく読んだ。
実装
既存のポートフォリオに無理やり BFF 層を追加して、一部のリクエストを GraphQL に置換してみた。logging も少し試した。
0 → 1 を少しやってみたかったので所謂 todo-mvc を 実装しようとした。単純に全てのリクエストを Apollo Server で処理するだけだとあまり面白くないので、 apollo-client で local state managemet を試してみた。
Client / Server の両方で schema を定義して TypeScript の型定義を生成して... という流れを経験できた。そして apollo-client の local state management は辛いという結論に達して挫折した。
現状 apollo-client で local state management するのは時期尚早感あるのかな...
— メロン (@yn2011) 2020年5月2日
- apollo-client-devtools が client schema 対応してない(と思う)
- apollo-codegen は local resolver の型定義生成しない
あと Graph Manager というサービスも触ってみた。課金しないと全然試せることが少ないけど、本番運用するなら必須の機能が簡単に使えるっぽい。
Graph Manager 触ってみた pic.twitter.com/Qh0hljYz6e
— メロン (@yn2011) 2020年4月5日
感想
- 実際に手を動かすと関連する ライブラリ が色々見つかり最初辛い。
graphql-code-generator は TypeScript 使うならほぼ必須。linter は linter としての機能というより error が分かるのが嬉しい。VSCode をちゃんと設定すればエディター上でも分かるようになるんだろうか。
graphql-modules は良さそうだけど、設計がこの ライブラリ にロックインされそうな印象がある。
graphql-config は使っていないが、GraphQL 関連のライブラリとかエディタ毎に設定ファイルを独立して書かなきゃいけない傾向があり、辛いので一括で管理できるようにしてくれるっぽい。確かに設定ファイルどんどん増えてくるのは分かる。
schema と 型定義の自動生成により、関数型プログラミングのスタイルで開発できる。
React の Component に GraphQL のクエリを紐付けて管理するのはコンポーネント指向感あって良い。ただし複雑な Web アプリケーションだと色々辛い部分もあるんだろうな...
正直 GraphQL の導入は Apollo Server の実装よりもフロント側の方が考えなきゃいけないことが沢山あって大変そうという気持ちになった(まあ今回のサーバー側は REST API の中継しかしてないからかもしれないけど...)
AtCoder Beginner Contest に参加し始めた
AtCoder が毎週開催している AtCoder Beginner Contest (以下ABC)に参加するようになって 1ヶ月程度経ったので何かその辺りのことを書いておく。
今の成績
Rating 132 の灰色
なぜやるか
- 新しい趣味が欲しかった
- 実装力の強化
- 有給消化 + GW で25連休中のため比較的時間がある*1
始める前の実力
コンテストに関係しそうなやつだと
- 競技プログラミング未経験
- 高校数学は大体分かる(ただし整数問題は分からない*2)、大学の数学はほぼ忘れた
- 電子・情報系の学部にいた。ただしコンピュータ・サイエンスはそんなに身に付いていない*3
- 計算量・ビッグオー記法の概念・数学的な定義は何となく分かる
- 業務でコード書くエンジニアとしての経験は3年ぐらい
ABC 初参加前にやったこと
- AtCoder に限らず、所謂競技プログラミングは C++ が主流とのことだったので、まずは C++ の環境構築と学習から始めた(ちなみに、この選択は正しくて、ほぼ全てのAtCoder 関連の記事・解説放送、書籍は C++ を前提にしているので C++ やったことなくても学習した方が絶対効率よく学べる)
環境構築
VSCode の場合について書く。以下が揃えば良い感じに C++ でコンテストに参加できる。
- 拡張のインストール
code-runner (C++17 実行) の settings.json
"code-runner.executorMap": { "cpp": "cd $dir && g++ -std=c++1z $fileName && ./a.out", },
<bits/stdc++.h>
を利用可能にする- C++ の標準ライブラリが大体使えるようになるので便利(というかほぼ必須)
- Visual studio codeで競プロ環境構築[mac OS] を参考にする。ちょっと面倒くさい。
標準入力/外部ファイルから入力を受け付けてデバッグを行えるようにする
- vscodeでstdinを扱える環境構築を参考にする。work around 感は強い。
-
- コンテスト用のディレクトリの作成/テスト実行/提出 が可能(たまに動作しない場合もあるけど...)
- コンテスト参加時や過去問を解く時に便利
AOJ ITP1 を解いた
自分の場合は C++ をまったく知らなかったので、レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編:競プロを始めよう】 でオススメされている通りに AOJ の ITP1コースを解いて練習しておくことにした。
愚直に9割ぐらい解いたんですが、注意点としては
- 解答例は C++14 or 17 を見るようにする (標準ライブラリに慣れる)
- ある程度プログラミング経験がある場合は全部やらなくていいと思う。 とりあえずA,B 問題に取り組んで解説放送聞いたり提出されたコードを読んだほうが実践的かも
- ITP1 では標準入力の受け取りに慣れるのが1番大事かも
ABCに初めて参加した
自分はこの時点でA, B 問題までは解けた。コンテスト自体の知識は参加して覚えたほうが早い。(提出方法、問題の形式、誤答するとペナルティが発生する等)
スニペットを用意した
ABC の解説放送のライブコーディングで使われているスニペットを参考にした。自分の場合は start
とタイプすると以下が挿入されるように設定している。
"start-template": { "prefix": "start-template", "body": [ "#include <bits/stdc++.h>", "#define rep(i,n) for(int i=0; i < (n); i++)", "#define lower(s) transform(s.begin(), s.end(), s.begin(), ::tolower)", "using namespace std;", "using ll = long long;", "", "int main() {", " $0", " return 0;", "}" ], "description": "basic" },
いちいちテンプレートファイルを準備して問題毎にコピーして新しく書き始めるよりも早いと思う。
コンテストで学んだこと
主に数値の取り扱い。Webアプリケーションを書いているだけだと意識することが少ない(気がする)
でもコンテストでは必須の知識だと思う。(A, B 問題でそこを狙ってくるテストケースや問題設定が多いので)
- int (符号付き32bit 整数) の最大値は 231 -1 で、大体 2.14 * 109 で 、10桁
- long int (符号付き64bit 整数)の最大値は 263 -1 で、大体 9.22 * 1018 で 、19桁
- 除算は小数部切り捨て(例 5/2 = 2)
- 切り上げする場合は
(a+b-1) / b
→説明
- 切り上げする場合は
- 最終的な計算結果はオーバーフローしなくても計算途中の評価がオーバーフローすると駄目(例
a * b - c
でa * b
がオーバーフロー)
あと、AtCoder のコンテストで C++ で解答する場合は計算機の性能は大体 108 step / sec ぐらいと想定すると良いみたいです。(例えば O(N) でも 1018 step だと 2sec 以内には絶対に収まらない)
今やっていること
週に4時間もコンテスト関連には時間使えていないと思う。土日にコンテストに参加して次のコンテストまでに解説放送聞いて実装してみたりぐらいが限界。
ABC に参加する
忘れない限りは毎週参加している。C, D問題は実戦で学ぶ感じになっている。C問題は慣れれば解けるようになってくる印象。実はそんなに高度なことを要求していないことが多い。
解説放送を聞く
神コンテンツ。これがなければ ABC 止めてたかも。模範解答自体はコンテスト終了と同時に公開されるが、大抵読んでも理解に時間がかかるか何も得られないので、最近は始めから解説放送を聞いている。(これは自分の読解力の問題もある)
D 問題以降は正直ちゃんとアルゴリズム等の実装経験積まないと対応できないことが明らかなんだけど、それをする時間をまとめて取れなさそうなので 解説放送に出てきたものから順に学んでいこうかと思っている。まあいつかは D で要求される範囲全部カバーできるようになるんじゃないかな...
今後の目標
- コンテストに参加し続ける(後5回ぐらい参加で茶色になりそう)
- C, D 問題の正答率を上げる
- 楽しむ
VSCode で Go を書くための環境構築
環境
ゴール
- 高速な補完、フォーマット、シンタックスハイライトが VSCode で動作する
- vim-go の
:GoImport
のようにモジュールを選択して import できる - VSCode でデバッグできる(標準入力を伴う場合は入力した上でデバッグしたい)
手順
- VSCode にmicrosoft/vscode-goをインストールする
- (gopls がローカルにインストールされていない場合は)コマンドパレットから
Go: Install/Update tools
で gopls を選択 settings.json
のgo.useLanguageServe
を true に設定する- フォーマットはデフォルトが
goreturns
だが、変更する場合はsettings.json
のgo.formatTool
に値を設定する
これで標準入力を伴うデバッグ以外のゴールは達成。めちゃくちゃ簡単だ...
標準入力を伴うデバッグ
これはデバッグに使用する delve
が標準入力に対応していないので vscode-go でも対応できないとのことだが、ワークアラウンドが共有されていた。(Cannot debug programs which read from STDIN )
追加する内容はこのコメント参照
tasks.json
にdelve
を起動するタスクを追加するlaunch.json
に設定を追加し、起動済みのdelve
に attachしてデバッグができるようにする
以上を行うと、デバッグ前に1度タスクを実行するという手間は必要ではあるものの、デバッグ開始後に標準入力を受け付けるようになる。
その他
vscode-go で gopls が正しく動かないと思っていたらコードに package main とか宣言がないと動かない仕様だった。。 Go を書くのが久しぶりすぎて宣言忘れていたのも悪いが何かエラーを出して欲しい。そしてログをどこかに出力して欲しい...
— メロン (@yn2011) 2020年4月15日
こんなハマり方をする人はいないかもしれないが、注意しましょう。
ちなみにログがないと言っていましたが、ちゃんと出力されていました。( mac なら Library/Application\ Support/Code/logs/
配下)
あと、自分は Go なら Vim で書けばいいと思っていた派なんですが、フロントエンドは VSCode が圧倒的に向いているし、並行してバックエンドを書きたい場合もあるので VSCode でいいかなという気持ちになりました。
日々の健康状態を記録する CLI ツールを Go で書いた
多分 go get
すれば動くと思う
DEMO
目的
- 「世界一のプロゲーマーがやっている 努力2.0」を読んだ感想 に書いた「自分が無理をしていないか、常にモニターする」をやりたいな、と思った
- ノートに書くよりは データの方が集計とか楽だし、CLI なら毎日入力するために他の何かのツールと繋ぎ合わせやすいかなあ(例えば Alfred とか...)と思ったので作った
- それと次の職場で Go が使われているので、復習がてら素振りをしておきたい
機能
- 質問をする。答えを csv ファイルに書き込む。
- 日付指定して質問に答えることもできる。入力を忘れても次の日に挽回可能
- 質問は json ファイルで任意に定義できる。答えのデータ型と範囲(最小と最大)も定義できるのでバリデーションチェック可能(ここは少し頑張った)
感想
Rictyのバッククォート`が隣接する文字と重なる問題を解決したメモ
環境
- mac OS 10.14.6
問題
- スクリーンショットを撮るのを忘れていたが、`が隣の文字と重なってしまっていた(`uがúみたいな感じになる)
- markdownや文字列リテラルでバッククォートはよく使うんだけど、その度にこれが起きていて微妙な気持ちになっていた
解決策
- Rictyのバッククオートを修正する
- 多分簡単には直らないんじゃないかなと思っていたが、重い腰を上げてググってみたらすぐに解決方法が見つかった上にすぐ直った
FontForgeのインストール
スクリプト実行
- 上の記事のコメント欄のスクリプトを保存
./script.sh ~/Library/Fonts/RictyDiminished-Regular.ttf
(ファイル名は修正したいフォントに合わせる)- ちなみに、VSCodeのフォントで使っている場合は、1度workspaceを開き直さないと表示が変になった
やっぱり気になったことはスルーしないで解決していく姿勢が大事ですね...(案外すぐ直ることも多い)
「勝ち続ける意志力 世界一プロ・ゲーマーの「仕事術」」を読んだ感想
前回の記事に続き、プロゲーマー本シリーズ。今回は勝ち続ける意志力 世界一プロ・ゲーマーの「仕事術」を読んだので感想を書く。最近、自分語りの投稿が増えているのはリモートワークが続いていることと何か関係あるのかもしれない。
成長が目的
- ときど氏が「ゲームを通じた交流」をモチベーションにしていたのに対して、梅原氏は「自身の成長と人生の充実」こそが目的であるとしているのが対照的
お金が目的の人にとっては、効率の悪い努力とか、荒波に揉まれる経験は必要ないのかもしれない。お金さえ手に入れば、自分自身の成長などなくても満足なのだから。
梅原大吾. 勝ち続ける意志力 世界一プロ・ゲーマーの「仕事術」 (小学館101新書) (Japanese Edition) (Kindle の位置No.972-974). 小学館. Kindle 版.
僕はゲームを楽しみたいとか、ゲームで勝ちたいとか、その程度の気持ちではなく、もう少し別の次元で物事を考えている。やはり、ゲームはあくまでもゲームで、本当の目的は自分自身の成長にある。だから、あえて暗くて険しい道を行く。
(Kindle の位置No.1063-1065). 小学館. Kindle 版.
ゲームを通して自分が成長し、ひいては人生を充実させる。いまは、そのために頑張っているんだ、と。
(Kindle の位置No.1646). 小学館. Kindle 版.
何度か書いてきたことだが、いまの僕は日々の成長、継続に喜びを感じている。そうやって毎日、一歩一歩進んでいる。
(Kindle の位置No.1526-1527). 小学館. Kindle 版.
目標と目的の違い
大会で勝つこと自体を目的にするとろくなことはない。少なくとも僕の場合、結果だけを求めて出場した大会で良い成績を残せたことはない
(Kindle の位置No.1634-1635). 小学館. Kindle 版.
大会というのは、日々の練習を楽しんでいる人間、自分の成長を追求している人間が、遊びというか、お披露目の感覚で出るものではないだろうか。大会における勝利は目標のひとつとしてはいいかもしれないが、目的であってはいけない
(Kindle の位置No.1642-1645). 小学館. Kindle 版.
- 受験、資格試験、転職なんかにも言えそう。それは目標なのか?目的なのか?
- 受験(入学)や転職(入社)は目的化してはいけないものの典型だろうなという実感がある
- 自分も大学受験(入学)は完全に目的化していて、大学生活で何をしたい・どう過ごしたい等は全然想像していなかった...
- 本当は、自分の興味関心を追求する勉強の通過点であるべきなんだろう
勝っても喜ばず、負けても落ち込まない。結果はあくまでも結果で、自分にとってはもっと大事なことがあるから、どちらにせよすぐ忘れる。
(Kindle の位置No.1812-1813). 小学館. Kindle 版.
何かを目標に、ある一定の時期だけ頑張っていると、目標がすべてになってしまう。そして、目標を達成できなかったときに立ち直れなくなってしまう。
(Kindle の位置No.1862-1863). 小学館. Kindle 版.
- 梅原氏は、自分のモチベーションが低下して何もしたくなくなることに対する恐れみたいなものを持っている印象
- 自分も勝ち負けに拘らず、求道者といった感じの生き方を志向していきたい(とはいえ、梅原氏は「飽きるほど勝ってみないとこの感覚は分からないかもしれない」とも講演で話している)
基礎を学ぶ
何かを身につけたいと思うのであれば、丁寧に、慎重に、基本を学ぶべきだ。下手なうちから独自の取り組み方をしたり、自由に伸び伸び練習したりすると、最終的に底の浅い仕上がりになってしまう。少なくとも2年、あるいは3年、基礎を学ぶ必要がある。自分の我を通すことなく、セオリックなことを学ぶべきだと考えている。
(Kindle の位置No.1216-1219). 小学館. Kindle 版.
- ときど氏が「世界一のプロゲーマーがやっている 努力2.0」でも同じことを書いていた。"丁寧に・慎重に"という部分が印象的。
- 麻雀は2年ぐらいはまったく成果が出ていなかったそうで、さらっと2年とか書くけど成果でないまま2年は相当辛いと思うので凄い。
- 例えば目立った成果がない状態のままで、競技プログラミングを2年続けられるかと想像すると...
継続
毎日、60の幸せを手にするため、作業しているとき以外は逆に自信を持って休むことが大切だ。明日の英気を養うことも、継続的な努力の内なのだから。時間を費やすことだけで努力している気になる人が多いが、限界を超えて打ち込んでも成果は上がらない。1日6時間なら6時間、3時間なら3時間と時間を決めて、集中する方がいい。そして後は自信を持って休む
(Kindle の位置No.1845-1849). 小学館. Kindle 版.
- これも「世界一のプロゲーマーがやっている 努力2.0」と類似の内容で、ON/OFFの重要性はやっぱり普遍的なんだろうな
嫌悪感
だけど正直、みんなから孤立してゲームを追求するというのは、なかなかどうして辛かった。しかし、ゲームが好きという気持ちを裏切ることはできなかった。
(Kindle の位置No.269-271). 小学館. Kindle 版.
中学卒業のとき、高校卒業のとき、進学先や就職先を決めていく同級生を見ながら、ゲームしかない自分への嫌悪感を拭うことができなかった。
(Kindle の位置No.1440-1442). 小学館. Kindle 版.
- 梅原氏も当然に1人の人間なんだと思わせる一節
- 自分もプログラミングは好きだと思うが、やはり他者と自分を比較して、嫌悪感とまでは言わないが、孤立感や、本当に自分はこれでいいのか?と自問自答して憂鬱になったりといった経験はある
- しかし、プロゲーマーになった後の梅原氏は、ゲームしかない自分が世間から認められることで自身を肯定できるようになったとのこと
- 自分は何か世間から認められているというわけでもないけど、最近は自分の生き方を他者と比べるようなことはあまりしなくなった。結局、人間はその人らしく生きることしかできないし、それが1番幸せなのかなと思っている