ベルリンのITスタートアップで働くジャバ・ザ・ハットリの日記

日本→シンガポール→ベルリンへと流れ着いたソフトウェアエンジニアのブログ

技術書ランキングサイトをQiita記事の集計から作ったら、2700冊の技術本がいい感じに並んだ

QiitaのAPIから投稿記事を取り出し、技術書籍を紹介している箇所を集計して、ランキングサイトを作った。作った本人が言うのも何だけど、できあがった技術書ランキングがやたらエンジニア指向で便利で面白いなー、と。

技術書ランキングをQiita記事の集計から作成した
テック・ブック・ランク

エンジニアにとって技術書の選定はまーまー苦労する。単なる発行部数ランキングでは「人気あるからって技術書として参考になるとはかぎらない」と、なってしまいがち。ブログでオススメされている書評なんかも参考にするが、結局それらは書評を書いた人の主観で書かれたのであって客観的指標にはなりえない。
そこで「Qiitaにある技術ブログ記事内で紹介されている書籍情報を集計すればひと味違った書籍ランキングになるのでは?」と考えた。

で、以下の条件に当てはまる本を「いい本」とした

  • たくさんのQiita記事で紹介されている本
  • 人気のある記事で紹介されている本
  • 新しい記事で紹介されている本

結果としてできあがったランキングの総合部門トップ6はこんな感じになった。当たり前だけど「売れてる本」と「技術記事で紹介したい本」はちょっと違う。本当の意味で有用な技術本というのは後者の「紹介したい本」の要素が多いかな、と。

f:id:tango_ruby:20180405224646p:plain:w500

いい感じに古くからずっと支持されている古典的名書と最新の人気ある書籍がトップに入っている。「リーダブルコード」なんかは廃れることのない名著だし、最近出たばかりの「エンジニアリング組織論への招待」や伊藤さんの「プロを目指す人のためのRuby入門」がトップ10に入っていて、気に入っている。ちなみに恣意的に特定の本のランクを上げたりは絶対にしていない。同じルールの元で公平に集計測定した結果がこれ。

Qiita記事にあるタグがいい効果を発揮している。Qiita記事に貼ってあるタグはそのまま紹介されている書籍のタグとした。つまりタグ=>記事=>書籍となっているのでタグと書籍の関係は直接ではなく、ゆるーく繋がっているだけ。そこがいいなと思っている。

例えば「人工知能は人間を超えるか」という本の場合、この本には20以上のタグが付いている。

f:id:tango_ruby:20180405225533p:plain

ウェブサイトで見ていただくとドーナツグラフでタグの分析結果が見れるようにした。

PythonやTesorFlowのタグが付いているが本書にはこれらの技術に関する言及は無い。でもタグがあって、それは「この本を紹介するエンジニアはだいたいPythonやTesorFlowに関係する記事を書いてますよ」という意味になる。このゆるーい関係のタグ付けがいいと思った。他にもRubyの本にGitHubがタグ付けされていたり、書籍の内容には関係無さそうだけど実務では関係あるタグ付けがなされている。

自分で作ったサイトながら、そのタグをクリックして関連タグで人気順にソートされた技術本ランキングを次々に眺めるのが面白くて、しばらくサイト内を巡回していた。例えばAという技術のタグを押しても全てがAに関する書籍ではなかったりするので、「おーこんな本もあったのか」という発見がある。なのでタグを目立つようにして、検索窓は右上に必要な時だけ表示する仕組みにした。サイトのコンセプトとして検索してピンポイントで必要な書籍情報だけを見るよりも、タグをクリックしていろいろ巡回して見た方がこのサイトは面白いと思ったからだ。

本についてはその本を読むこと以前に「その本との出会い」がとても重要だと思っている。売れている順や人気順のランキングならばアマゾンので十分だ。
テック・ブック・ランクは他には無い「本との出会い」がある。なぜならそのランキングに使っている指標が限りなくエンジニア目線を元にした指標だからだ。人工知能の本にTesorFlowのタグを付ける、なんてやるのはエンジニアだけだろう。

Qiitaの技術記事ってそれなりにちゃんと書かないとLike数なりView数なりで人気を得ることは難しい。なのでそれらと連動した技術本のランキングもそれなりに信用に値するかな、と思っている。

テック・ブック・ランクが皆さんの「こんな本があったのか!」をたくさん提供することを願って公開した。ご感想なり、批評なりなんでもコメントください。

技術書ランキングをQiita記事の集計から作成した
テック・ブック・ランク


使った技術

  • Rails
  • GraphQL
  • React + Redux
  • GCP
  • Heroku
  • CloudFlare

GraphQLを最速でマスターするための意識改革3ヶ条

GraphQLをサーバー側とクライアント側とで実装してみて得た意識すべきポイント3つについて。

  • ひとつのエンドポイント
  • バージョン無し
  • できるだけ薄く

この3つを意識して実装するのとそれが無いのとでは実装スピードが何倍か違うと思う。特にREST脳な人の場合。

GraphQLは使い所さえあえばめちゃくちゃに有用で面白い。しかもGraphQLの公式サイトはとてもわかりやすく説明されている。その辺のブログ記事よりもよほど洗練されていて、技術に関してはここ以外に読む必要はほぼ無い。

しかしGraphQLを使いはじめた当初はなんか妙にコーディングが進まなかった所があった。その原因はずっとRESTfulでやってきたREST脳の意識からGraphQLへと変換できていなかったことだった。GraphQLとRESTは設計思想が異なるので、意識を変える必要がある。その意識さえ変えればGraphQLに難しいところなんて無く、とてもカンタンに実装できてしまう。公式サイトに技術内容がどんなに分かりやすく書かれていても、このポイントを絞って意識を変えることに注力していなかったら「あれ??今まではこうだったのに、なぜだ?」となってしまうのだ。

そもそもGraphQLってなに?となっている人はこことか公式サイトを読んでください。

GraphQLを書いてみた話 - emahiro/b.log
GraphQLに関するメモ - ushumpei’s blog
GraphQLを使ってみた - kakts-log

以下はそのGraphQLの概念は分かっているという前提で書く。

【意識改革1】 ひとつのエンドポイント

GraphQLにエンドポイントはひとつしかない。RESTのように `GET api/v1/users` `POST api/v1/users/:id` とか一切無い。どんなリクエストも全て`/graphql` に向けて飛んでくる。GraphQLのクエリ言語がそういった処理を全て吸収してくれるからだ。クライアント側を実装していて「えーっとこのリクエストはどこに投げればいいんだっけ?」と思う度に、いやいや「どこ?」とか考えてる時点でそれREST脳だ、と自分で訂正していた。

個人開発したウェブアプリをGraphQLで実装していた時にある箇所のキャッシュとデータベース側の処理を2種類に分ける必要があった。そこで通常の処理を`/graphql` で受けて、その他の処理を別のエンドポイント(例えば`/graphql2` とか)で受ける設計を考えた。今から考えてもバカなデザインだったと思う。こんなことをするとGraphQLのメリットをちっとも活かせないし、メンテナンス性が著しく下がる。後からqueryやTypeが変更になった際にいちいち2つのエンドポイントとその挙動について考えなければならない。個人でやってたのでクライアント開発者とサーバー開発者の間でやりとりする必要は無く、自分の脳内で2役やって終わりだったが、あれをチームでやってたら、エンジニア同士の間でムダな話し合いが増えていたことが分かる。

GraphQLのメリットはクライアントーサーバー間で「この型でいきましょう」と決めただけで実装にかかれるところにある。後は欲しい情報を欲しい時にリクエストするだけで完了する。
公式サイトにはサラっとしか書いていないが「ひとつのエンドポイント」はとても重要なことなのだ。

【意識改革2】 バージョン無し

GraphQLは基本的にバージョンレス。つまりRESTのようなバージョンという概念は無い。RESTでやってるプロジェクトは`api/v1/...` からバージョンがあがるとクライアント側の実装と呼吸を合わせて、せ~ので`api/v2/...` とかを作ってリリースしていた。
理論上はうまくいくはずなんだけど常にこれが頭痛の種になる。だがGraphQLにバージョンは無い。`/graphql` というエンドポイントでv1もv2も無くずっとそのままだ。

これがREST脳だった私には不安だった。「え?バージョン無し???一応は念の為に付けとこうかな?」みたいに考えた。しかしこの質問と答えで気が付いた。「RESTのAPIになぜv1やらv2とバージョンがあるのか?」答えは「破壊的な変更があって、その度にバージョンを上げる必要があるから」と。
つまりは「GraphQLにすれば破壊的な変更は無いのでバージョニングする必要がない」となる。
クライアントが欲しい情報をリクエストして、そのままレスポンスを返すGraphQLでは基本的に変更をかけても破壊的ではない。今まであったfieldを削除するとかは破壊的かもしれないがGraphQLではadd-only approachを推奨している。つまり加えるのみ。

なので今回作ったrailsのルートはBest Practice にのっとり
`graphql POST /api/v1/graphql`
とかではなくて
`graphql POST /graphql`
としている。清々しい。対外的にも「バージョンは無いからな」と宣言することにもなる。
今までRESTfulでAPIのバージョンを上げることの痛みをずっとガマンしてきた人なら、このversionless APIという発想は気に入っていただけるだろう。

【意識改革3】 できるだけ薄く

GraphQLの作者Lee Byron氏も言うように「なんでもできるGraphQLだが、GraphQLはできるだけ薄く保つのがいい」と。Lee Byron氏の公演ビデオはとても示唆に富んだビデオで参考になる。そんな中で一番はこの「できるだけ薄く保て」という箇所だった。
実装していけば認証やらセッション管理やらありとあらゆる処理がGraphQLを通して行われる訳だが、それらをGraphQL内でやってしまわないこと。それらの処理をするのに適したクラスが必ずあってそっちでやるべき。
GraphQLの責務と役割はquery(RESTfulのGET)とmutation(POSTもしくはPATCH)だけであって、それ以外は無い。したがってresolve ->(obj, args, ctx)の中にロジックがあったら、その責務はどこが持つべきか考えてそこに移すべき、ということだ。
これはアプリのソースコードが大きくなればなるほど効いてきた。「薄くしといてよかったなー」と。

以上がGraphQLを最速でマスターするための意識改革3ヶ条でした。

動くGraphQLの実例

こちらがGraphQLとRails、React+Reduxを使って個人で開発したウェブアプリです。
エンジニアの集合知を図解するSNS「node-node-node」デスクトップ版
PCでしか見れませんが、ぜひ感想をお聞かせください。ぶっちゃけ、どう改良したらいいのか分からなくなってきたので「ここがダメなんだよ」とかなんでも言っていただけたらありがたいです。

情報ノードはパラっと開いて、グリグリとドラッグできる訳でして、こうして階層構造の技術リンクをマッピングしていけば理解しやすいかな、と。
f:id:tango_ruby:20180205204551g:plain

node-node-nodeについてなんでも感想や批評を書き込めるフォーム

少し前はいろいろとダメな点とかご指摘をたくさん受けて修正した。でもその修正が終わった途端、あんまりコメントをいただけなくなって辛いので、ちょっとでもコメントいただけたら嬉しい。

tango-ruby.hatenablog.com

www.youtube.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

イノベーションを後押しするのはシリコンバレー的文化で、それはとりあえず「スゲー!」と言っておくこと

個人開発ではあるが、なんとか公開にこぎつけたのはベルリンにあるシリコンバレー的文化があったことは紛れもない事実。そんな経験からアメリカのある特定の都市から革新的なIT企業が次々に現れる理由にはそういったシリコンバレー的文化が後押ししているんだろうな、と感じた。

個人開発においては開発者のモチベーションだけが鍵になる。納期も約束もなくただその開発者が「やってみるか」と思ってやる開発においてはそのモチベーションだけが原動力になる。そしてそのモチベーションは本当にもろくて崩れやすい。

  • こんなの作っても意味ないわ
  • これ公開しても誰もアクセスしねーわ
  • こんなしょぼいアプリを公開しても恥かくだけだ

といった思いはなんども開発者に押し寄せる。で、そういった思いが間違っていることはあまりなく、ほとんどの場合においてそれは正しい。
それでも何百万とある企画の中から0.0001%のキラっと光る企画で諦めずに改善を続けたモノだけが、脚光を浴びて大成功する。

ヨーロッパのITスタートアップ聖地と言われるベルリンに身を置いて感じるのは、良くも悪くもシリコンバレー的な考え方がひとりひとりに染み付いているな、ということ。それは端的に言ってしまえば、なにかよー分からん新しい企画や考えに出会った時にとりあえずは「オーサム」「ファンタスティック」「アメージング」などを連発してノリノリのコメントをぶつけておくこと。ぶっちゃけIT関連のアイデアはあまり素直に「スゲー」と思えないのが多い。今では成功が確定している企業ですらこんな感じだ。

  • ビデオが観れるウェブサイト(YouTube)
  • 24時間で消えるSNS(スナップチャット)
  • 写真がキレイに並ぶSNS(インスタグラム)

もしこれらのアプリが流行る前にこのアイデアを聞かされたとしても「スゲー!」「オーサム!」「ファンタスティック!!」とその先見性を予感して心の底から絶賛できる自信が私には無い。でもベルリンのITカルチャーにならって一応はそう言っておくだろう。なにが当たるか分からない時代にとりあえずノッておくのはまーまー大事なのだ。そしてこの「一応はノッておく」というのがこの都市の全てのITスタートアップに勤める人々の意識にデフォルトで入っているようだ。

言っておくが全てのヨーロッパ人がこんなノリな訳ではないし、アメリカ人にしても全てがヒャッハーな訳がない。その証拠に全米の全ての都市から革新的なIT企業が出てきる訳でもなく、限られたアメリカの都市が突出しているだけだ。

今回の私の個人開発でなんとかモチベーションを保てた原因は2つ。
公開前:プロトタイプを見せた時の職場の同僚や友人達の大袈裟でノリノリなコメント
公開後:アプリを使っていただいたユーザーからのフィードバック

断言できる。これらが無ければとっくの昔に頓挫していた。やったことがある人なら分かってもらえると思うが、自分が作ったものに対してちょっとコメントもらえるだけで、それがどれほどモチベーション向上になるか。それに「オーサム!」なんて言われてたら、そらやる気も出る。別にやたらと褒める訳でもない。特に技術者とかはノリノリではあるが、ダメ出しも強烈だ。

職場の同僚であるロシア人フロントエンドエンジニアのKは、私が個人開発したプロトタイプにあったReact+Reduxのソースコードを見て、ボロクソに言ってきやがった。バックエンドばかりやってきた私にとってフロントエンドはまだまだ知識が足りないのは分かっている。「それをそこまでメタクソに言うことは無いだろ」と思ったがそれでも嬉しかった。私の個人開発にそこまで熱を込めてダメ出ししてくれるKの熱意がまた私のやる気に火を付けた。ベルリンを包む空気が新しい企画に対してポジティブなのだ。

f:id:tango_ruby:20180228002741j:plain

都市はそこに住む人達が相互に作用しているのでひとりが「やってみるか」とやる気出してやったことが、他にも波及して、またそれがバイラルになって都市全体に波及していく。そういうエネルギーをIT都市ベルリンからはハッキリと感じる。

もしこれをお読みの方でご自身の住む都市をシリコンバレーに匹敵するぐらいのイノベーション都市にしたいと思ったら、カンタンにできることがひとつある。それは職場の先輩や上司であまり仲良く話す訳でもないし、ちょっと気を使うような関係の人が居たとして、その先輩が個人的に新しい企画を考案して「こういうの作ってみようかなと思うんだよね」と言った時にこう反応するのだ。

「えー先輩マジですか?それ。マジでー!それスゲーぇええ!!そんなの初めて聞いたわ!マジかよ!お前なー天才だわ!もう鼻血出るわ!てめー今すぐこの会社やめろよ!ヤメてそれやれや!天才のくせに時間ムダにすんなよな、おいボケ!そんな顔してザッカーバーグかと思ったわ、この天才!」

と言う感じでちょっとノリのいいリアクションを取ってみましょう。仮にその先輩のショボ企画がスベっても、そんな先輩の企画を見て触発された人や、そんなあなたの態度に触発された他の人達が「オレもやってみるか」と思ってきっとなにかアクションを起こす。そんな相乗効果は都市全体を包むはず。シリコンバレーなんて魔法の都市でもなんでもなく、結局はそんなひとりひとりの新しい企画に対するノリノリなコメントが大きく影響しているのでは、と思った次第。なので私自身も誰かの作ったモノをネット上でも見かけたらできるだけたくさんコメントするようにしている。

こちらの私の個人開発でも随時、素直なご感想やコメントを募集中です。なんでも言ってやってください。

エンジニアの集合知をノードグラフにして図解するSNS。(デスクトップ版)
「node-node-node(ノード ノード ノード)」
 https://www.node-node-node.com/

tango-ruby.hatenablog.com
tango-ruby.hatenablog.com
tango-ruby.hatenablog.com
tango-ruby.hatenablog.com