Macのvimをゴリゴリカスタマイズしてみる
Kotlinを始める際に参考にしたサイトや書籍
今年のGoogle I/OでKotlinがAndroid公式言語になったことをきっかけにKotlinの勉強を始めました。今回はその時に参考にしたサイトや書籍を紹介したいと思います。
Kotlin助走読本
kotlin-prior-learning-book.pdf - Google ドライブ
Kotlinの機能や歴史が簡単にまとめてある無料の本です。後で紹介するKotlinスタートブックの作者やKotlinコントリビュータの方々が執筆しています。
Kotlinの機能が簡潔に書かれているので、助走をつけるにはちょうど良い内容になっています。
Kotlinスタートブック

Kotlinスタートブック -新しいAndroidプログラミング -
Kotlin入門書の定番。助走読本と比べて各機能が詳しく説明されています。
第1部は助走読本のようにKotlinの機能が簡単に紹介されています。データ型や制御構文の説明もあるので飛ばさず読みましょう。
第2部では章ごとにKotlinの文法の説明がされています。第2部の最後まで読んだ後にもう一度見返すと、1度目とは違った見方ができるので時間があれば読み返すと良いと思います。
第3部はAndroidのサンプルアプリを作ります。Android固有のコードやライブラリについての説明が多めなのでAndroidアプリ開発経験がある場合はさらっと流す程度でも良いでしょう
KotlinKoans
KotlinKoans
Kotlin公式のチュートリアル。問題にしたがってソースコードを修正し、テストを通す形式になっています。
自分で考えてコードを書く形式なのですべての問題を解いたころにはKotlinの文法に慣れているでしょう。問題を解くにはKotlinの幅広い知識が必要になるのでやっておいて損はないです。
KotlinReference
KotlinReference
Kotlin公式のリファレンス。ほとんどの機能についての説明があるので困ったらまずこのページを見ると良いでしょう。
Kotlin1.1時点でexperimentalなCoroutinesの説明もあります。
最後に
KotlinはAndroidで使用可能なJavaと比べてモダンな機能が豊富にあり、簡潔なコードを書くことができます。Kotlinについての情報はまだ多いとは言えないですが、Androidの公式言語になったことで利用が拡大されることが期待されます。
ぜひKotlinをやっていきましょう〓️
#96 MFI対応
ついに今週から某伝説レイドが始まりましたが、皆様楽しんでおりますでしょうか?
しかも期間限定らしい、ということで自分も初日の日曜はかなりバタバタと走り回っておりましたw
さて、本日のネタは
MFI対応について
MFI(モバイルファーストインデックス)対応についてでした。
Google Webマスター向け公式ブログの声明
MFIって何、というところからですが、
Googleのウェブマスター向け公式ブログを見ていただいたほうが早そうです。
Google ウェブマスター向け公式ブログ: モバイル ファースト インデックスに向けて
これまでGoogleのインデックスは、デスクトップ版のコンテンツが中心でしたが、
時代の流れと共にモバイル(スマホ)が中心になってきたため、
これからはデスクトップ版よりもモバイル版が中心になってきそうです。
ということで、弊社でも、MFI対応を順次行っていく予定となっています。
何故MFI対応が必要なのか?
- サービスの内容にもよるが、流入元の大半がGoogle検索などとなっている
- PVの比率もモバイル中心にシフト
- 当然ながら売上も
MFI対応の具体的な流れ
- モバイル版ページのコンテンツを参照することになるのでモバイル版でPC版のそれとおなじコンテンツを配信する。違うもの(コンテンツ足りてないとか)だと評価がさがる
- PC版のみの場合はMFIの対象とならないが、モバイルフレンドリー(後述)対応してないので評価がさがる
- 故にモバイルフレンドリー対応をしっかりやっておかないとならない
モバイルフレンドリーテストツールですが、Googleが公式で用意してくれています。
https://support.google.com/webmasters/answer/6352293?hl=ja
モバイル フレンドリー アップデートを開始します
- 検索順位に影響
- ズームしなくても読める
- 横スクロールNG
- リンク押しやすく
などなど…
モバイルフレンドリー対応
PCとは別にモバイル(スマートフォン)に最適化したページ配信が必要となります。
配信方法は3つあり、
1. レスポンシブ・ウェブデザイン
- PC・スマホ同じコンテンツ
2. ダイナミックサービング
- 同一URLで別々のコンテンツ
3. セパレートURL
- 別URLで別々のコンテンツ
例えばこのSeesaa ブログでは、セパレートURL形式となっています。
- 重複コンテンツ対策に alternate canonical 属性
- PC版URLにスマホでアクセスした場合はスマホ版にリダイレクト
- レスポンシブデザインではなく、事情によりスマホ専用コンテンツにする必要があった
この3つの方式のうち、
1. レスポンシブ・ウェブデザイン
2. ダイナミックサービング
の2つは、モバイルフレンドリー対応にあたって特に対応が不要となっています。
セパレートURL配信時のデメリット
- MFIにおいては alternate / canonical の意味合いが逆になる
- google は大丈夫といっているが…
- セパレートURLの場合の被リンクの扱いがあやしい
- ブログの場合、MFI時は /s/ がベースになるわけだが、、
- 雑誌等でURLが別に記載される場合 /s/ とか記述される可能性
- SNSシェアフレンドリーじゃない
- FB/twitter/はてぶでシェアされる場合
- URLがわかれると別コンテンツとされてしまう(未確認)(スター数とか減る)
- MFI云々とはそれるがこれはけっこう痛い気もする
結局ダイナミックサービングにする必要がある
# 主な作業
- URLの変更対応
- /s/ URLのリダイレクト対応
- vary HTTPヘッダーの対応
- Vary: User-Agent
- alternate / canonical 属性を削除
- PC/SP版におけるコンテンツ内容のチェック
- 差異がないように、モバイル版に存在しないページ等は noindex
# 想定される問題点
- SP版においてURLが変更される
- 現状インデックスされている分は移転扱い
- PC <=> SPの切り替え
- cookieでやる? vary: User-Agent が無効化
まとめ
- MFIへの具体的な対応内容はモバイルフレンドリー向けのものとなる
- MFI導入時レスポンシブ、ダイナミックサービングは基本的に影響しない
- セパレートURLは注意が必要
- SeesaaブログではMFI時のリスクを考慮し、ダイナミックサービングに変更予定
…といった感じで、これから順次やっていきますよ、とのことでした。
参考
グーグルがPCサイトを見なくなる? モバイルファーストインデックス(MFI)で大切なこと
アメブロで行ったモバイルファーストインデックスへの準備について
モバイル ファースト インデックスに向けて
モバイル フレンドリー アップデートを開始します
動的な配信
【iOS】位置情報取得ライブラリ
モバイルソリューション事業部の田中です。
ここ数日iOS界隈はiOS11がリリースされたりiPhone Xが発表されたりiOSDCがあったりといろんなイベントがありましたね。
今回はそんな話題とは関係なしにiOSの位置情報取得ライブラリSwiftLocationを紹介したいと思います。
位置情報を取得する場合、CLLocationManagerDelegateプロトコルを宣言しデリゲートメソッドやいろいろコードを書く必要がありますが、SwiftLocationを使えばそんな煩わしい作業をスッキリさせてくれます。
実装
現在位置を取得する処理は以下のようになります。
Location.getLocation(accuracy: .room, frequency: .continuous, cancelOnError: true, success: { request, location in
}, error: { error in
})accuracyでは位置情報の精度を設定できます。
- - IPScan: IPアドレスで指定
- - any: 1000km
- - country: 100km
- - city: 3km(kCLLocationAccuracyThreeKilometers)
- - neighborhood: 1km(kCLLocationAccuracyKilometer)
- - block: 100m(kCLLocationAccuracyHundredMeters)
- - house: 10m(kCLLocationAccuracyNearestTenMeters)
- - room: 最高精度(kCLLocationAccuracyBest)
- - navigation: ナビゲーションに最適な値(kCLLocationAccuracyBestForNavigation)
Frequencyでは更新頻度を設定できます。
※accuracyがIPScanの時はこの指定は無視され、oneShotが設定されます。
- - continuous: 継続的に更新(Foregroundのみ)
- - oneShot: 一度だけ(Foregroundのみ)
- - deferredUntil: 指定された基準が満たされるまで遅延で位置情報を更新(Foreground/Background)
- - significant: 継続的に更新(Foreground/Background)
これだけのコードで簡単に位置情報を取得することができます。
そしてジオコーディングも簡単に行えます。
private func locationMonitoringAddress() {
Location.getLocation(forAddress: "京都駅", success: { placemarks in
print("placemarks = \(placemarks)")
}, failure: { error in
print("error = \(error)")
})
}ログはこんな感じになります。
placemarks = [京都市, 京都府京都市 @ <+35.01096850,+135.76820130> +/- 100.00m, region CLCircularRegion (identifier:'<+35.09822930,+135.71884765> radius 28727.67', center:<+35.09822930,+135.71884765>, radius:28727.67m)]いかがでしょうか。
今まで私はPromiseKit/CoreLocationを使っていましたが、こちらもなかなか良さそうなので次に位置情報を使ったアプリを作る際はSwiftLocationを試してみたいと思います。
他に逆ジオコーディングやリージョン監視なども行えますのでなかなか便利そうです。
DroidKaigi2018に参加してきました
普段は京都で主にKotlinを使ってAndroidアプリの開発を行っています。
今回は2月8,9日に開催されたDroidKaigi 2018に参加してきたので報告記としていろいろ書かせていただこうと思います。
DroidKaigiとは
DroidKaigiとは国内外Androidエンジニアが集まって、各々の知見をセッションで発表したりエンジニア同士で交流し合ったりするAndroidのカンファレンスです。
以下公式サイトの引用です。
DroidKaigi 2018
What is DroidKaigi?
DroidKaigiはエンジニアが主役のAndroidカンファレンスです。
Android技術情報の共有とコミュニケーションを目的に、2018年2月8日(木)、9日(金)の2日間開催します。
今回は「ニッチな技術とコミュニケーション」を重視する予定です。
1日目のウェルカムトークの前に流れためちゃくちゃかっこよいオープニング動画が公開されていたのでそちらも併せてどうぞ。
今回、DroidKaigiに参加することで多くの学びを得ることができたのでそれらについて書こうと思います。
全体的な感想とまとめ
DroidKaigiに実際参加するのは今年が初めてなのですが、前年までのセッション一覧やアーカイブ、スライドなどと比較すると「より細かい部分(何故そうなのか)」にフォーカスがあたったセッションが多い気がしました。ニッチな技術が重視された結果かもしれません。
今回参加するにあたって、自分の中で「クロスプラットフォームと設計」というテーマ決めて聴講するセッションを選択していました。
クロスプラットフォームに関しては特に近年React NativeやXamarinなどをよく聞くようになり、Flutterも最近話題になっていると感じます。今後実務などでクロスプラットフォームフレームワークを使う際に、これらにはどういう違いが合って、このケースではどう選択すれば良いのかという判断を迫られた際に決定できるための材料として学ぼうという気持ちが大きかったです。また、個人的にもiOSとAndroidのクラスプラットフォームアプリ開発に対して非常に関心が高かったということもあり、テーマの1つとして挙げました。
設計に関してはMVP、MVVM、CleanArchtecture、Fluxなど挙げればキリがないくらいに様々なものが登場しています。これらに関して詳細にどう違うのかまた、自分が実務を行う際にはどれを選択すると良いのかというのに対しかなり悩んでいた部分があったので選択しました。
DroidKaigi全体に対しての印象ですが、まずセッションのほとんどのサンプルコードがKotlinだったという印象がかなり強いです。会場内の展示ルームで幾つかのアンケートがありましたがそれを見ても半数近くの(少なくともDroidKaigiに参加している)エンジニアはKotlinを使用しているという感じでした。
KotlinがGoogle I/Oで公式言語としてサポートすると発表されてからまだ1年経っていませんが、Android開発においてかなりスタンダードになってきているなと感じました。
また、今回は過去最大規模で1,000人程が会場に居たのですが、1日目のウェルカムトークを聞くためにホールへ入場した際に「おぉ……ここに居る方々はみんなAndroidに関わってる方々なんだなぁ……。」と謎に感動してしまいました。
当日2日間で合計14セッションを聞くことができましたが、自分の中で特に印象に残ったセッションは以下の4つでした。
- ・How to improve your MVP archtecture and tests
- ・Anko試食会
- ・コードで見るFlutterアプリの実装
- ・開発者が知っておきたい通知の歴史
How to improve your MVP archtecture and tests
How to improve your MVP architecture and tests by きりみん
MVPアーキテクチャを実際に適用するとよくありがちなアンチパターン(テストが無かったり、レイヤーに一貫性がないような作りになっているなど)を挙げ、それらを改善していく方法を紹介しているセッションでした。
また、テストを実際にプロダクトアプリに書き始めると起こる難点を改善するため、よりよりテストの書き方(テストのリファクタリング)手法を紹介されていてかなり実践的なセッションとなっていました。
セッションを聞きながら「うんうんわかるわかる……。」となってしまったので参考にしながら改善していきたいなと強く思いました。
1つ1つが具体的に丁寧に説明されていたので、MVPアーキテクチャーを使う際やテストを書く際には非常に参考になるセッションだと思います。
Anko試食会
Anko試食会 by watanave
AnkoというJetBrains公式のKotlinでAndroid開発を行う上で非常に便利になるサポートライブラリがあり、その中でもAnko LayoutsというViewのレイアウトをKotlinで作るコンポーネントにフォーカスをあてたセッションでした。
Androidでレイアウトを組む際にXMLを基本的には書きますが、どうしても肥大化した際に(includeタグ等で共通Viewを切り分けたとしても)読みにくかったりする問題が個人的に持っており、それを解決する良い手段だなと感じました。DSLで記述することによりXMLレイアウトファイルの中から重要な部分だけを抜き出したような記述になるのでパッと見でわかりやすいという利点があるかなという感じです。
また、Kotlinで記述するためコンストラクタなどで状態を受け取ってViewの描画を容易に行うことができる上、コードなので繰り返し文などで「リストを作る程ではないが、数個同じようなViewがある」というのを簡潔に書ける点に魅力を感じました。
セッションの後半ではKotlin−DSLの作られ方をAnko LayoutsのようなDSLを実際に組みながら説明されておりDSL初心者の自分としてはかなりタメになるセッションでした。このセッションを聞いた後にKotlinイン・アクションを読むとDSLへの理解がスムーズになると思いました。
コードで見るFlutterアプリの実装
コードで見るFlutterアプリの実装 by konifar
FlutterというGoogle製でDartで記述するクラスプラットフォームSDKを実務で実際に利用できるのか?というセッションでした。
登壇者であるkonifer氏はDroidKaigi2018のアプリをFlutterでiOS版をAppStoreにリリースしており、そのコードを読んだり動かしてみたところ非常に良い感じがしたので理解を深めるべく聴講しました。
参考 - FlutterでDroidKaigi 2018のiOSアプリを作りました - Konifar's WIP
Flutterと他のクラスプラットフォームフレームワークの違いとして大きいのがUIサポートであり、ライブラリが公式で豊富にサポートされている点でした。また、IntelliJ + Pluginのサポートが大きく、更にはGoogle製なこともありFirebase周りのライブラリも充実していることから「Androidエンジニアがクロスプラットフォームを始めるぞ!」というときにはかなり有用なものなのではないかと強く感じました。
まだ2日前にv0.1.2がリリースされたばかりなので、今後の周りのやっていき力とGoogleの推し具合によってはクロスプラットフォーム開発をやるならFlutterという流れになってもおかしくないなと思います。
自分もFlutterで色々作ってみようと思います(まずはiPhoneを入手するところから)。
開発者が知っておきたい通知の歴史
開発者が知っておきたい通知の歴史 by Keisuke Kobayashi
ネイティブアプリにおいて、通知というのはユーザーにとっては非常に重要な機能です。が、AndroidではAPIのレベルによって大きな変更が通知によく加わります。このセッションではそれらの歴史を振り返りながら、どう実装すればユーザーフレンドリーな通知が実装できるのかを紹介しているものでした。
ちょうどDroidKaigiの週あたりから、業務で通知に関する悩みがあったのですがこのセッションを聞いたら全て解決して翌週にIssueをFixする事ができました。
やはり通知周りはバージョン分岐を行って実装することが必須であり非常に辛いながらもUXをしっかり考えて実装していきたいと思いました。
さいごに
今回DroidKaigiに参加することができて非常に多くの学びを得ることができました。セッションを通しての学びももちろんあれば、アフターパーティーで他のエンジニアの方々とコミュニケーションをしたりして学ぶことも多々ありました。
このような機会を設けて頂いて公式スタッフの方々には大変感謝です。
私も来年やそれ以降ではCfPを提出して登壇チャレンジを行ったり、スタッフとして参加させていただいたりしてAndroid界隈を盛り上げて行きたいなと思いました。
みなさんもAndroidでやっていきしましょう!やるぞ! 〓〓〓
YAPC::Okinawa 2018 ONNASONに参加してきました
普段は渋谷でサーバサイドエンジニアなどやってます。
今回は
YAPC::Okinawa 2018 ONNASON
に参加してきました。
経緯
今回YAPCが自分の大好きな沖縄で開催される、と聞いてこれは参加せねば…と思い、
また少人数でアットホームな感じでまったりと楽しめそうという事から、ほんの軽い気持ちでトークに応募してみましたw
まぁトークのネタも目新しいものじゃないし、どうせ落ちるだろう、、そしたらLTくらいは試してみようかな、と。
…すると通ってしまってびっくりしましたが、こうなったらやるしかないな、と。
前夜祭
小洒落たバー的なお店で乾杯。
酔っ払っていたのでところどころ印象に残っているところだけ・・
---
# 知られざる、Alibaba Cloudを支えるオープンソース
日本からは分からないもう一つのインターネット、というのが印象的でした。
---
次はSpacemacsの話。
@jigyakkuma_ さんの # A Spacemacs Journey
自分も昔からずっとEmacs使いであるだけに気になっていたのですが、次回以降のPerl 5 Layer(?)が入ったらちょっと試してみようかなと思います。
---
お次はLTのお時間に。
応募が多いのか、Perlのワンライナーでトークを抽選、いいですねw
ひたすら飲んで結構酔っ払っておりまして、覚えているものだけ・・
同僚の @oddmutou さんによる、
「クロスオリジンでログイン状態を継続させる(ようにみせる)テクニック」
公の場で久々にSledge の名前が出た気がしますw 良い。
---
続いて @kazeburo さんの
logrotate殺プロセス事件 YAPC::Okinawa 2018 前夜祭 LT/Mystery of logrotate’s death
のお話。
深夜のアラート対応、ログローテートの話はいつも悩まされているだけに、そこをHackするのかwというのが興味深い内容でした。
---
あと、他に特に印象に残っているのが、
@tompng さんの、「綺麗なコードの書き方」
綺麗なコードの発想、これは会場大爆笑でしたw
当日
朝、県庁前に7:30に集合ということで早起き。
その途中初めてのサニーゴも無事ゲットw
で、Wi-Fi完備の快適なYAPCバスに揺られてOISTへ。
当日になっても資料がまだ完成していなかったので、適宜書きながらだったのですが、
印象に残っていたトークをいくつか…
@__papix__ さんによる、
Webサービスを監視するときに僕達が考えたこと
弊社も Mackerel を日々使わせていただいておりますが、
障害対応時のペアプロ/ペアオペの重要性、蓄積と可視化の重要性など、とても共感できる話でした。
個人的には mackerel-plugin-nasne で自宅のnasne監視がツボでしたw
---
@bird_tummy さんの GraphQL をプロダクション導入した結果
GraphQLは個人的にも興味を持っていて、社内勉強会などでもちょっと遊んでいたので聴講させていただきました。
運用編・キャッシュの扱いなど、実際に導入してみないと見えてこないところについての知見が参考になりました。
---
さて、豪華なお弁当を食べた後、いよいよ自分の発表。
ギリギリまで資料を作っていましたw
で、発表させていただいたトークですが、
# Perlを中心としたワンライナーあれこれ
というのをお話させていただきました。
こういった場での発表は初めてなので、テンパって時間とかめちゃくちゃで失礼しました。。
途中、テンパりながらも、阿部寛のホームページネタと素数を数える話がウケてくれたのがちょっと嬉しいw
会場が思ったよりも学生さんが多かったので、これからの人にこそUNIX哲学を意識してもらえるといいなぁ、と。
当日の様子は、以下のあたりにまとめていただいておりました。感謝。
https://togetter.com/li/1205668?page=23
---
@xtetsuji さんの、
WordPress 運用を支える Perl
去年のPerl入学式でも大変お世話になった @xtetsuji さんのトーク。
原則コアモジュール縛りの話、inotifyを使ってS3のホスティング、mod_perlのフィルタ、疎結合・密結合の話などはとても共感できました。
---
ここからは早くどこかに資料をアップロードせねば、というのがあり、ずっとmarkdownをkeynoteに変換する作業をしていたので、あまり他の方のトークを詳しくは聞けませんでした。。
ちなみに最初、MarkdownファイルをPDFにしたのは Marp というソフト。いつもありがたく使わせていただいているのですが、
今回の資料のPDF化では、コード記法の後ろの方の表示が見切れてしまって、
ワンライナーの資料としては致命的な事に気付きました。
で、
markdownからkeynoteを生成する「md2key」を作った
これを急遽使わせていただいて、記法崩れを手直し、ラストの @yappo さんのKeynote くらいまでになんとか修正できました。。
他の方のトークがあまり聞けなくて本当にもったいないことをしました。。
---
その他の方のトークも後になって資料をいろいろと拝見させていただきました。
私家版 YAPC::Okinawa 2018 記事/資料まとめ
↑後でいくつか試させていただこうと考えております。
今回、自分が知っているYAPCにしては珍しく(w)Perl濃度が濃くて自分的にはとても心地よい最高のイベントでした。
運営に関わった皆様、本当にお疲れ様でした!!本気で楽しめました。
次回は東京ですね!
最後に
弊社ではPerlが好きなエンジニアやそうでないエンジニアも募集しているみたいなので,
興味のある方は是非お気軽にどうぞ〜〓
http://www.seesaa.co.jp/recruit/jobs.html
ちゃんとテスト書いてますか?
こんにちわ、モバイルソリューション事業部でサーバーサイドを担当してるアキです
暖くなってきたとともに花粉の季節の到来ですが、いかがおすごしでしょうか。
弊社では週1で持ちまわりで部署の垣根なくエンジニアで集まって技術発表をしております。
今日は先日自分が発表した内容をせっかくなのでブログにも書きたいと思います。
いつも笑いを取ることに力を入れすぎる余り、要約すると内容がないよう。となりますが、沢山しゃべってもこういう場では伝わりきらないので良しとすることにします。良しとしてください。
Q.ちゃんとテスト書いてますか?
そんなタイトルでやりました。
テスト大事なのは当然なんですが、ちゃんと見ればいろんな方法がありますよね。できればフル活用したいですよね。とはいえ、テストって辛い時がありますが、僕だけですか?きっとみんなそうなので、一緒に頑張りましょう!というお話です。
LinterとFormatter
このスライドの一枚を思いついてしまったがタメに今回の題材を決めたといっても過言ではないです。

が、ジェネレーションギャップなのか、全く笑いがおこらなかったのでツライばっかりでした……。
テストコード書いたり、テスト回したりする前にもっとLinterとFormatter活用しましょうよ。というお話。
個人的にJS界隈でのフォーマッタPrettierが良い感じで、さらにES-Lintとの組み合わせが強力で素敵だと思います。ちなみにRubyにもRufoというフォーマッタがありますがイマイチ人気があがってこないですね。でもLinterはRubocopを使わないほうが少ないんじゃないでしょうか。その連携が上手くいくと良いですよね。
エディタでリアルタイムでLintするほか、Pre-commitでフックすると効果的です。Node.js系であればいろいろありますが、一つの例としてhusky + lint-staged、Rubyであればpre-commitというGemがありますので導入も簡単です。Pre-commit時だとキツい場合はPre-pushでも良いかと思います。
要点は、バグを混入させないように自動で防げるものはやったらいいよね、という話。

もう1点、僕が考える運用として「ルールは聖域とする」ことです。WARNINGなどは警告のみで無視できるものも多いです。ただし、無視できるルールを無視してると割れ窓理論的にどんどんルールが無視されていって、結局Lintしてる意味がなくなってきてしまいます。無視していいルールなら、そもそもルール自体の制約を緩めるべきで、検出されたら直しましょう、という意味での「ルールは聖域」です。理想論的な部分もありますが。
ビジュアルリグレッションテスト
視覚的回帰テストですね。そこまでメジャーじゃないものの、BackstopJSなんかは導入が以前より遥かに楽になっててびっくりしました。デザインの変更は意図した変更と意図しないものがあるので、最終的には人の目の判断ですが、それでも転ばぬ先の杖としてかなり有用ですね。
ちなみにコードレベルではなく、見た目レベルでの差分を出すため、例えば同じサイズだけど画像が差し変わってしまった場合なんかも検知できます。モバイルソリューション事業部のサーバーサイドではあまり出番はないですが、使えて損はないですね。
デモをしたんですが、だいぶ私的なものをサンプルに使ってしまったのでここでは残念ながらお見せできません。
ユニットテスト
テストと言えばユニットテストなので、今回はアサーションに絞ったお話です。Rubyのテストツール、Rspecが与えた影響は素晴しいと思います。テストコードがかなり英語と同じ感覚で読めるので、何を意図しているかわかりやすいです。その反面、デフォルトで使ってる限りは、テストに失敗した時に、何が失敗してるかが掴みにくいこともあります。またマッチャが多いため、複雑になってくると相応に学習コストも上がっていきます。

個人的にはテストで詰まった時がツライので、Rspecのような自然言語寄りの思想より、Power-assertを好んでいます。Power-assertの場合、テストをパスしなかった場合の情報がわかりやすく表示されるので何を修正すべきか判断しやすいです。また、マッチャもシンプルなままなのも良いですね。その反面、実装や仕様を把握してないとテストコードからテストの意図を読み取るのはRpec的な自然言語に近いほうが良いかもしれませんね。

余談ですが、RspecでPower-assertを使う方法もあります。
ここもやはりデモをしたんですが、だいぶ私的なものをサンプルに使ってしまったのでまたしても残念ながらお見せできません。
E2Eテスト
Rubyでは既にデファクトスタンダードとなったCapybaraがありますが、今回はササっとサンプルを作ったのでNode.js系のNightwatchでデモをしました。思ったより簡単に書けました。フレームワークやドライバーはたくさんあって書き方も変わりますが、一つ使えると応用が効く範囲ですね。
また、最近特にヘッドレスブラウザの活躍が目覚しいので、CI上で回せる点も良いですね。なお最近ではコーディングなしでテストが作れるような流れもあるので、もはやエンジニアではなくディレクターさんがテストを作ってしまう、ということも可能になりそうな気配です。ここはササっと紹介だけになっちゃいました。
まとめ
いつも業務のテストではRspecばかりですが、今回ビジュアルリグレッションテストを使ってみたり、JESTを触ってみたりしていろいろと知見が増えました。JEST、良いですね。相性もありますがPower-Assertとも組み合わせられますし。ビジュアルレグレッションテストは導入も簡単なので上手く使っていきたいですね。
テストの書き方に困ることはありますが、「どんなテストも無いよりマシ」を胸に、なるべくテストを沢山書いて、安心して開発していきたいと思います。
Let's Encryptでワイルドカード証明書を取得する
今日は、先日から始まったLet's Encryptによるワイルドカード証明書の取得についてかいつまんでご紹介しようと思います。
ドメインの確認プロセス
ドメイン認証型証明書を発行してくれるLet's Encryptは従来、http-01、dns-01という方式を用いて、ドメインの確認を行っていましたが、ワイルドカード証明書の取得を行うには、dns-01方式のみ使用することができます。
http-01方式は、指定されたファイルの存在と内容の確認が行われることで、証明書の取得を行うことができ、自動化の仕組みを実装する難易度は低かったのですが、dns-01方式は、TXTレコードで指定された値を登録する必要があります。そのため、http-01方式と比べ自動化の仕組みの実装には、API操作が可能なDNSサービスを利用するか、自前でのDNSサーバーの運用が必要となります。
取得プロセスの実装
今回は、実際に使用するためではなく、証明書の取得テストをするためだったので、Let's Encryptのstaging エンドポイントを使って確認をしました。
DNSサーバーはRoute 53を使用していたので、API操作は https://github.com/barnybug/cli53などのツールを使うことも考えましたが、とりあえずperlで。と思い、LWP::UserAgentとNet::Amazon::Signature::V4を使用しました。
AWSはAPIのドキュメントが、細かく書いてあるので、それを参考にしています。
https://docs.aws.amazon.com/ja_jp/Route53/latest/APIReference/API_ChangeResourceRecordSets.html
証明書の取得自体は、perlのモジュールもありますが、従来から使用していたツール(https://github.com/lukas2511/dehydrated)と組み合わせて使うので、フック処理にroute53の書き換えをするperlスクリプトを実行するように、実装しました。
コードについては割愛します。(perlで無理にしなくてもいいじゃん説はあるし、今回はプログラムに組み込む訳ではなかったので、aws-cliを使ったほうが楽なのでは?というあなた正解です!)
ハマったところ
Route 53へPOSTしたら、PENDINGとして応答が返ってきますが、実際に数秒ほどクエリの内容が変わるまで時間がかかります。
また、証明書に含めるドメインの数、すなわち、Subject Alternative Names (SANsともいいますが)の数だけ確認の回数が発生するので、そのひとつ前での確認プロセスで入れた値が引けてしまい、エラーとして判定されてしまいました。(example.com、*.example.comというような場合に)
そのため、Route 53へのPOST後、数秒から十数秒ほどwaitを入れて、Let's Encrypt側の確認で、指定された値が引けるように、配慮をする必要があります。
まとめ
今回は、Let's Encryptでのワイルドカード証明書の取得を試してみましたが、自動化していくには、エラーハンドリングは入念にする必要があると感じました。また、ある程度自由度の効くDNSサーバーも必要であることがわかりました。
HTTPSでの配信の難易度については、こういった証明書周辺の歩み寄りで以前比べてかなり下がってきており、シーサーでもいくつかのサービスでそういった変更をさせていただいている最中です。
NoSQLとはナンダ?
それにしてもIT業界人って造語作るの上手いですね!
Cloud、FinTech、X-Tech、IoT、XaaS(PaaS/SaaS/IaaS)、DEATH MARCH、etc...
閑話休題
NoSQLとは、諸説あるようですが「Not only SQL」の略称、総称、標語。
今までのリレーショナル(関係)データベースとは異なる構造を採用している
SQL(Structured Query Language)を利用しないデータベースのことです。
乱暴に定義すると、MySQL、PostgreSQL、ORACLEなどのRDB以外全部です。
どのようなプロダクトがあるのか
結構あります。
NoSQLの一覧
GDBMのような、Key-Value-Store(KVS)もSQLは使わないのでNoSQLです。
Memcached、Redis、DynamoDB、MongoDBなど知名度が高いものや聞いたこともないものもありますが、大手ベンダーやOSSが続々と製品をリリースしていることからもテック界隈のNoSQLに対しての関心や今後の発展が見込めると思われます。
従来のRDBとどこが違うのか
SQLを利用しないデータベースの総称なので製品によってもかなり違います。
なので、利用者が多い(と思われる)MongoDBと比較します。
DB-Engines Ranking
因みにMongoDBは、英単語の huMONGOus(ばかでかい・途方もない)に由来している名前だそうです。
NoSQLとしては、ドキュメント志向データベースに分類されており、ざっくりとですが主に
・スキーマを定義しなくても使用できるスキーマレスである(項目を定義せずにデータを保存可能)
・複雑な検索条件でデータを検索可能
・JSON形式でデータを格納可能(内部的にはBSON形式)
・コマンドの構文でJavaScriptが使える
・拡張性、可用性、冗長性も考慮(スケールアウト、レプリケーションなど)
・画像ファイルなどバイナリデータもそのまま格納可能
・実行処理速度もRDBに劣らない(という計測結果もある)
という特徴があります。
とても便利そう!だけどやっぱりよく分からなかった
ので、実際にインストールして使ってみました。
公式サイトの「Install MongoDB Community Edition on Linux」を読めばサクッとインストール完了(※)
Install MongoDB Community Edition on Linux
$ mongo とターミナルから打てばクライアントアプリのmongo shellが起動します。
The mongo Shell
アプリケーションから利用したい場合は、ドライバが必要となるので使用言語のものをインストールしてください。
MongoDB Drivers
※2系と3系がありますが、JSON文字列でダブルクォーテーションで囲まれた数値でのsortは、バージョン3.4から追加されたcollationメソッドを使わないと文字列としてsortされるため、期待した結果が帰ってこないのでハマりどころなのでインストールするバージョンには、注意してくださいね。
とりあえずクライアント(mongo)へのログインは出来ました。
・・・インストールしたはいいけども用語、コマンドからしてRDBと違う。
show tables; も受け付けてくれない。
show collections; という同等のコマンドが用意されていました。
他にもRDBとはかなり違いますね。
でも、スキーマレスな世界が待っているのでここで心折れずに前へ進みましょう!
RDBMSとの用語対応表やマニュアル
MongoDBの基礎入門 - インストール から CRUDまで
MongoDBの薄い本
MongoDB本家のマニュアル(英語)
読みやすかった順番です。NoSQLすごい!RDBは、忘れてしまえばいいじゃない!(ダメ、絶対)
NoSQL(MongoDB)をお勧めしたい理由
・SQL構文知らなくてもJavaScriptの構文が使えるので敷居が低い
・インストールして即使える(スキーマ定義が不要、テーブル作成も不要!)
・変更が多いアジャイルやスパイラル開発モデルにマッチしている
・RDBを触ったことのないフロントエンド・エンジニアにも扱える
・というかコマンド構文がJavaScriptなのでほぼイケる感がある
・mongoimportなどのツール類も充実している
・とりあえずMongoDBにデータぶっ込めば何とかなる!(ような気がする)
まとめ
他にもMongoDBには、レプリカセット、アービター、(オート)シャーディングなど、とても野心的な機能があるのですが、まだがっつり説明出来ないので今後の課題としたいと思います。
元々は、NoSQLというワードに前から興味があり、MongoDBのドキュメント(本家サイト、ブログ、スライド)などを見ていると既存システムのデータベースのスキーマ設計をするときにアプリケーションは一切無視して正規化や関係を十分考慮して設計すること。
極端に言うとアプリケーションレイヤーは、コロコロ変わる場合が多いが、データは永遠だ!最初のスキーマ設計は重要!と言う先人たちの定石とは、全く違ったアプローチで開発が出来ることに驚きました。
また、SQL未経験者でもJavaScriptライクな構文なら比較的学習コストをかけずに覚えられることやシステムでまずプロトタイプを作りたいけど画面などのアプリケーション側から作っていきたいので、RDBMSでテーブル設計定義して項目増減で見直しするとか時間がかかるので、まずサクッと作りたい時などにMongoDBは最適です。
今回は、飛ばしましたが、複数セカンダリーやシャーディングを使ったスケールアウト構成にすれば実運用でも十分利用出来るレベルです。使いたい・・・。
今回は、MongoDBの上っ面を触っただけの ”紹介” なので興味のある方は、ドキュメントなどを読むと繰り返しになりますが、野心的で使い勝手の良いMongoDBを好きになると思うので個人的に強くお勧めします!
(今回も渋谷感ゼロだったな・・・動画でも貼ってお茶を濁すか・・・)
Gitにまつわるエトセトラ
新年度ですね。アキです。いや、季節は春なんですが、今回のブログ担当が僕、アキです。どうも。
弊社でも多くの開発現場と同様、Gitでのバージョン管理を行なっています。フレッシュな若者達がうっかり変なコミットをしたり、戻そうとして泥沼にはまったり、勢いでforce pushしてしまったりするんでしょうか。ワクワクしますね!
今回は各種コマンドでどうこう、というお話ではなくそれ以外のGitの話をしてみようと思います。
基本にて王道のコミットメッセージついて再考察してみる
簡単ですが奥が深いと思っているコミットメッセージ。結局のところログなので大切なことは、
- 可読性を持つこと
- 被検索性を持つこと
が大前提ですね。後から探すのが楽で、見たらすぐ何かわかる、というのが理想です。
さんざん今まで議論され尽してきた感がありますが、今いちど、このルールを再確認しましょう。
How to Write a Git Commit Message
また、commitizenというプロジェクトがあります。
これはルールにのっとって対話式にコミットメッセージを作成するCLIなんですが、デフォルトの設定が秀逸です。
タイプ(スコープ): タイトル
というフォーマットを使います。
タイプは例えば、fix、feat、doc、build、choreなどが入ります。
スコープはある場合記入し、タイトルのところには先程コミットメッセージのルールにのっとったようなメッセージが続きます。
そしてもちろん必要な場合は3行目から詳細を書きます。
個人的には日本人のみで構成される開発チームの場合は可読性と検索性に考慮していれば日本語コミットでも良いと思っています。ただし、英語の言語特性では動詞、つまり一番核となるものが最初に来ます。そのため分かりやすいメッセージになりますが、日本語の言語特性の場合、最後に来ることが基本になります。
日本語でわかりやすいコミットメッセージにしようと思ったら、英語よりさらにルールを追加するのが良いでしょう。例えば、
修正: ◯◯のバグ
とか
機能: ◯◯の実装
のように。先に動詞をもってくる、体言止めにする、読点はつけない、みたいにすると良さそうです。また同音異義語や同じような意味も多いので使う言葉をあるていど絞ったほうが良いかもしれません。最初に言った被検索性に留意したいですね。
Protected Branchを使う(GitHubの場合)
GitのシステムにGitHubを使っているなら、Protected Branchの設定ができます。これは設定したブランチに対してforce pushが効かなくなるように保護してくれるものです。例えばmasterやproductionブランチが重要な場合、運用コストがかからないので設定しておくのが良さそうです。
その他にもstatus check機能で、PullRequest時にCI上のテストが通らないとマージを行なえない、など設定することも可能です。
Git hooksを活用する
GitHub上でCIによるテストが回るように、ローカルでも特定のGitコマンドをトリガーにして特定の動作を自動でおこなうことができます。これはGitHubではなくGit自体の機能なのでどのような環境でも使うことができます。
例えば、コミット時にLinterやformatterをかける、Push時にテストを回す、など。また、工夫次第では特定のブランチの場合、プッシュをリジェクトなんていうこともできます。
設定の仕方は/.git/hooksにそれぞれのトリガー用のシェルスクリプトを置くだけです。
僕の場合はmaster、もしくはproductionブランチにプッシュしようとすると警告を出して確認するスクリプトが走るようにしています。これは自分ではmasterからトピックブランチ生やして作業していたと思ったら生えてなかった! ってことがあったからです。上で説明したProtected Branchではforce pushしか防げないので、両方設定するよにしています。
具体的には以下のスクリプトを/.git/hooks/pre-pushとして保存するだけです。
(実行権限の付与が必要です)
#!/bin/bash
while read local_ref local_sha1 remote_ref remote_sha1
do
for branch in "master" "production"; do
if [[ "${remote_ref##refs/heads/}" = "${branch}" ]]; then
echo "警告:重要なブランチにプッシュしようとしています。正気ですか? [y/N]"
exec < /dev/tty
read ANSWER
case $ANSWER in
"Y" | "y" ) echo "プッシュします";;
* ) echo "プッシュをキャンセルしました";exit 1;;
esac
exit 0
fi
done
done
Git Hooks を活用するための便利なもの
Rubyでは、pre-commit時だけでよければpre-commit、全てのトリガーに対応するならばovercommitなどがあります。
特に後者はカスタムスクリプトも走らせられるので、上で説明した自作のpre-pushなどを併用することができます。
またNode.js系が使えれば、huskyが有名ですね。こちらはpackage.json内にトリガーに応じたコマンドを記述するので|や&&でつなげば自作スクリプトも併用できます。特にlint-stagedと組み合わせることが多いです。
テンプレートを活用する(GitHub)
GitHubを使っているならIssueやPullRequestも使っていると思います。実はこれらはテンプレートを決めて、新規作成時に自動で挿入してくれる機能があります。
使いかたはプロジェクト直下、または/.github内にPULL_REQUEST_TEMPLATE.mdとISSUE_TEMPLATE.mdをそれぞれ置くだけです。
例えば要望のIssueのテンプレートなら
## 要望概要
## ゴール
<!-- この要望を達成したと見なす条件 -->
## タスク
- [ ] タスク1
とか。PullRequestのテンプレートなら
## 概要
FIX or RESOLVE or CLOSE: #
## 内容
## 想定する影響範囲
## 動作に必要なコミットに含まれない変更
<!-- e.g. 環境変数, DBの更新 など -->
## 補足
とか、実はまだ完全に定まってはいないんですが、ちょこちょこ使っています。
テンプレートの効能として、ある一定のクオリティを保った内容になるとともに、ガイドができて内容を書きやすくなるので、積極的に使うほうがいいと思います。特にIssueについては非エンジニアの人が作る開発現場もあると思います。そういう時にテンプレートがあれば、まず状況を確認するの必要な情報が入りやすくなるのでオススメです。
IPv6の名前解決が遅い(ことがある)
春になり出会いの季節ですね。名前を覚えるのが苦手な自分にはつらい季節です。ありがたいことに弊社弊部にも新人の入社があり、幸いにも覚えるのが苦ではない人数であったため何とかなりました。
今日はそんな名前解決(?)にまつわるエピソードです。
外部サービスのAPIが遅い
とある案件でモバイルアプリ用のAPIをRailsで開発していたときの話です。そのモバイルアプリではとあるサービスのSDKを利用していたのですが、そのSDKで度々エラーが発生していて主要な機能が利用できないといったことが起きていました。
事象としては、モバイルアプリ上で特定の操作を行った際にSDKがコールバック先のURLにリクエストを送り、5秒以内に応答がなくタイムアウトエラーになるというものです。
コールバックのリクエストをRailsで受けて外部サービスの提供するAPIからのレスポンスデータを使って応答を行っていましたが、Railsの処理はDBアクセスがあるものの薄い処理となっているため、③のAPIのレスポンスが遅いものと思い調査を始めました。
実はIPv6の名前解決が遅かった
APIへのリクエストにはfaradayとfaraday_middlewareを使っていたためドキュメントを参考にレスポンスタイム(前図の②と③)をログに出力してみましたが、いずれも数ms程度で応答されておりAPIが原因ではありませんでした
アプリケーションの実装で遅くなりそうな箇所がやはり思い当たらないため、リクエストの前提となる名前解決に問題があるのではと思いtcpdumpでログを出力してみました。するとIPv6の名前解決が遅くタイムアウトの末にリトライが行われていることが分かりました。
(AAAAレコードの取得がタイムアウトになり再度リクエストが行われているログ)
11:01:42.081559 IP 1.1.1.1.51266 > dummy.jp.domain: 64983+ A? api.service.com. (38)
11:01:42.082310 IP dummy.jp.domain > 1.1.1.1.51266: 64983 2/3/3 CNAME cname.api.service.com., A 2.2.2.2 (187)
11:01:42.082431 IP 1.1.1.1.33833 > dummy.jp.domain: 21547+ AAAA? api.service.com. (38)
11:01:47.085722 IP 1.1.1.1.33833 > dummy.jp.domain: 64983+ A? api.service.com. (38)
11:01:47.086453 IP dummy.jp.domain > 1.1.1.1.33833: 64983 2/3/3 CNAME cname.api.service.com., A 2.2.2.2 (187)
11:01:47.086582 IP 1.1.1.1.58653 > dummy.jp.domain: 21547+ AAAA? api.service.com. (38)
11:01:48.634999 IP dummy.jp.domain > 1.1.1.1.58653: 21547 1/0/0 CNAME cname.api.service.com. (69)
IPv6を無効にするも改善しない
IPv6を無効化の設定を施してサーバーを再起動してみますが、IPv6の名前解決のリクエストが依然行われている状態でした。アプリケーション以外(curlなど)で名前解決を行うとIPv4の名前解決のみ行われるため、アプリケーションもしくはRubyの問題であると予想されます。
Rubyを再ビルドしてみることも考えましたが、サービスが稼働中のなかで安全に行える環境ではなかったため他の手段を探しました。
faradayのアダプタを取り替える
faradayにはhttpリクエストを行うためのアダプタを選択できる機能があり、最終的にtyphoeusというライブラリが提供しているアダプタに置き換えることでこの問題を解決しました。
選定理由としてはtyphoeusはlibcurlのラップした実装なため、curlで期待する動作が確認できていたこともあり効果があると踏んだためです。
まとめ
「IPv6の名前解決が遅いのでIPv6を無効化した」という話は調べてみると沢山ありましたが、単純に無効化しただけではダメだったというケースとして今回記事にしてみました。
faradayのようにアダプタを選択できる実装になっていると、利用者は安定したインターフェースを利用しながら内部の実装を取り替えられるので嬉しいですね。
でもIPv6の名前解決が早くなって同じ問題に悩む人がいなくなる方がもっと嬉しいですね!
モブプログラミングをやってみました
こんにちわ、アキです。全国的に梅雨シーズン到来ですね。ジメジメして不快指数も上がってくる季節ですが、気分はいつもカラっと行きたいものですね。そしてそんな気分が晴れるように元気にコーディングしていきたい方法として、モブプログラミングなんていかがでしょうか。
モブプロをやってみました
モブプロとは
そもそもモブプロの前にペアプログラミングのお話。ペアプログラミングとは
- 1つの画面
- 1つの端末
- 2人のエンジニア
という構成で、コードを書く人 = ドライバー、書いてなくてサポートする人 = ナビゲーター という役割でプログラミングをしていくスタイルです。イメージとしては車などのラリーのように、ハンドルを握る人とそれを全面的にバックアップしてサポートするところから来てるようです。
モブプログラミングはこれをベースにナビゲーターを複数人にして、みんなで一つのコードをやっつける、という手法です。そうすることにより活発なコミュニケーション、意見交換がされながらコードが発展していきます。
このドライバー、ナビゲーターの役割は一度決めたらそれきりではなくタスクの節目や時間単位を目安に適宜交代していきます。
きっかけ
きっかけは僕がモブプロの勉強会に参加してまるで天啓かのように感銘を受けたから、と言ってしまえばミもフタもないんですが、ちょうど4月から弊部にも新人が入り、チーム的なお作法を共有する場、お互いの理解を深める場、先輩と後輩の垣根を低くする場として上手く活用できそうな気がして試験的に初めてみました。
やってみてわかったこと
モブプロとペアプロは別モノ
ペアプロの場合
ペアプログラミングの場合、技術レベルが同程度なら良いんですが例えば今回のケースのような新人加入時のように技術レベルに差が明確な場合、意外に難しいと思います。
1対1になってしまい、そこに差があると結局先輩の言うとおりに手を動かすだけになってしまいがちです。また後輩側が良い意見がある場合でも遠慮してしまったりでなかったことになってしまうことにもなるでしょう。
モブプロやペアプロが周りの助けを借りながら出来る強力さがある一方、ドライバーは思考停止してもできてしまいます。この場合、先輩は後輩に知見をどんどん伝えていきたいところですが、思考停止してしまうとお互いに良い効果が生まれません。
という理屈で、実力差がある場合のペアプロはなかなか難しいことを痛感しました。
モブプロの場合
ナビゲーターが複数という状況が上手く回るきっかけになります。![]()
複数の視点を持ち、複数の意見が聞ける、コンセンサスを得ながら進む心強さがあります。また心理的にも時間的にも余裕が生まれやすく、実力差や先輩後輩関係があっても必要以上の緊張感を負うことなく取りくめました。
まとめ
- 他の人の強みや弱みを知るきっかけになる
- リアルタイムにコードを書いてたり意見を出し合うとレビューよりも如実に相手の考えがわかりました
- 楽しい
- ただしもちろんコミュニケーション自体を負担に思う人も居るはずなので配慮は必要
- ノせる力が必要でした
- 特に今回のように自分だけ経験者の場合「モブプロ良いね」って雰囲気まで持っていくのにノせる為の強引さみたいなものは必要でした
- 心理的安全性が高い
- これが一番大きな効果であり、一番の利点な気がました
- 設計やコードの方針のコンセンサスがちゃんと取れていること
- みんなで協力する共闘感
- これが一番大きな効果であり、一番の利点な気がました
疑問
と、ここまで「モブプロ良いぞ」って説明したところでいくつか質問が出たのでその答えを。
(人的、時間的)リソースもったいなくない?
モブプロがいくら良さそうでも、個々が分担して平行作業したほうがよっぽど効率的に進む気がするという御意見、ごもっともです。
ただし、それはコーディングだけをとってみれば、な実感があります。
通常、開発が進んだらプルリクエストがありレビューする流れというのが一般的だと仮定した時、レビュワーはレビューする段階で初めてコードを見ます。そこからプルリクエストの意図、実装方針や内容の意図、各コードに異常がないかのチェックなどを行なっていくことでしょう。その間、当然レビュワーは自身の別の事は行なえないですよね。
モブプロの場合、意図も方針も納得ずくのコードができあがるため後からレビューする手間もほぼありません。そこまでトータル的に見た場合、決して人的、時間的リソースがもったいないことにはならないでしょう。
全部モブでやったほうが良い?
いえ、モブで解決にするのに適さない課題もあるなあという実感もしました。
- スコープが広かったり腰を据えてやるべき課題
- 調査
- バグ探し
- 実験的な実装
調査やバグなど情報のインプットと整理がメインの作業に関しては、モブでやったから効率が上がるわけでもなさそうです。また、実験的に試行錯誤する場合も同様です。
まとめ
今現在は僕の所属するモバイルソリューション事業部のサーバーサイドで試験的にやってみている状況です。仕掛け人は僕ですが、なんとか他のメンバーの皆さんにも好評をいただき週一ぐらいのペースで時間を設けて続けています。
今回、社内勉強会で他のチームや部の方々にも知見と楽しさは共有できたと思うので徐々にその波が広がっていったら嬉しいなあ、と思う次第です。
ジメジメした季節もワイワイして乗りきっていきたいですね!
Gitのコミットストラテジーを再考する
梅雨なんて一瞬で過ぎさったかのように明けてしまいまして、毎日暑い日が続きますね。どうもまた僕です、アキです。そしてまたGitの話題です。
以前「Gitにまつわるエトセトラ」ということでGitについていろいろ書きましたがその続きと捕捉のお話になります。
コミットフレンドリー
コミットメッセージには相変わらず悩みますね。前回も触れましたが個人的に以前からcommitizenを導入して使っています。
これはgit commitをgit czなどのコマンドに置きかえて、なおかつ対話的にコミットメッセージを作るラッパーライブラリです。もともとAngularJSなどで制定されているGit Commit Guidelinesに沿ったもののようで、Vue.jsでも同様のものが見られます。
これを使いだして以前よりは楽にコミットメッセージが書けるようになったのと、副次効果としてはこのメッセージでコミットの区分分けをすると逆説的にコミットの粒度や範囲もルールにのっかるようになってきます。コミットメッセージと変更内容の整合性が良い感じになって感じはあります。
これは是非他の人にも使ってもらいたいし、仲間に「貴様のコミットメッセージはわけがわからん!」と面と向かって言えないToo Shy Shy boyなので、ツールで誤魔化す作戦にでることにしました。
といっても単純に対話的に作る部分の質問分と選択肢を日本語に翻訳しただけです。せっかくなのでNPMで公開もしてみました。
cz-conventional-changelog-ja - npm
(実はNPMで公開するのは初なので不備があるかもしれません。自分でも見なおして修正していきたいです。)
使い方はcommitizen - npmを読んでいただきたいんですが、設定を"path": "cz-conventional-changelog-ja"にすれば大丈夫なはずです。
fixなのfeatなの、どっちなの?
実は今まで使ってきて機能追加なのか修正なのか、両方なのか、悩むことがたまにあったんですがこのパッケージをNPMに上げる過程でなんとなくわかってきました。
元であるcz-conventinal-changelogにはsemantic-releaseというライブラリによってリリースバージョンを自動で生成してるんです(便利!)が、仕組みとしてはセマンティックバージョニングに準拠していてfixがあったらpatch、featがあたらminorのバージョンが上がるようになっています。
これも逆説的に考えると今行なった変更がminorバージョンを上げるような機能の変更(or追加)ならfeatだし、patchレベルであればfixだな、と考えることができるようになりました。万事OKなわけではないですが、悩んだときの一助になって良い感じです。
Pre-commitフックをちゃんとする
前回も言及しましたが、僕は基本的にほとんどのプロジェクトでhuskyでhookしてlint-stagedでコミット対象にLintを噛ませてます。
良く紹介される方法でも十分効果的ではあるんですが、対象がファイル単位になるためhunkに分けたい場合でもファイル単位で上がりなおってしまう、ということがありました。lint-stagedのリポジトリをつぶさに見ていたらhunk対応版の方法があがっていたので共有したいと思います。
package.jsonを以下のようにします。
{
...(中略)
"scripts": {
"cz": "git-cz",
"precommit": "lint-staged",
"stash-unstaged": "git stash save -k 'pre-linting-stash' >> /dev/null",
"lint-staged": "lint-staged || (npm run pop-stash >> /dev/null && exit 1",
"pop-stash": "git stash && git stash pop stash@{1} && git read-tree stash && git stash drop"
},
"pre-commit": [
"stash-unstaged",
"lint-staged",
"pop-stash"
],
"lint-staged": {
"*.{js}": [
"eslint --fix",
"eslint"
]
},
...
}
lint-stagedの前後にgit stashによる退避と戻すのを挟む方法ですね。
この方法を導入してからhunkを多用気味な僕としては心に平穏が訪ずれました。
ちなみに業務ではRubyを、プライベートではVue.jsを良く触りますが、lint-stagedを上手くやってやればTypeScriptでもRuby+Rubocopだろうとどんとこいです。
Rails 5.1以降からYarnが正式に使えるようになったので、嬉しい副次作用です。
また、もちろんESlintにはPrettierも同時にかかるように設定してます。
まとめ
lint-stagedまわりはプロジェクトにNode.js系の要素がないとちょっとツライところですが、最初にご紹介したCommitizenはグローバルインストールでもいけるのでどんな言語のプロジェクトにも対応できますね。
もうちょっと上手く拡張してプロジェクトごとにタイプの設定を載せてルール付けるのもアリかもしれませんね。日本人だけのプロジェクトであればタイプとスコープは英語にして、その後のメッセージは日本語でも良いかもしれません。重要なのはある程度決まった型にそろえる、ということですね。
コード中にしろコード外にしろ、フォーマットをある程度揃えるのは本質じゃないところの統一することでノイズをカットして本質を注視しやすくする。そしていろいろサクサクやっていくぞ! という意気込みです。
BoomAppGamesのゲーム攻略Wikiシステムの紹介
弊社の運営しているサービスの一つに,BoomAppGamesというゲーム情報ポータルサイトがあります。
その一環として,ゲーム攻略Wikiを昨年より多数運営しています。上記URLのページ上部にある「攻略中のゲームWiki」にリンクが貼られているものです。
例
- FGO攻略Wiki - Boom App Games
- ドールズオーダー(ドルオダ)攻略Wiki - Boom App Games
- デジモンリアライズ(デジライズ)攻略Wiki - Boom App Games
以前から度々twitter等で話題になる,集合知によらない,新しいタイプのゲーム攻略Wikiサービスですね。
弊社では旧来より,ゲームやそれ以外でも自由に誰でもwikiを作成し運営できるサービス「Seesaa Wiki」も運営していますので,よければこちらもご利用ください。
今回はこのゲーム攻略wikiの技術てきなことについて軽く書きます。
*
インフラは全てAWS上に構築しました。
draw.ioにて雑な絵を描いたので以下に示します。
サーバーアプリケーションはEC2上のdockerコンテナで動いています。EC2内にnginxが立っており,各アプリケーションにつながっています。アプリケーションはPerlで書かれており,PSGI/Plack,Starletを使用しています。
メインとなるwikiのページ用のアプリケーションとは別で,ユーザーのアカウントをまわりのページやAPIを担当するコンテナが分けられています。
それぞれ負荷の大きさが異なることが予想されているので,将来的に分離し,EC2からECSにし,スケーリングしやすくすることを前提とした設計です。
DBはMongoDBを使っています。AWS公式でマネージドサービスが無いので,EC2上で作っています。
mongoはReplica setを組んでおくと突然死しても自動で切り替わってくれるので便利ですね。
なお何度か実験したのですが,primary交代の際にアプリケーションを見ていると10秒ちょっとダウンタイムが発生することがわかりました。ミッションクリティカルなモノには採用できませんね。
KVSはmemcachedを使っています。本当にキャッシュにしか使わず,シンプルな場合は,メモリ効率の良いmemcacheのほうがふさわしいかな,と。
ElastiCacheを使うと,本当にマネージドは楽で良いなあというお気持ちになりました。
画像はS3に保管されます。
高解像度の画像が保管されるのですが,貼り付けられている箇所によって適切なサイズに圧縮されるように,API Gateway+Lambdaを用いてリサイズする仕組みを作りました。サイズをURLパラメータに入れており,パラメータの内容別にCloudFrontでキャッシュ(Behaviorの「Query String Forwarding and Caching」をホワイトリスト制に)しているため,次回以降の閲覧では高速に配信しています。
wikiのトップページや記事ページもCloudFrontでキャッシュしているのですが,記事更新の度に該当URLのキャッシュをinvalidationし,最新の内容が出るようにしました。また,記事下のコメント欄等は別途APIで取得するようにしこれも最新のものが出るようにしています。
このサービスを作っているときに,ちょうどdev.toや日経電子版とかがバズっていて,よし高速化やっていくぞという気持ちが発生して,そこそこ速く見れるようになりました。
Cache-Controlも適切に設定し,gulpでJSとCSSを一つに圧縮したりもしました。
CDNでのキャッシュを効かせにくいページでもそこそこ速くレスポンス返せるように,アプリケーション内でmemcachedでのキャッシュを多用しDBへのアクセスを大幅に減らす等のチューニングも行いました。
GoogleのPageSpeed Insightsにかけてみると,以下のようなスコアになりました(2018/07/27現在)。
速度は早いらしいですが,まだまだ最適化が足りないようです。
他社の競合サービスさんに追いつけ追い越せの気持ちで,頑張っていこうと思います。
*
弊社ではAWSでのインフラ構築やWebフロントエンド&サーバーサイドプログラミングに興味のあるエンジニアを募集しています!
募集中の職種ページを是非ご覧ください。
突撃!となりのキーボード
なんとなく気が向いたので,弊社エンジニア数人にどんなキーボード使っているか聞いてみました。
原文ママであるため,文体が人によって異なっておりますが,ご了承ください。
tanaka
いまお使いのキーボードはなんですか?
MacBook
そのキーボードに至った経緯を教えてください。
自分以外のPCを触る時のため
@msa_uccky
いまお使いのキーボードはなんですか?
Macbook
そのキーボードに至った経緯を教えてください。
キーボードが変わると作業効率が悪いので、標準のキーボード+簡単な設定変更のみに落ち着いた。
作業先に常設しておく訳にもいかず、持ち運ぶのが面倒くさかったので。
テツ
いまお使いのキーボードはなんですか?
MacBook Pro (Mid 2014) の備え付けキーボード。
そのキーボードに至った経緯を教えてください。
家に RealForce があるのでそれを持ってこようと思ったこともあるが、MacBookは素のキーボードで結構快適なので、そのまま使っている。
キーボードとタッチパッドが一体化していて両者がすぐ近くにあるので、手の移動距離が短いのも良い。RealForce+マウスにすると、手の移動が増える。
以前いた職場では、デスクトップPCに付属していたキーボードがシケた打鍵感だったので、RealForceを持ち込んでいた。MacBookキーボードの打鍵感はけっこう好き。
その他キーボードについて好きなだけ語ってください。
Dactyl Keyboard というのが、なんだかすごそう。
ErgoDox みたいなセパレート型なうえに、 Kinesis のような立体配置になっている。
CADデータが公開されている。 https://github.com/adereth/dactyl-keyboard
ErgoDoxの公式サイトにて、派生系の一つとして紹介されている。 https://www.ergodox.io/#dactyl
*
(編集者)
まずはじめに御三方,職場ではラップトップに備え付けのキーボードを常用している派の回答でした。
他人のPCを触ることや多い役職になると大変そうですね(すっとぼけ)。
常に備え付けキーボードを触っておくと,出先の喫茶店などで軽くPC開いたときに何ら違和感なく作業できてよさそうですね。
Ryoth+
いまお使いのキーボードはなんですか?
東プレ REALFORCE91 UBK
そのキーボードに至った経緯を教えてください。
Macbook標準キーボードを使っていたが、肩こり、腰痛などの軽減、姿勢維持の為、外付けキーボードに移行。秋葉原で試打しまくって、打ち味、打鍵音、コスパのバランスを考えてチョイス。
*
(編集者)
備え付けキーボード常用のメリットもありますが,やはり姿勢が悪くなりがちなのが気になるところです。
弊社有数のヘルシープログラマ(たぶん)なRyoth+さんからは健康に焦点を置いた回答が得られました。
baba
いまお使いのキーボードはなんですか?
Magic Keyboard 2
そのキーボードに至った経緯を教えてください。
常用していた Magic Keyboard 1 が古くなったので買い換え
その他キーボードについて好きなだけ語ってください。
キー配列と押した感じが割とよくコードを書きやすいので。Macbookと統一感も出ていいよ。
*
(編集者)
備え付けのキーボードと操作感を変えることなく姿勢を良くするためにApple製のキーボードを代々使っているbabaさん。実に合理的だと思います。
アキ
いまお使いのキーボードはなんですか?
ErgoDox EZ(Cherry MX 赤軸)
そのキーボードに至った経緯を教えてください。
エルゴノミクスデザイン好きが高じてKinesisを使いはじめたものの、セパレート型の自由度が羨しくなりErgoDoxに乗り換え。
送料や為替を含む金額、保証、 脚付きなどを考えた結果、自分で組み立てるタイプではなく完成品のErgoDox EZにしました。
その他キーボードについて好きなだけ語ってください。
Kinesisの時もそうでしたが、修飾キーやSpace, Enter, Backspaceなどのキーを親指周りに寄せるという思想が好きです。 ErgoDoxの場合ファームウェアレベルでキー配置を書き換えることができるものの、SandSなどの1キーの押し方で挙動を変えるようなものはKarabiner-Elementでやっています(同時押しの判定が異なるため)。ちなみに日本語入力はSKK派です。
外出時や会議室に移動した時にラップトップにビルトインのキーボードを触る場合や自分のキーボード以外を触ることも少なくないためベースになっているキーマッピングはあえてQWERTYを大きく外れないようにして、戸惑わないようにしています。
ハードウェア的にはO-リングを噛ませていますが、今後いろいろと余裕が出たらキーキャップを変更して静穏赤軸に換装したいと思っています。 親指周りもホームポジション的にわかりやすくするためにダイモのエンボステープを貼っています。
分割型の利点を利用して中央にラップトップを置きトラックパッドは本体のものを使っています。実は自宅でもErgoDoxですがそちらでは椅子の肘掛けを拡張したところにErgoDoxと外付けトラックパッドを置いてます。
余談ですがサブディスプレイの下に鎮座しているライオンはテストを書くことの啓蒙です。
やぎにい (@yaginier)
いまお使いのキーボードはなんですか?
Let's Split (Cherry Linear Grey軸)
そのキーボードに至った経緯を教えてください。
元々メカニカルキーボードが好きで、中2あたりの頃からMajestouchを使っていました。
左右分割のキーボードを使いたくて、一時期はMajestouch Ninjaを2つ置いて使う運用してましたが場所をとるのでやめました。
キースイッチは以前ヨドバシで偶然触ったBLACK PAWNシリーズの超レア軸として置いてあったLinear Grey軸の感触が忘れられなくてチョイスしました。
その他キーボードについて好きなだけ語ってください。
分割キーボードの間にトラック(ボール|パッド)を置く部の部員なのですが、最高の感情になれるので入部をおすすめします。
Let's Split以外にはHelix,Gherkinキーボードを自作したりしました。
Helixは自宅で、Gherkinはオンラインゲーム用のキーボードとして大活躍しています。
自作キーボードは軸も選び放題な上にかわいいキーキャップをつけて毎日が楽しくなるので本当におすすめです。かわいいは正義。
僕は自作したキーボードを叩くために毎日働きに来てるようなものです。手段の目的化が激しいです。
*
(編集者)
ナウなヤングにバカウケの左右分割キーボードをお使いのお二人でした。
肩が開くと人間工学的に良いらしいです。
うすき
いまお使いのキーボードはなんですか?
Magic Keyboard(JIS配列)
そのキーボードに至った経緯を教えてください。
iMacを買ったら付いてきたのでずっと使ってます。職場では英語入力なので若干混乱しますが、なんとかなってます。
*
(編集者)
会社支給のラップトップの備え付けキーボード(何も指定しなかった場合US配列)と普段遣いのキーボードの配列が異なってしまう事故,よくある話なのでお互い意思疎通がんばっていきたいです…。
seto
いまお使いのキーボードはなんですか?
REALFORCE TKL SA / R2TLSA-JP3-BK
そのキーボードに至った経緯を教えてください。
みんながいい!って言ってたので、同じ系統のを使っていたが、まことにいい気がするので、買った。
その他キーボードについて好きなだけ語ってください。
好きなものを使えばいいのでは。
*
(編集者)
長いものに巻かれるのもよし,好きなものにするのもよし,ですね。
むとう(@oddmutou)
いまお使いのキーボードはなんですか?
Majestouch MINILA JP68キー 茶軸
そのキーボードに至った経緯を教えてください。
学校に置かれてあったHHKBを触っていてコンパクトなキーボードに惹かれたのですが,Fnキーの位置が気に食わなかったのと,当時HHKBにBluetoothモデルがなかったため,これにしました。ちなみに家ではBluetoothモデル(Air)の青軸を使っています。
親指にFnキー(イマドキの自作キーボード的言い方ならレイヤー変更キー?)は良いものです。
*
(編集者)
わたしです。
最後に弊社最古参エンジニア(役員除く)(たぶん)のtecklさんです。
@teckl
いまお使いのキーボードはなんですか?
MacBook 標準キーボード(US)
そのキーボードに至った経緯を教えてください。
昔は長い間ThinkPad R30のキーボードを使っておりトラックポイントの使い心地や打鍵感など気に入ってました。
その後、ThinkPadからVaio Type P、Windows Mobile機、MacBook Air 11, MacBook 12-inchを使うようになり、Happy Hacking Keyboard 、各種Bluetoothキーボードなど、いくつか試してきました。
初期のAndroid機時代は、Bluetoothキーボードは結構気に入って使ってました。
元々キーボードには大きなこだわりはなく、どれも特に大きな不満もなかったんですが、次第に会社や自宅以外の場所で作業する事が増えていきました。
そうなると、外に大掛かりなキーボードを持ち歩くのは荷物の都合上面倒くさくなってきたので、結局標準のMacBookキーボード(US)に落ち着きました。
どんな良いキーボードでも、モバイルしてノマド作業するには、キーボードやデュアルディスプレイなどに慣れてしまうと、いつもの環境と違ってしまうのでいざという時に作業効率が落ちてしまいます。
そんな感じで、結局現在ではMacBookの標準のキーボードに慣れてしまうのが最も楽だろう、ということで今の所考えています。
MacBook 12-inch 2016 の第一世代バタフライキーボードですが、最初は打鍵感が薄くてちょっとだけ戸惑いましたが、比較的静かなカフェなどで作業してもそこまで音もせず、今では完全に慣れて結構快適です。
*
(編集者)
皆さんご協力ありがとうございました。
このように様々なキーボードを使うエンジニアが働く弊社では,キーボードに興味のあるエンジニアもそうでないエンジニアも募集しております。よろしければ募集中の職種ページもご覧ください。