Kotlin 入門

f:id:nemuzuka:20190501150617p:plain

色気づいてサーバサイド Kotlin に興味を持ち始めたので勉強してみました。

今回のコード

構成

  • SpringBoot: 2.1.4.RELEASE
  • Kotlin: 1.3.30
  • あと使用してるのはこの辺見てください

内容

JSON 返す API サーバとして作ってます。

Repositry

とりあえず SQL 実行できればいいと思ったので、使いづらいと思いながらも JdbcTemplate を使いました。

コンストラクタで JdbcTemplate をインジェクションする感じです。
ここのテストは H2 にアクセスして実際に SQL を発行します(application-unittest.properties を見てる)。テストすべきは SQL ですからね。
FlywayTest でテスト用の Fixture を入れてます。
JdbcTemplate でないとすると、選択肢としては Spring JPA なんでしょうか。ScalikeJDBC みたいなの無いかしら。

Service (依存 class を Injection するケース)

Repositry のように依存する奴は Mockito で Mock 化します。 昔は Mock のメンテコストが割と高かった気がするので使わないようにしてたのですが1、最近は簡単に使えますね。
Kotlin で Mockito 使うなら Mockito-Kotlin 使うべきですかね。 Mockito-Kotlin との出会いのきっかけ

Controller

依存する奴は Mockito で Mock 化するパターンで。
正常パターンは大丈夫っぽいですが、パラメータの validation とかは Server 立ち上げないとできないのが、アレだなと思いました(Kotlin 関係ない)。

Controller のパラメータとか

この辺が Kotlin でよかったと思えるところでしょうか。
data class にのアノテーションでちょっとハマりました(field: の辺り)。
JSON にしても@JsonProperty 効かなくて焦りました。 field: との出会いのきっかけ

body パラメータの validation がアノテーションで定義できるのは嬉しいですけど、Controller 呼び出し時のエラーハンドリングが面倒なのは皆さまいかがお過ごしでしょうか(Kotlin 関係ない)。

Integration

server 立ち上げて実際に API 呼び出すパターンです。
H2 にアクセスして SQL 発行します(application-integrationtest.properties)。

レスポンスの JSON の verify に JsonAssert 使ってるのですが、最近の人は何を使っているのでしょうか。org.hamcrest.Matchers 使うのがアレな気分です。

感想

  • Kotlin について
    • Java + lombok より書きやすい気がします
    • 名前付き引数 + data class の copy 最高
    • @Slf4j は欲しいなぁ...
    • 明示的に open にしないと継承できないとか固くかけるのが良い
    • null 安全の為に Java のライブラリ使うとき面倒だな、と思うこと多し。!! 使いすぎないようにしないと
  • 結構 GitHub に Spring + Kotlin のサンプル上がってますね。Kotlin 好きが多いなw
  • Kotlin 自体はとっつきやすいです。ただ、Spring と Scala が仲良しならなぁ...という思いが隠せません
  • ktlint 入れて CI 回したり、Docker image がビルドできなくてハマった時間の方が長かったです
  • エルビス演算子 ?:命名センスに惚れた。でも他の言語でも使ってた

読んだ本

Kotlinイン・アクション

Kotlinイン・アクション

Kotlin Webアプリケーション 新しいサーバサイドプログラミング

Kotlin Webアプリケーション 新しいサーバサイドプログラミング


  1. EasyMockとかね…

【読了】失敗から学ぶRDBの正しい歩き方

失敗から学ぶRDBの正しい歩き方 (Software Design plus)

失敗から学ぶRDBの正しい歩き方 (Software Design plus)

アプリ開発の経験年数=RDBに触ってきた年数でもあるので、知識の棚卸しに読んでみました。頷くポイントが多すぎて首が痛くなりました。

人の失敗から学んで同じ失敗を繰り返さない姿勢、大事です。夜はゆっくり寝たいじゃないですか。

データモデルが大事ではあるとは思うのですが、使う RDBMS の癖や得意/ 不得意なことを知っておくとそうでないとでハマることから避けやすくなる筈です。 時間も別のことに使えるわけです。

SQLもデータ件数がメモリに乗るレベルであればパフォーマンスもそこそこ出ます。メモリに乗らなくなってから慌ててチューニングすると、table構造の見直しが発生する訳です。

ボトルネックになるのは永続化層なことがほとんどなんですよね。で、データが溜まってから問題が顕著にあらわれるわけです。その時は開発時のエースはプロジェクトから抜けて...というあまり望ましくない状況だったりするわけです。いやー、困る。

そうすると既存のデータどうすんの?という問題になって、データ移行バッチを作る羽目になったり、既存データでデグレらないよね、とヒヤヒヤしたりする訳です。夜はゆっくり寝たいじゃないですか。

ある程度設計を任せられるポジションの人も、若さと気合と根性でカバーできる人もこの本は読んでおくと良いと思います。先人が犯した(と思ってる)失敗をあなたが繰り返し経験する必要はないわけですよ。もっと違うことに悩む時間を使えるハズです。

  • あえてアンチパターンを適用して目先の時間を取って維持するのに手間をかけるアプリにするか
  • ちょっと立ち止まり時間をとって考えて、維持しやすいアプリにするか

どっちが良いか考えてみませんか。作った後にメンテナンスする人が変わったとしても後ろ指刺されることが無くなるんじゃないかな、と思います。

「データベースの寿命はアプリケーションより長い」は確かにそうだと思います。アプリケーションはリファクタリングしやすいけどRDBMSのデータはリファクタしづらいですしね。

合わせて読みたい

SQLアンチパターン

SQLアンチパターン

Selenide をローカルの file から open してみる

Selenide 良いですね。 さて、わかる人にだけ伝われば良いやシリーズです。

Selenide 使って最初にアクセスするページが http が https とは限りません。HTML のドキュメントそのもの(文字列)ということだってあるわけです。Selenide のサンプル見ると、

open("/login");

とか

open("http://www.google.com/");

とかなわけですよ。 まぁ、外部サービス連携なんかすると、普通は Location ヘッダに移動先の URL があるでしょうからそれを使うでしょう。ただ、世の中そんなシステムだけじゃない。HTML のコンテンツを返すからそれをブラウザに流して処理を続けてよね、って奴もあります。

そんな時 Selenide ではどうするか?

@Test
public void test() throws IOException {
    String contents = "<html>...</html>";   //ここに HTML のコンテンツが入ってると思ってください

    Path tempFile = File.createTempFile("temp", ".html").toPath();
    try {
        try (BufferedWriter writer =
                     Files.newBufferedWriter(tempFile, StandardCharsets.UTF_8)) {
            writer.append(contents);
        }

        HogePage firstPage = open(tempFile.toUri().toString(), HogePage.class);
        HogePage secondPage = firstPage.clickNext();
        secondPage.clickNext();
    } finally {
        Files.delete(tempFile);
    }
}

@Data
private static class HogePage {
    private final ElementsCollection submitButtons = $$("input[type=submit]");

    public HogePage clickNext() {
        submitButtons.first().click();
        return page(HogePage.class);
    }
}

拡張子見てたのね...これにハマること数時間...。私と同じ失敗は繰り返しませんように。

ちなみにHTMLのコンテンツが Shift_JIS とかの場合は、ファイルをその Charset に合わせることで化けなくなりますヨ

噂の肉巻きバウムクーヘンに挑戦してみた

BBQのインパクトを強めるべく、たけだバーベキューさんが紹介していた「肉巻きバウムクーヘン」に挑戦してみました。

用意するもの

バウムクーヘン

f:id:nemuzuka:20180813084827p:plain

原信で購入。

薄切りバラ肉

f:id:nemuzuka:20180813084523p:plain

カトウ食材で購入。解凍しておきます。

アルミプレート

f:id:nemuzuka:20180813084950p:plain

ダイソーで購入

手順

1. バウムクーヘンに薄切りバラ肉を巻く

f:id:nemuzuka:20180813085108p:plain

なんか、レディーガガの生肉ドレスみたいです。美味しくなるのか怪しい...。

2. 焼く

f:id:nemuzuka:20180813085302p:plain

焼き網にアルミホイルを敷いてその上にバウムクーヘンを置きます。

f:id:nemuzuka:20180813085418p:plain

で、アルミプレートで蓋をして蒸し焼き状態に。

f:id:nemuzuka:20180813085516p:plain

こんな感じに焼けました。塩コショウを振っていただきます。

「そのまま食べたかった」とグチグチ言う子供に、良いから食べてみな、と食べさせてみた所、思ったより悪くないとの評価でした。 甘じょっぱくて、逆アメリカンドックのような感じがします。不思議な食感。ケチャップ & マスタードも良い組み合わせかも(試すまで残りませんでした)

ただ、油が下に溜まって焦げやすいので、下に敷くアルミホイルには穴を空けるなりの工夫が必要かもしれません。

まとめ

割とインパクトも大きいので、BBQで盛り上がると思います。準備もそう大変でないので、盛り上げコスパは高いでしょう。 焼きマシュマロ的な立ち位置で子供や女子にウケが良いと思います(ビア缶チキンより引かれません)。

いつ食べるのが正解なんだろうという疑問は残りますが。

長岡IT開発者勉強会(NDS)の第55回勉強会に参加してきた #nds55

NDS第55回勉強会 に参加してきました。 地元の開発者さんに会う機会が久しぶりだったのでテンションが無駄に上がってた気がします。

申し込み時は発表するネタが思いつかなかったけど、それから何か話したい熱が盛り上がり、何の気なしにそんな事をTwitterで呟いたら、主催より「発表どうですか?」とお誘い頂き、発表もさせて頂きました。ありがとうございました。*1

発表ネタ

技術的に面白い事をパパッとまとめられなかったので、自分が経験しているけど他の人はそんなにしてない系の話をしようと思いました。

地方の会社でリモートワークというのはきっと超えなきゃいけないハードルがたくさんあって大変なんだろうと思っていましたが、今フルリモートやられている方を聞いてみると、東京の企業に勤められている方か、フリーランスの方が多い感じでした。

首都圏の会社でフルリモートで働くのを良しとするなら結構採用の枠が広がるかと思ったのですが、実際フルリモートでやってみるとコミュニケーションギャップが発生するので、本気で取り組むならリモートしたい人だけでなく、オフィスで作業される方の協力が必要だよという意味も込めてネタを作りました。新しい環境+フルリモートってストレスたまるんですよね。

もちろんリモートする人の意識を変える(というとちょっと違う気がするけど)必要があって、「言われた事をこなす」に徹されるとちょっとキツイかもというお話もさせて頂きました。距離を超越した働き方をしたいなら対価を出せ、というところでしょうか。

まとめてて思ったのは、「この働き方ってリモート関係ないじゃん」という事でした。これできれば、多分ですけどプロパーでもフリーランスでも成功しますね。

割と参加者の方からは共感を得られたので満足です。

他の方のネタ感想

  • pythonはじめの一歩(コードとかではなく)」(civic)
    • t.co
    • pythonは触った事なくて、このセッションではハマらない為にどうすれば良いか的なお話をしてくれました。簡単な処理はpythonで書く人多いですよね。やってみようかしらん。
  • 「プロジェクトマネジメント入門」(hiro_ishibashi)
    • スーツ代表いしばしさんです。この方面とんと疎くなったなぁと思いながら聞いてました。規模の大きさで管理の単位を変えるの大事という所にいたく共感しました。
  • 「Docker for Mac/Windows ではじめる Kubernetes」(hayajo)
    • はてなに在籍されてるはやじょさん。東京に行ってよりカッコよくなった気がしました。k8sのお話をしてくれたのですが...。オイラにはまだ早かったみたい。せっかく話してくれたのについていけないのが勿体なかった。
  • 「はじめてのソフトウェアテスト技法 ー 同値分割・境界値分析編」(kasacchiful)
    • t.co
    • テスト大事。むやみにテストメソッド生やしても管理コスト高くついちゃうから効率的に行うこと大事。個人的には Unit Test では Jorgensen 方式じゃないとテストした意味ないと思ってます
  • 「アウトプットのすゝめ 〜春のエモを添えて〜」(しんぺい a.k.a. 猫型蓄音機)
    • 安定感抜群のしんぺいさん。面白いながらも熱いメッセージを聞かせてくれました。確かにチュートリアルやった系よりも、そこからあなたがどう思ったかの方が聞きたい。資料あげてくださいよー。
  • Amazon Neptuneに入門してみる」(Watanabe)
    • t.co
    • フルマネージドのグラフデータベースサービスのお話でした。AWS何でもフルマネージドサービスにしてくるなーと思いながら聞いてました。
  • 「アイコンフォントを手作りしよう」(gatabutsu)
    • なんでもできるgatabutsuさん。トーク面白いです。長岡市の地図をアイコンフォントを作るのをライブで見せてくれました。ハマったポイントもちゃんと説明してくれたし、すごいお人や。丸星行きましょうね。
  • 「学び方入門」(masaru_b_cl)
    • まさるさん。最初に初めるのはチュートリアルから。それから個々の情報を見る。確かに。ブレにくいものを1つ押さえておくと軸ができるから別に学ぼうとする時に応用が効くことが多いですよね。
  • 「数年ぶりにJSを使った件」(gonchan93)
    • キレ芸枠?のごんちゃん。JScript初めて聞いた。そして投げ捨てる感じのプレゼン...。面白い。
  • 「Web Assemblyについて」(ailight)
    • MS怖い。dllブラウザで読んでる...。
  • 「Azure開発の感想」(ToruAbe)
    • MSに難色を示していたのに実際使って見るとMSサイコーになったお話。MS怖い。
  • 「ながおか技術教育支援機構についてのお知らせ」(masarunagai)
    • プログラミング教育のお話。子供達が興味を持ってやれるようにするには色んな方向からアプローチしてみないといけないんでしょうね。ロボットやデザイン、それこそ仕事の数だけプログラミングの需要がある。私は子供に教えられることがあるのかな、あったとしてより興味を持ってもらえるようになるのかしらと思いながら聞いていました。
  • 「はじめてのAWS認定資格取得」(kasacchiful)
    • そうか、試験受けるのに英語いるって見たな。秋葉原会場が良いのか。ふむふむ
  • 今年度新しくやったことを振り返る(山P)
    • 必要に迫られると人は伸びる。確かに。

今回は多かった。これだけの濃い発表が聞ける勉強会、そうそうないですよ。行ってみようかなーとちょっとでも思ったアナタ、次回お待ちしております。

*1:時間が収まらなかった要因はそのせいでもあるんだろうな、と思わなくもなく

JAWS-UG 上越妙高支部 第3回勉強会(サーバーレス勉強会)に参加してきた

f:id:nemuzuka:20180122183026p:plain

JAWS-UG 上越妙高支部 第3回勉強会(サーバーレス勉強会)

いつもは長岡市近辺の勉強会に顔を出しているのですが、唐突に行ってみたい衝動にかられ、上越まで車を走らせました。 天気も荒れてなくて良かった...。

f:id:nemuzuka:20180122182612j:plain

あ、この子スキーの装備だけじゃなくてかんずり持ってる...

お題は「サーバーレス」ということで、個人的にAlexaと戯れる時に必要なLambda繋がりで触り始めたのでタイミング的にも知識を深めたい所でした。

サーバーレスってなに? / Lambda+Serverless実演(植木さん)

EC2、ECS、サーバーレスで管理する単位が違うんですよ、という話から始まり、実際にServerless FrameworkでLambdaをデプロイするデモを通して、OSとかコンテナとか意識せずにアプリのコードだけ書けば良いのですよ、ということをお話ししてもらいました。

数あるAWS上のサービスがLambdaと連携できることでサービス自体の使い勝手を良くしているのだろうと感じました。 メモリや処理時間の制限はありますが、AWSのサービス+自前のLambdaで出来ることの幅が広がりますよね。

あと、AWSをお仕事にする方はServerless FrameworkよりもAWS SAMが一般的なのかしらと思ってたのですが、まだServerless Frameworkの方が楽なことが多いのでしょうか。

ちょっとしたWebアプリならLambdaでサクッと作れて課金対象も使った分だけなのでサーバ維持費も考えなくて良い時代なのですよねー。個人開発者としてはいい時代です。後はアイディアさえあれば食うに困らないはずだ...。

サーバーレスフレームワーク Zappaを使用した話(中澤さん)

Pythonでサーバレスなアプリケーションを開発するためのフレームワークとしてZappaを使ってみた、というお話でした。

Djangoが動かないと色々苦労されていましたが、Serverless Frameworkでいいんじゃないかと思ってしまう私は「技術者」じゃないんだろうな、と再認識しました。でも、こういう話聞くのは大好きです!

AWS IoTで証明書を自動登録してデータをアップするまでのお話(知野さん)

AWS IoTを使って証明書を自動登録するお話しでした。

証明書とモノの紐付けは、1台なら手動で良いけど、台数が増えると面倒だから自動化しました、というお話でした。開発者ガイドを元に実施されたことをお話して頂いたのですが、これAWS IoTを使わない場合どうやるんだろう、と思いました。この辺りの仕組みを自前で構築してゴハン食べてる会社さんは死活問題じゃないのかしら? AWS IoTとLambdaを組み合わせる辺り、ピタゴラスイッチっぽくて、子供がScratchみたいなビジュアルプログラミングから入っても間違いじゃないのかな、と思うようになりました。自分の知らない業種のアプリの事例を聞くのは勉強になります。

懇親会

f:id:nemuzuka:20180122182640p:plain

車だったので飲みませんでした。「飲みたいけど飲めない」とはこういう気分なのか...、と久しぶりに気づきました。飲みたいけど飲めない人にもっと優しくなろう。

まとめ

私のようなAWSを浅く触っているような人にはハードルが高いのかも、なんて思ってましたが、いざ参加してみると、知らない人にもわかりやすく伝えてくれる良い勉強会でした。AWSのサービスが多岐にわたる為、Webアプリケーション以外にも事例が聞けるのは自分の視野も広がります。勉強会の空気もアットホームな感じでした。AWSに興味があれば参加してみては如何でしょうか?社内だけでなく、外部にも話せる人を見つけられると思います。

なんと中澤さんと知野さんは長野から来られてました。県外の勉強会に参加するのはなかなか凄いなぁと思います。なので次回は負けじと何か話したい気になりました*1

今回参加されたみなさま、ありがとうございました。

*1:次回はお花見の時期に開催予定とのことでした

Amazon EchoからSlackに通知を出してみた(Cognito + API Gateway版)

前回前々回 とAlexaからSlackに通知できる仕組みを試してみましたが、Alexaから呼ばれるLambdaに接続先やメッセージを環境変数で設定する必要があり、ユーザ毎にできるようにしたくなってきました*1

今の仕組みでも、Alexaユーザーとシステムユーザーを関連付けることができます。そこから接続情報やメッセージを引っ張って来れればうまく行きそうです。

  • ユーザ毎に情報を保持するアプリ
  • Alexa SKill

の2本立てで行きたいと思います。

Serverlessの為にどんな構成にする?

  • ユーザ管理・認証
  • ログイン済みのユーザに紐付くデータ
    • API Gateway経由でhtmlを返したりAPIを叩いてデータにアクセスする

永続化は?

最初はユーザに紐付く情報をCognito Syncで考えていたのですが、各端末間のデータ同期に特化したサービスらしく、Lambda上でユーザに紐付く情報を取得するのは難しそうでした。なので、保存先はDynamoDBで行います。

イメージはこんな感じです。 f:id:nemuzuka:20180120150534p:plain

ユーザ毎に情報を保持するアプリ

API Gateway経由でリクエストを受け取り、レスポンスを返します。AlexaからKickされたLambdaがユーザに紐付く情報を取得するのもこのアプリ経由になります。設定画面は誰からもアクセスされると困るので、API Gateway 側でTokenの有効性をチェックします。

コード

Alexa Skill

AlexaからKickされたLambdaはAccess Tokenを元にユーザに紐付く情報を取得します(アカウントリンクを有効にします)。そして、その情報を元にSlackに通知を投げます。

コード

ちょっと気になる点

それぞれのGitHubリポジトリ上に構築手順をまとめましたので、気になる方はぜひ試してみてください。 実は、API GatewayのカスタムオーソライザーでCognitoのarnを直接設定できます。これでTokenの有効性チェックを自前で行う必要はないのですがID Tokenしか有効でないらしく、AlexaからKickされたLambdaにはAccessTokenしか渡ってこない為、自前でチェックしています。その辺ご存知の方がいらっしゃればご教示頂きたいです。

まとめ

現在、Alexaからユーザ固有の設定をリクエストパラメータ的に渡すのは難しいので、外部のシステムに保持させておき、Access Tokenを元に取得するという方法が実現できました。これでちょっとスマートスピーカーの使い道も広がるんじゃないかと思います。

*1:流石にユーザに声でメッセージやURLを伝えてもらうのは無理ゲーだと思いました