【読了】失敗から学ぶ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を伝えてもらうのは無理ゲーだと思いました

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

前回Alexa、会社に連絡をしてと話しかけることでSlackに通知するアプリを作成しました。 ですが、このアプリ経由だと「誰からのメッセージなのか」がわからないので、環境変数名前を設定する必要がある為、ユーザ毎にLambdaファンクションを登録する必要がありました。

別に公開するとかそういうのではないのですが、ソースコード上に設定値をハードコードしている感じがして雑な感じです。もう少しいい感じにならないかと探していると、Alexaからアクセストークン取得できるんですね。 SlackでもOAuth使えるので、取得したTokenを元にWeb APIを呼び出すことで認証したユーザとして書き込めます。今回はこっちでやってみましょう。

1. Slackのアプリ登録

  1. SlackのApplication管理画面より、Create New Appをクリックします
  2. App NameWorkspaceを設定して、Create Appをクリックします f:id:nemuzuka:20180109122426p:plain
  3. 機能 - OAuth & 権限 の スコープの設定セクションで、権限スコープの選択に メッセージをユーザーとして送信します chat:write:user を設定し、変更を保存するをクリックします f:id:nemuzuka:20180109122457p:plain
  4. OAuth トークン & 転送 URLセクションで、ワークスペースへのアプリのインストールをクリックします f:id:nemuzuka:20180109122512p:plain
  5. アクセス許可画面にて、許可するをクリックします f:id:nemuzuka:20180109122525p:plain
  6. 基本情報 - アプリの認証情報セクションで、クライアントIDクライアントシークレットが表示されます(後で使用します) f:id:nemuzuka:20180109123248p:plain

2. Lambdaファンクション登録

Skillが呼ばれた時にアクセスtokenが渡されるようになる為、それを使用して環境変数で指定したチャンネルへメッセージを登録します。詳しくはソースコードをご覧ください。

こんな感じで登録してください f:id:nemuzuka:20180109122613p:plain

環境変数として、書き込むChannelのIDやメッセージの設定が必要です f:id:nemuzuka:20180109123402p:plain

3. Alexa Skill登録

3-1. スキル情報

f:id:nemuzuka:20180109122651p:plain グローバルフィールドは全て「いいえ」を設定します

3-2. 対話モデル

インテントスキーマとサンプル発話に設定します。

これとかこちらを参考にしてください

3-3. 設定

  • サービスエンドポイントのタイプ には AWS Lambda の ARN (Amazonリソースネーム)
  • デフォルトにはLambdaファンクションのARN

を設定します。また、アカウントリンクの設定をはいにして、必要な情報を設定します。 f:id:nemuzuka:20180109122706p:plain

  • 認証 URL https://slack.com/oauth/authorize
  • クライアント ID Slackの基本情報 - アプリの認証情報セクション内のクライアントID
  • スコープ 今回はchat:write:user
  • リダイレクトURL この項目は、Slackの設定に必要です
  • 認可の承諾タイプ Auth Code Grant
  • アクセストークンURL https://slack.com/api/oauth.access
  • クライアントシークレット Slackの基本情報 - アプリの認証情報セクション内のクライアントシークレット
  • クライアント認証スキーム リクエストボディの資格情報

4. Slackのリダイレクト先を設定

Slackの 機能 - OAuth & 権限 の リダイレクトURLセクションで、Alexa SkillのリダイレクトURLを全て設定し、URLを保存するをクリックします f:id:nemuzuka:20180109122720p:plain

5. リンクを有効化

f:id:nemuzuka:20180109122735p:plain 管理画面を開いて有効にするをクリックするとアクセスを許可するか確認する画面が表示されるので、許可するをクリックします。 f:id:nemuzuka:20180109122753p:plain

f:id:nemuzuka:20180109122807p:plain

6. 話しかけてみる

Alexa、スラックに通知をしてと話しかけることで、Slackに通知が行く筈です。

f:id:nemuzuka:20180109122821p:plain

有効化した時のアカウントからのメッセージとして登録されていますね!

まとめ

リンクを有効化した時のアカウントからのメッセージとして登録されるので、環境変数で名前を設定することから解放されました。 ですが、まだユーザ毎にカスタマイズできると良いものがありますね。そう、チャンネルIDとメッセージ本文です。個別のパラメータとしてどうにか送れないかな...