Vue.js アプリを Firebase にデプロイしてみる

Firebase を使ってみようと思います。ひとまず、以下の続編としてアプリを Firebase にデプロイしてみようかと。

Vue.js でウィジェットっぽいもの (仮) その2 - kntmr-blog

ソースコードはこちら。

github.com


以下、備忘録。

Firebase Console

Firebase Console でプロジェクトを作成する。「国/地域」には日本を選択する。

Project Overview から「ウェブアプリに Firebase を追加」をクリックしてコードスニペットをコピーする。

Firebase CLI

Firebase CLI をインストールする。

> npm -g install firebase-tools

ログインする。

> firebase logout
No need to logout, not logged in
> firebase loing
? Allow Firebase to collect anonymous CLI usage and error reporting information? Yes # ブラウザが起動するのでログインする

Firebase

依存モジュールに Firebase を追加する。

> npm install firebase --save

src/main.js を編集。

import firebase from 'firebase'

// 上でコピーしたコードスニペットを記述する。
var config = {
  apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "APPNAME.firebaseapp.com",
  databaseURL: "https://APPNAME.firebaseio.com",
  projectId: "APPNAME",
  storageBucket: "APPNAME.appspot.com",
  messagingSenderId: "xxxxxxxxxxxx"
};
firebase.initializeApp(config);

ビルド & デプロイ

ビルドする。

> npm run build

Firebase プロジェクトとして初期化する。

> firebase init
? Are you ready to proceed? Yes
? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confirm your choices. Hosting: Configure and deploy Firebase Hosting sites
? Select a default Firebase project for this directory: APPNAME # 既存のプロジェクトを選択
? What do you want to use as your public directory? dist # npm run build で dist に出力されるため、dist を指定する
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? File dist/index.html already exists. Overwrite? No # index.html は上書きしない

Firebase にデプロイする。

> firebase deploy
# Hosting URL: https://APPNAME.firebaseapp.com のURLにアクセス

これからやりたいこと

PWA の学習を兼ねて、Firebase にデプロイしたアプリを PWA 化してみる予定。

AWS導入ガイドセミナー2018年春編 〜クラウド移行のコツはポイントを押さえて効率よく〜 に行ってきた

先日、AWS導入ガイドセミナー2018年春編 〜クラウド移行のコツはポイントを押さえて効率よく〜 に行ってきました。簡単に所感をまとめます。

dev.classmethod.jp

所感など

各所で聞く話もありましたが、クラウドについては素人ということもあり、改めていろいろとクラウド移行のメリットを感じました。セキュリティについては、様々な要件に対応できるだけのサービスが予め用意されているところは心強いですね。あと、初期コストだけでなく、日々の管理やシステム更改などのことを考えれば、長期的に見てもコストのメリットがあるようです。

また、移行パターンについては初めて知ったのでとても参考になりました。移行パターンから検討するなら確かにクラウドベンダーと協業するのはありだなと思います。

ただ、当然のことではありますが、協業してクラウド周りをクラウドベンダーに丸投げしてると、短期的にはビジネスとして成立するかもしれませんが、既存ベンダーはいずれこの業界から淘汰されることになるんだろうなと...。

既存ベンダーもAWSのサービスを利用した案件を提案できるようにノウハウを身に付けていく必要があると感じています。IoT やビッグデータ、AI を活用するプラットフォームであるというような話もありましたし。

ひとまず、社内外問わず小規模でもいいので、AWSを導入して実績を積んでいかないとなぁ、と思う今日この頃です。


以下、メモから抜粋。

クラウドが変化させる今のIT・これからのIT

  • クラウドはコンピュータリソースを提供しているだけではない
    • 例えば、IoT, AI を使うためのインフラ
  • 金融業界、SMB (中小企業) などのお客様が使っている時代
  • オンプレ⇒クラウドに移行する理由
    • オンプレはシステム更改が必要になる
    • キャパシティプランニングの難しさ (リスクヘッジのため余分なリソースを購入している)
  • AWSは初期費用ゼロ、従量課金
    • AWSはどんどん値下げする (利益をユーザーに還元する文化)
    • ハードウェア費用、減価償却費は削減できる
    • 必要なときにすぐに使える (必要に応じてスケールアウト/スケールアップできる)
    • システム更改が不要なので、長期的に見てもコスト削減が見込める
  • いろいろな認証を取得して、セキュリティやコンプライアンスの要件を満たす
    • 「自社データセンターの方がリスクが高い」
    • クラウドベンダーはセキュリティに投資している (これがビジネスのキモと言っていい)
    • VPC, Direct Connect, アベイラビリティゾーン (データセンターレベルで冗長化している)
    • 大阪ローカルリージョン (災害対策向け、基本は東京リージョンを使う)
  • 日本法準拠、通貨、管理UIの日本語化 ⇒使い易い
  • パートナーコミュニティの充実
  • VMware Cloud on AWS
    • オンプレの VMware 環境をそのままAWSに移行できる
    • AWSサービスと組み合わせられる
  • IoT, ビッグデータ, AI は三位一体で動くもの
    • インターネット常時接続、構造化/非構造化データ、機会学習/ディープラーニング
    • S3をハブにしてデータを各サービスで活用する
    • AWSではデータを収集して付加価値を提供している

AWSを使うとき、ネットワークの検討、忘れてませんか?

  • 金融、医療、公共などの業界で使われるようになっている
  • 現在は基幹部分にもクラウドが活用され始めてる
  • セキュリティの確保が重要
  • ネットワークの検討はかなり後工程になっているのが実情
    • 現状分析⇒企画⇒設計のうち、設計あたりで検討している
  • AWSのネットワーク設定でハマる
    • BGPの設定 (やったことないひとは多い)
    • 閉域ネットワークを作るのは大変
    • AWS独特のルーティング仕様がある
    • AWS内のネットワーク設計の理解が必要
  • インターネット経由のAWS利用はセキュリティが心配
  • モバイル経由だと通信速度がネック
  • 専用線は納期、価格の面がネック
  • フートコネクト (CloudGateway)
    • NTT東では閉域ネットワークでサービスを提供する
    • フレッツ回線があれば素早くAWSに接続できる環境が準備できる
    • 今までの閉域ネットワークのサービスに比べれば安価である
    • AWSと閉域ネットワークを直接接続しているので高速

クラウドを使ってより効率的なセキュリティ対策を!抑えるべきポイントはココ

  • 物理的なセキュリティ機器はクラウドに持っていけない
  • 責任の共有モデル
  • セキュリティ規制/標準の準拠
    • 各セキュリティ要件に対応した各種AWSサービスが用意されている
    • ただし、AWSを使う側は設定する必要がある
  • ミドルウェアなどの脆弱性AWSを使う側が対応しないといけない
  • Deep Security (トレンドマイクロ)
    • ウィルス対策、Webレピュテーション (危険なWebサイトへのアクセスをブロック)
  • セキュリティの自動化 (不正アクセスの検知/遮断、ウィルス感染時の自動隔離/自動復旧)

クラウド移行のパートナー活用術 〜これがクラウド移行の現実解〜

  • クラスメソッドメンバーズ (導入、コンサル、支払などの代行)
  • 導入企業の広がり、ユースケースの広がり
  • 既存ベンダーに依頼するか or 内製するか or クラウド専業ベンダーに依頼するか
    • 既存ベンダーはクラウドの知見に対する不安がある
    • 内製はリソースが確保できないなどの不安がある
    • クラウドベンダーは既存業務の知識に対する不安がある
  • 移行パターン
    • オンプレの構成ではクラウドのよさを生かし切れない
    • システム刷新はシステムのライフサイクルに合わず余計なコストになる
  • 既存ベンダーとクラウドベンダーを組み合わせる
    • 多数のAWSサービスでいろいろ対応できる反面、専門家の支援が欲しい
    • インフラ、OS、アプリ、業務のスキルをすべて一社で賄うのは難しい
    • 適材適所でベンダーを使い分ける
  • 移行パターンに応じてベンダー同士で協業する
  • クラウドベンダーと協業する場合は初期段階から参画し、移行パターンから検討する

移行パターンについては以下の25ページあたりに書いてあります。

www.slideshare.net

その他、以下のあたりが参考になりそうです。

git rebase メモ

備忘録。基本的に svn を使うことが多いので、たまに Git を使うとコマンドを忘れている件...。

> git rebase -i HEAD~2

これを

pick <commit_hash> hogehoge
pick <commit_hash> fugafuga

こうする

pick <commit_hash> hogehoge
f <commit_hash> fugafuga

fugafuga のコミットが hogehoge のコミットに統合される。実際はコミットをひとつにまとめた新しいコミットになると思われる。なので、新しいコミットには別のハッシュ値が割り当てられる。

ただし、未コミットの変更がある場合は rebase できない。変更を戻すか、git stash で一時的に退避させる。

JJUGナイトセミナー「Java SE 10 / JDK10 リリース特集」に行ってきた #jjug

先日、JJUGナイトセミナー「Java SE 10 / JDK10 リリース特集」に行ってきました。簡単に所感をまとめます。

jjug.doorkeeper.jp

メモから抜粋。(資料が公開されたら貼っておきます ⇒ 2018/03/29 追加しました)

JDKリリースモデル変更について

  • 5/17 Java Day Tokyo 2018
  • OpenJDK
    • 無償提供
    • GPLv2 + Classpath Exception
    • 6ヶ月単位でリリース
    • 3ヶ月単位でパッチリリース
  • Oracle JDK
    • 有償のみ
    • 1バージョン8年サポート (他のOracle製品同様)
    • 3ヶ月単位でパッチリリース
    • 3年間隔でリリース
    • 新しいリリースモデルに準拠するのは Java 11 以降
    • 9, 10 は OpenJDK のリリースモデルに準拠
  • ドキュメントは OpenJDK から提供される
  • Deprecated の運用ルールはそのまま (1年で削除される)

JDK10の追加機能解説 - JEP286/ローカル変数の型省略(var記法)を中心に

www.slideshare.net

  • JEP 286
  • ローカル変数の型推論
  • 初期化のときに型宣言を省略して読み易くする
  • ローカル変数は for ループ, for-each, try-with-resources を含む
  • ローカル変数の型推論 != 動的型付け
  • コンパイラの話でありランタイムレベルの話ではない
  • 従来のコードが簡潔に書けるようになる
  • 型が明確であれば読み辛くなることはないはず (もちろんすべてに当てはまるわけではない)
  • なぜローカル変数だけなのか
    • フィールドやメソッドの引数などの影響は複数のファイルにまたがるため
  • Denotable types
  • varが常に何らかの型でリプレースできるとは限らない
  • varは型の名前には利用できない (Varは大丈夫)
  • 変数名には利用できる
  • var var = new var();
  • 書き易さより読み易さ
  • ローカルコードで理解できることが大事 (どう動くか判断できること)
  • IDEなどのツールに依存するべきではない
  • 明示的に型を宣言するのはトレードオフ (すべてのローカル変数をvarにすることは避ける)

既存コードを一気に var に置換するとかは NG です。あと、原則やガイドラインは以下にまとまっています。とても重要。

orablogs-jp.blogspot.jp

個人的に興味深いのはこれ。これが問題になることはあまりないとは思いますが。

// ORIGINAL
List<String> list = new ArrayList<>();

// Inferred type of list is ArrayList<String>.
var list = new ArrayList<String>();

あと、おもしろかったのはこれ。

PriorityQueue<Item> itemQueue = new PriorityQueue<Item>();

// OK: both declare variables of type PriorityQueue<Item>
PriorityQueue<Item> itemQueue = new PriorityQueue<>();
var itemQueue = new PriorityQueue<Item>();

// DANGEROUS: infers as PriorityQueue<Object>
var itemQueue = new PriorityQueue<>();

// DANGEROUS: infers as List<Object>
var list = List.of();

var とダイアモンド演算子を併用すると Object として型推論される模様。後日、同僚と話してたんですが、var とダイアモンド演算子を併用するときはコンパイルエラーにするとか、IDE で警告出すとかしてもよさそうですねという話になりました。

もう1つおもしろかったのはこれ。

// ORIGINAL
byte flags = 0;
short mask = 0x7fff;
long base = 17;
 
// DANGEROUS: all infer as int
var flags = 0;
var mask = 0x7fff;
var base = 17;

たぶん32ビット以下の値が int として型推論される模様。

あと、きしださんのエントリ。

d.hatena.ne.jp

Java 10でぼくたちの生活は どうかわるの?

www.slideshare.net

  • Java XX で動かしてみる
  • Java XX でコンパイルしてみる
  • jdeps や jdeprscan で内部APIか非推奨APIを使ってないか確認する
    • jdeps : 依存関係を調べる
    • jdeprscan : 非推奨APIを使ってないか
  • Parallel Full GC は効果的だが、そもそも Full GC が頻発するような状況自体がよくない
  • LTS のバージョンごとにアップデートするといきなり削除されている API が出てくるかも
    • 基本的には @DeprecatedforRemoval=trueAPI が将来的に削除される
  • immutable コレクションの確認/作成を自前でやってるところは標準 APIcopyOf で置き換え推奨
  • RuntimeMXBean でプロセスIDが取得できる

Java 9, 10 は Java 11 サポートに向けて検証するために利用するのがよさそうとのこと。Java 8 から 9 を乗り越えるのが大変っぽい。それ以降はそれほど大きな壁はないはず。

Spring の @Validated と Bean Validation の javax.validation.groups.Default と groups について

実際の挙動がイメージとちょっと違うのでメモる。

パターン1

バリデーショングループのインタフェースで javax.validation.groups.Default を継承しないパターン。

interface Group {}

@NotNull
private String foo;
@NotNull(groups = Group.class)
private String bar;

Controller で @Validated とする場合、groups が未指定 or Default.class を指定したアノテーションのフィールドがバリデーション対象になる。ここでは foo のバリデーションが実行される。

一方、Controller で @Validated(Group.class) とする場合、Group.class を指定したアノテーションのフィールドがバリデーション対象になる。ここでは bar のバリデーションが実行される。

パターン2

バリデーショングループのインタフェースで javax.validation.groups.Default を継承するパターン。

interface Group extends Default {}

@NotNull
private String foo;
@NotNull(groups = Group.class)
private String bar;

Controller で @Validated とする場合、groups が未指定 or Default.class を指定したアノテーションのフィールドがバリデーション対象になる。ここでは foo のバリデーションが実行される。

一方、Controller で @Validated(Group.class) とする場合、Group.class を指定したアノテーションgroups が未指定 or Default.class を指定したアノテーションのフィールドがバリデーションの対象になる。ここでは foobar のバリデーションが実行される。

まとめ

当初、パターン2の挙動がイメージと違ってたんですが、こうやってまとめてみると別におかしくないですね...。Group インタフェースは Default インタフェースのサブインタフェースなので、is-a の関係になります。なので、パターン2において、Default を指定したときは Group.classアノテーションは対象外になるし、Group を指定したときは Default.classGroup.classアノテーションが対象になるのは当たり前ですね。

SAStruts のフォワードとリダイレクトについて

Seasar/Struts チョットデキルマンのみなさんには常識かもしれませんが、@Execute の属性に redirect=true を指定してるのにフォワードで遷移することがあったり、イマイチそのあたりの挙動が分からず。備忘録。

デフォルトはフォワード

Super Agile Struts - Annotation Reference

redirect要素(オプション) 遷移先にリダイレクトで遷移するかどうかを指定します。 デフォルトはfalseで、リダイレクトはしません。

redirect=true を指定するとリダイレクトになる。

エラーメッセージがあるときはフォワード

sa-struts/ActionWrapper.java at master · seasarorg/sa-struts · GitHub

if (redirect && ActionMessagesUtil.hasErrors(request)) {
    redirect = false;
}

ActionWrapper の execute の中でエラーメッセージがあるかチェックしてフラグを上書きしている。この場合、@Executeredirect=true を指定してもフォワードになる。

Action メソッドで返却するパスの末尾に redirect=true を付けるとリダイレクト

Super Agile Struts - Feature Reference

リダイレクトで遷移したい場合は、 パスの最後にredirect=trueを追加します。 =の前後に余分な空白は含めないでください。 redirect=trueの部分は、実際に実行されるときには、消去されます。

sa-struts/S2ActionMapping.java at master · seasarorg/sa-struts · GitHub

if (path.endsWith(REDIRECT)) {
    redirect = true;
    path = path.substring(0, path.length() - REDIRECT.length() - 1);
}

S2ActionMapping の createForward の中で redirect=true があるかチェックしてフラグを上書きしている。この場合、エラーメッセージがあってもなくても強制的にリダイレクトになる。

現場からは以上です。

JSUG勉強会 2018年その2 SpringとAPI時代の動く仕様への取り組み に行ってきた #jsug

JSUG勉強会 2018年その2 に行ってきました。簡単に所感をまとめます。
(2018/03/12) スライドのリンクを追記しました。

jsug.doorkeeper.jp

www.slideshare.net

  • システム設計の謎を解く
    • "設計とは考えること、アウトプットはその一側面である"
  • テストできないテストケース
    • 観点は書かれている
    • テストするための事前条件が書かれていない
  • テンプレート、フレームワーク
    • given: 事前条件、状態
    • when: 対象に対する操作
    • then: どうなるか
  • Spock: テストフレームワーク

    • ↑のテンプレート形式で書ける
  • 自動テストは動く仕様である

    • プログラムで表現できれば繰り返し検証できる
    • 動かして確認できる仕様という位置付け
  • テストメソッドの名前を given - when - then の形式で書く

  • テストで確認したい部分が仕様

    • プログラムレベルや操作レベルの内容はテストコードから隠蔽してよい
    • 仕様とは直接関係ないもの?
  • 状態中心のテスト

    • テスト対象の処理前後で状態の変化を検証する
  • 相互作用中心のテスト

    • テスト対象のオブジェクトのやり取り(どのメソッドが何回呼ばれたかなど)を検証する
  • 仕様はビジネスに使う言葉で表す

  • 仕様の粒度に気を付ける

漠然と思ったことなのですが、単体テストコードって仕様に対する品質保証より、プログラムに対する品質保証というかプログラマ心理的な安心を得るための役割の方が大きいのかなという気がしています。変更やリファクタリングするときとか。

なので、自動テストとは言っても、E2E のテストはさておき、JUnit などでやるようなメソッド単位のテストは、仕様を確認するというには少し粒度が細かすぎるのではないかという印象。

www.slideshare.net

後半は、Swagger, SpringFox, Spring REST Docs の話。なんとなくツールを使うモチベーションがズレてる気がして、ちょっと話を聞いててモヤモヤが...。