生涯未熟

生涯未熟

プログラミングをちょこちょこと。

GraphQLを勉強したのでGolangで書いてみた

ここ最近とてもGraphQLが盛り上がってますね! イベントも続々と開催されていたりするので、勢いを感じています。

そんなGraphQLを遅まきながら勉強してみました。

GraphQLとは?

既に様々な記事で論じられている内容なので割愛します。

この記事が個人的に一番分かりやすかったです。

qiita.com

実装してみよう!

それでは早速実装してみます。

今回はGolangを使い、サーバサイド側の実装を行います。

ライブラリ

ライブラリとしては以下を使いました。

github.com

こちらとも迷ったのですが、今回はStar数の多い方を使いました。

github.com

あとは、簡単にDBを使いたかったためSQLXを使用しました。

github.com

コード

実装してみたものは以下になります。

github.com

慌てて作ったものになるので、汚いですが一応動きます!

コード内でキモとなる部分は以下です。

  • schemaの定義
var queryType = graphql.NewObject(
    graphql.ObjectConfig {
        Name: "Query",
        Fields: graphql.Fields {
            "user": &graphql.Field {
                Type: userType,
                Args: graphql.FieldConfigArgument {
                    "id": &graphql.ArgumentConfig {
                        Type: graphql.String,
                    },
                },
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    idQuery, isOK := p.Args["id"].(string)
                    if isOK {
                        var u = user{}
                        err := DB.Get(&u, "SELECT * FROM user WHERE id=$1", idQuery)
                        if err != nil {
                            return nil, nil
                        }
                        return &u, nil
                    }

                    return nil, nil
                },
            },
        },
    },
)

ちょっと波動拳なコードになってしまっていますが、ここでschemaを定義しています。

今回は簡単な user のデータを返すschemaになります。

Queryとして userid を指定してもらい、それに対して resolve 、何を返すか?というのを指定してます。

そこで、実際にDBを照らし合わせてみて結果を返しています。

やってみて

結構記述量が多くなるので、実際にRESTfulなAPIからの書き換えになると大変だなーという小並感。

ただ、やるメリットは多大だと思うので積極的に使ってみたいですね!

goaのGraphQLバージョンとかあれば面白いな、とふと思ってみたり。

という感じで中身の薄い記事ですが、やってみた現場からは以上です!

僕の心と他人の心

本日付で勤めていた会社を退職致しました。

会社を含めた周りは悪くなく、全ては自分が原因です。

2ヶ月ほど休職していたのですが、その間に「僕という人間は何がダメで今後どのように向き合えば良いのか?」ということを連々と考えたりしましたので、心の整理をつけるためにも駄文ですが書き綴りたいと思います。

言葉の裏が読めない幼少期

僕は小さい頃、少しおかしな人間でした。

どのようにおかしかったかというと、人が発する言葉の裏が全く読めない人間だったのです。

例えば、近所に仲の良かったお兄ちゃんがいたのですが、その人が冗談で牛乳瓶に泥水を入れた状態で「コーヒー牛乳やで!」と手渡してきました。

色もコーヒー牛乳とは違っていたので、普通だと「そんなわけないじゃん!」とツッコみを入れるところですが、言葉の裏が読めなかった僕は「あ、こういう色のコーヒー牛乳があるのか」と疑いもせず飲もうとしました。

慌ててお兄ちゃんが止めに入りましたが、当時の僕はそのくらい人の発する言葉を鵜呑みにする人間でした。

言葉には裏があると知る

その後、幸いにも周りの人に恵まれ、成長を重ねる毎に人の心というものを学んでいき「言葉はそのままの意味を受け取らず、裏の意図を読む」ということを覚えました。

この概念を覚えたことにより、僕の生活はとても過ごしやすくなりました。

いや、過ごしやすくなったと錯覚していました。

裏を読むことで僕は爆死した

社会に組み込まれる人間になり、裏を読むことを常に要求されるようになりました。

言葉の裏を読むということはとても疲れる作業です。

僕は段々と疲弊していきました。

「もしかしたらこの人は僕をダメな人間と言っているのではないか?」

「この人は僕のことを嫌っているのではないか?」

常にネガティブな妄想が頭をよぎるようになり、つい2ヶ月前にこの数年間溜まっていたものが噴出してしまいました。

本音で向き合う

休職し、暗闇の中で僕は何が悪かったのか?を自問自答する日々を過ごしました。

時には辛くなり、刺身包丁を手に取る夜もありました。

しかし、僕は気付いたのです。

いつの間にか、言葉の裏に惑わされて自分の本音をぶつけ、他人の本音をぶつけられるということの大切さを綺麗さっぱり忘れていることに。

本音を自分の中にしまい込み、他人と本音でぶつかり合うということを無意識に避けるようになっていることに。

これから

今後は多少パワーを使うことになろうとも、他者と気が済むまで本音でぶつかり合ってみようと思います。

ぶつかってみた結果、後味が悪いことになるかもしれません、それか本当の意味での信頼が生まれるかもしれません。

実践することによりどうなるか結果は全く分かりませんが、自分の経験値となることを信じてやっていきたいです。

その他気付いたこと

  • 休職中の保険料を払わないといけないので余裕のある資金を持っていたほうが良い
  • 部屋にずっといるとネガティブな考えも沸き起こってくるので、なるたけ外に出る
  • せっかくの休養なのでとことん自分自身と向き合って、自分にとって何が許せなくて何がしたいのか?を発見すること
  • 休職中だからといって頑張ってはいけない、休むことに徹する
  • うつ病になると周りの人間が全員敵に見える、すれ違う人にも恐怖心を覚えた時は我ながらビックリした
  • 本当に悪い人間なんて一握りもいない

goroutine使ってゴニョゴニョするCLIツールを作った時の備忘録

備忘録として自分用に書きます。

cobra良いよ

以前までurfave/cli使ってたんですが、「dockerのcliとかcobra使ってたよな〜」とよくcobra見かけるようになったので使ってみた。

$ cobra initでアプリケーションの土台作ってくれるので、煩わしいこと考えずにサクッと開発に入れて良い。

あとは、urfave/cliよりも細かく挙動の管理が出来そう(未検証)。

またエラー時などにカスタマイズした標準出力する場合は、SilenceUsageSilenceErrorsをやっといたら吉。

きちんとデザインパターン使ってみた

結城浩さんのデザパタ本を読み終わったので早速デザパタを取り入れてみた。

Goの場合、こちらのリポジトリに実装例がまとまってるので読むと得るものが多い。

github.com

雑にgoroutine回した時の注意

雑に大量のスレッド作成した時にpanic等で落ちると、大量のログが吐かれて元のエラー内容が確認できない場合があるので、

$ go run main.go 2>hoge.txt

とかでファイルに吐いてあげると良い。

複数のgoroutineから同一mapを参照すると死

エラーで死。1.6からエラー吐いてくれるようになったらしい。

排他制御やるか、channelとWaitGroup使って後からまとめてmapに代入したりするべし。

プログレスバー

CLIツールでプログレスバーを実装する場合、cheggaaa/pbが簡単。

見た目が気に入らない場合はbriandowns/spinnerとか使うと良い。

今回はhttp.Get()でのダウンロードの際にpbを使ってみたが、大量のgoroutineで並列処理した状態でプログレスバーを出すと表示が50%で止まったりしたので、並列度を定義し徐々に表示を増やしていった方が良い感じ。

ちなみにhttp.Get()プログレスバーを出す場合はこんな感じのコード。

 response, err := http.Get(url)
    if err != nil {
            // エラー処理
    }

    fileSize := response.ContentLength
    progressBar := pb.New64(fileSize).SetUnits(pb.U_BYTES)
    progressBar.Start()
    reader := progressBar.NewProxyReader(response.Body)

    defer response.Body.Close()

    io.Copy(file, reader)

Goglandの謎挙動

開発途中でpbをgopkgからインストールし、Goglandで使おうとしたら該当ディレクトリを読み込まず。

再起動したら読み込んだが、もしかしたら読み込みタイミングがアレなのかもしれない。

[追記] 上部メニューバーのFile→Synchronizeの実行でファイルの再読込を行えばOK

vim-goの入力補完が動かなくなった

.vimrcの整理整頓作業をしていたところ、突然vim-goの入力補完が下記のようになった。

f:id:syossan:20170216133259p:plain

「いやいや、こっちがPanicだよ」と思いつつ、色々と対策を探しました。

対策

そもそも、vim-goの補完にはgocodeが使われており、そちらのISSUEを探したところありました。

github.com

「gocodeを再起動させてみ?」って感じのレスがあったので、一度gocodeのアップデートをかましてから再起動しました。

$ gocode close
$ go get -u github.com/nsf/gocode

するとキチンと補完してくれるようになりました。

とりあえず困ったら再起動ですね!

kirimoriにVimのExコマンドを実行する機能を追加しました

細々とkirimoriの開発をしております。

今回はkirimori addkirimori removeをした際に各プラグインマネージャー毎に対応したExコマンドを叩く機能を追加しました。

例えば、Vundleの場合はkirimori addした際に:PluginInstallが、kirimori removeした際に:PluginCleanが自動で実行されます。

実行してみると以下のような動きになります。

f:id:syossan:20170206231645g:plain

これで結構便利なツールになったのでは、と思います。

まだまだ機能改善の余地がありますので、「これ欲しいな」や「動かない」など何でもご意見お待ちしております。

github.com