• 子供のGPS

    うちの子が小学校上がって初めて寄り道して帰ってきた。

    奥さんから「まだ帰らない」ってLINEがあったから僕も心配してたけど帰ってきたとのこと。どうやら友達の家で遊んでいたらしい。

    おぉ〜 いいぞ成長した。

    って思ったけど、帰ってこないのは心配だよね。GPSと通話機能があればきになったら聞けばいいし見れば良くなるからこれをきっかけに買うつもり。

    GPSもたせるってなったらなんか縛られるようなイメージがあるけど、子供にGPSもたせたら場所がわかるから「遊びに行っていいよ、GPSあるから」ってことになるね。

    GPSなかったらできない、今まで得られなかった自由があるツールで得られるようになるわけだからいいことだと思うけど、考え方によっては「遊びに行くにはGPSを持たないといけない」ってことになる。

    物は言いようだね。例えば

    「ディズニーランドに行きたかったら勉強しなさい(=制限)」

    「勉強したならディズニーランド行っていいよ(=権利)」

    同じことなんだけどね。この2つが大きく違うように捉えることができるからコミュニケーションには問題がおきやすそうだね。

    ディズニーランドに行くというのが普通にできることなのか、できないことなのかという前提の間隔もすごく影響する。普通にできると思ってたらただの制限になりやすいね。

    特に政治の世界ではこの2つはすごくコミュニケーションミスが多いのかもしれないね。

  • GraphQLの理想と現実

    うち(obniz)でも採用してるGraphQLの人気がなくなってきてるらしい。

    本当かどうか置いといて、正直気持ちはわかる。

    僕も新しい小システムでは採用せずRESTに切り替えたし。

    ただ、GraphQLとしてきっとこういうこと目指したいんだろうなっていう理想とそれに対する差が大きいからその難しさを解消しないといけない。

    自由と堅固さの両立

    なんでGraphQLがいいなと思って採用したかって、もちろん新しいからという新しいもの好きなのもあるけど、REST APIが持っていたフォルダ構造の限界を打ち破れそうな気がしたから。

    まず、REST APIだとあるユーザー`yukisato`が投稿してしかもお気に入りにした記事を取り出そうと思ったら、例えば

    GET /users/yukisato/articles/liked

    だったり

    GET /articles/liked?by=yukisato

    なんてのだったり、書くわけだけど実際は、その記事に対して書かれたコメントも欲しいなんてことになると、もう1段階深いところまで返すことがあって

    {
      articles: [
      {
        id: 101,
        text: "焼きそばの青のりは必須?",
        comments: {
          user: whiterabbit,
          text: "いらない"
        }
      }
      ]
    }

    なんて多段になることもある。

    そこで思うのは

    「あれ、userを取りに行ったのにuserのしたに記事があるの?」

    「articleの下にコメントがあるの?」

    のような妙な感覚がでてくる。この原因は URLのパスに上下関係があるからで

    /users/yukisato/articles

    を見たときに、「usersフォルダがあって、その下にyukisatoがあって、その中にarticlesがある。」用に見える。

    これはwww(ワールドワイドウェブ)の名残で、本当はこんな書き方じゃなくていい。だってフォルダでもファイルでもないんだから。だけど踏襲してる。ブラウザが過去を切り捨ててなくて、むしろそれに合わせようぜとなっているのが REST APIだから。

    だから、フォルダ構成っぽくないものとか(/articles/today)、2段以上( articleの中にcommentsがある )になると「ん?」となる。いくら規格化して方針を定めてもURLに構造があって1つである限り表現に限界がある。

    GraphQLはそれを打開しようとしているのをすごく感じる。

    まず階層構造はない。すべて平おき。まず記事を取ってくるのはこのようになる。

    query getArticles(id: "yukisato") {
        id
        text
      }
    }

    まず、前提としてAPIサーバー側に`getAticles`が必要になる。関数を用意するのと同じ。そして要求に対して返す。今回はidとtextを返せば良く、他に情報があったとしてもいらないと言われている。

    GraphQLという名前の通り、SQLがすごく意識されていて

    select id, text from articles where id = 'yukisato';

    と同じことになっている。

    SQLもTable同士に階層構造がないように、GraphQLにもない。

    これがものすごい自由度と堅固性を担保している。

    更にjoinやサブクエリを目指しているような仕組みがGraphQLにあって、同時にクエリを叩くことができる。例えばREST APIで記事とそのコメントを取り出したかったら

    1. コメントも帰ってくる記事APIを叩く
    2. 記事APIを叩いた後に関連するコメントAPIを叩く

    といった動きになるが、GraphQLでは

    1. 記事APIと関連コメントAPIを同時に叩く

    ことができる。しかし、ここに問題がある。「それを実装するのが自分」ということ。

    SQLのような自由度をWebAPIに持ってきたのはいいけど、結局それを全部自分で実装しないといけない。記事APIと関連コメントAPIを同時に多々たたけるようにするのは自分ということになる。

    いくらGraphQLで「構文として」それを許可したとしても実装されていないと意味がない。

    もちろんライブラリのサポートはある程度は存在しているが結局認識しているクエリじゃないと対応が難しく、場合によっては無限に掘り下げる実行をしてしまう可能性がある(これは昔から指摘されていて、限界回数を指定できるなどの仕組みがライブラリにある)

    そうなると結局REST APIと同じような作りになる。誰も同時にクエリを叩いたりせず1つずつ叩くし、REST APIのendpointを作るようにqueryやmutationを作ることになる。

    そんなことするぐらいならドキュメント生成ツールがあったり、エラーが読み取りやすいREST APIの方がいいってことになってしまう。

    今GraphQLが下火になってるのなら、REST APIを置き換えて使ってみたけど「これREST APIでよくね」となっているんじゃないかという気がしてしまう(僕がそうなってる)。

    GraphQLを提供するDBができればいい

    解決策として思うのは、そもそもデータベースがSQLではなくGraphQLでtable操作ができ、それを公開すればアプリを書くこともなく使えるというのが理想だと思う。

    そもそもデータを操作するのにAPIである必要はなくフロントエンドからSQL叩いたっていいはず。firebaseとかsupabaseがそれに近いことをやっている(Application less database accessともいうべき)。

    問題になるのは認証やマイグレーションや負荷対策などだろうけど、もう少しロジックをデータベース側に持たせてGraphQLが生えて操作ができるのであればきっと理想に近づけるんだろうなと思う。

  • 起業が怖いって高学歴だからじゃないか

    今日は起業家関係で早稲田の学生含めたメンバーからインタビューを受けてたんだけど、その中に「起業怖くないですか、食いっぱぐれる心配とか」ってのがあって、そのときは

    「町歩けばコンビニとか絶対人募集してるし、絶対仕事あるんだから死ぬ心配なんてしてない。死なないから大丈夫」

    って言ってたんだけど、家に帰った今ふと思ったけど

    食いっぱぐれ怖いって高学歴だから思うことじゃないか?

    正直質問受けたときに「なにを心配してるんだろう」って思ってた。
    いや、言いたいことわかるけど。

    それがふと家に帰って思ったのは、起業の反対側に就職ってのがあって、就職が食いっぱぐれないと思ってるのがあるんじゃないかと。だから就職というのは安心みたいに思ってるのかもしれないなと。

    どっちもただの仕事だよ?

    これは高学歴な人に多い考え方なんじゃないか。
    なぜ就職したら食いっぱぐれないと思ってるのか。

    社長をやろうと社員をやろうとお金を稼げなければ終わりなのは一緒。
    桃太郎で、もし仮に誘われたサルが「桃太郎さん社長やるなんてすごいっす」とか言ってたら「いや、大して変わらんじゃん。きびだんごはあげるけど鬼倒せなきゃ運命共同だよ」って言われてもおかしくないよね。会社は人数多いから薄れるだけで。

    それを安心って思ってるのは結構危険だと思ってこの記事書いてて、
    むしろその会社のそのポジションでしか通用しないことでお金を稼ぐ(そう、「お金を稼ぐ」んです)のは、個人としてはリスクがあって、それも大企業ほど。
    ポジション変わったり、会社変わったときに通用しない可能性がある。

    桃太郎は社長として次はボルデモートを退治しに行くかもしれないけど、犬は鬼の中でも青鬼倒す訓練しかしてないときに、会社がもう鬼倒さないってなったら困るし、青鬼やってる会社以外に行けない。

    だからって就職がだめって意味じゃないけど、リスクの種類が違うだけで、むしろ現代なら時代が変わって鬼が変わっても大丈夫なように訓練しとかないと、ある日きびだんご配給が終わるかもしれないし、ずっと1日1個から変わらないかもしれないリスクを持ってて、逆に今日・明日鬼が倒せなくてもとりあえずきびだんごをもらえる安心材料はあるけど、鬼倒せてないから、一時的なものでしかない。

    大学に行く人が割と少ない低偏差値の高校から早稲田行った身からすると、高学歴な人は生きていく・仕事をする ということに盲目的で無頓着な人が多い気がしているからぜひ一回考えてみて欲しい。

  • コンビニってネガティブな気分にさせるよね

    レジなんだけどさ、レジでネガティブな気持ちになる

    店員「(ピッ)あたためますか?」

    僕「大丈夫です」

    店員「レジ袋はどうなさいますか?」

    僕「なくて大丈夫ですー」

    店員「300円です。ポイントカードはありますか?」

    僕「あ、大丈夫です」

    店員「(会計後)レシートは?」

    僕「大丈夫でーす」

    否定的なのあんまり好きじゃないのに連続で言わせられてやたらとネガティブになる「あー、また全否定だわ」って。

    これ家庭だったら

    「御飯食べる?」

    僕「いらない」

    「お風呂は?」

    僕「それもいいや」

    「コーヒーとかあるけど」

    僕「大丈夫でーす」

    みたいに、結構やばい言動だと思うんだけど。

    でもいらないのに「じゃあレシートください」と言う気にもならなしい。

    ってかいらないもの提案してくる店員も良くないよね。

    店員「ポイントカードありますか?」

    僕「ないですー」

    店員「じゃあ私のポイントカード使っていいですか?」

    僕「えっ?はい? へー。いいですよ」

    こんなんだったら肯定できるのに。

    それか否定を1度にさせてほしいな

    「僕は弁当温めないし袋もいらないしポイントカードも持ってないし、レシートを受け取る気はありません」

    って最初に言えばいいのかな。

    これはこれで嫌なやつじゃん。

  • BMSG ストアをBug fixしながら注文した話

    うちの奥さんがBE:FIRSTのファンで、今日は15時から限定商品の再販があるとかで連打してるけどつながらない。

    ふ〜ん と思いながら僕も参戦してデバッグしながら1つ買えたのでエンジニアリング的にメモ

    ヘッダのレスポンスは早いけど

    アクセスが多くて503とかが頻発するのはわかるけど、意外とローディング待ちも多い。タイトルが返ってくるのでヘッダーレスポンスは意外と早いらしいが中身が返ってこないところからレンダリングの問題っぽい(disk IOかも)

    そして503に堂々と”nginx”とでてくるので、セキュリティも不安に。。。

    10分ぐらい粘るとカートに商品は入ったので会員登録からクレカ決済入力、3Dセキュア認証まで行って戻ってくるところでエラー。

    「一番イヤなところでエラーだな・・・」と思いながらURL直やReloadを試したけどだめ。

    $が見つからない

    諦めて最初に戻ると今度は次へボタンが見えない。ただのCSSの問題ではなさそう。

    欄の下に2つボタンっぽいのがあるので、「左下かな。。こわいから文字を読むか」と思ってInspectすると左が「戻る」右が「次へ」だったので勘に頼らなくてよかった〜 と思いながら押すと押せない。

    コンソールを見ると$が見つからないとのこと。

    「私知ってるあなたjQueryね!」と頭の中でトトロのメイちゃんっぽいのが叫んだけど、リソースを開くと

    そのようですね〜。

    重くなる事がわかってるサイトでリソースを同じところから配信するのはいかがなものかと思いますが、気持ちはわからなくもない(CDN落ちたら嫌だもんね。わかるよ。でもこの品質だとそういう事を考えてというよりは多分public directoryに入れるものだと思って運用してるんですかね)

    しかし今回落ちてるのはこのサイトなので、、
    何度リロードしてもだめなので、ページレンダリングするやつとファイル返すやつが別なのかな?とりあえずjQueryをconsoleよりinject。

    (function (){
        function l(u, i) {
            var d = document;
            if (!d.getElementById(i)) {
                var s = d.createElement('script');
                s.src = u;
                s.id = i;
                d.body.appendChild(s);
            }
        } l('//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js', 'jquery')
    })();

    これで1ページ目はうまく行った。

    次ページはただ突っ込んでもNG。そいつはロード時にイベントリスナーの設定をしていた。そのコードをコピペして(幸い短いし読めるレベル)再実施して次へ。

    そして今度はクレカが怖いのでステップ減らすためにも請求書払に(GMOペイメントだろうけど、多分後処理だろうから外部に飛んだりしないだろうと)

    無事買えた

    買えて購入のメールも届いた。

    BMSG Store開発担当者へ

    楽しかったですが、直せた自分が買えたという若干の背徳感が。。以下提案です。

    • マシンリソースが増やせないのであれば、せめて必要なcss, jsらを1 packageにして外部配信に
    • それが難しければせめてjs loadに失敗してもボタンを押して進められるような設計を
    • cssがなくても読めるページ構成だったためそこは助かりました