HDE BLOG

コードもサーバも、雲の上

新卒インターンのシンガポール出張レポート#day2

こんにちは!新卒インターンの豊崎です!

シンガポール出張2日目は、現地のパートナー企業さん訪問でした!

(他のHDEメンバーはIoT Asiaの一日目に出展していたので別行動です)


インターン達は、シンガポールでHDE Oneを販売して頂いている大切なパートナーさん(現地のリセラーさん)を2件訪問しました。


彼らのお話で印象に残っているのは、やはり「日本とシンガポールは異なる」ということ。

国が違えば、クラウドセキュリティの市場状況もそこで働く人々の文化も異なります。


東南アジアでは日本ほどセキュリティの意識が高くなく、HDE Oneへのニーズもまだまだこれからだとか。

(裏を返せば、これから伸びしろがあるということでもあるのでしょうか)

セキュリティの市場状況もさることながら、豊崎が一番印象に残っているのはシンガポールで働く人々の文化のお話です。


シンガポールは多民族国家なので、ローカルスタッフの方々にも宗教や文化の違いがあるのだとか。


シンガポールは多民族国家だからこそ、多様性が豊か。

こうした多様性はチームに多様な視点をもたらす一方で、制約を伴います。


ムスリムの方がいらっしゃれば、決まった時間に祈祷をされますし、お食事もハラールで無ければなりません。

また、ヒンドゥー教徒の方ならば、牛はNGです。


他にも宗教ではありませんが、欧米系の方にはベジタリアンの方も多いです。



そしてこうした制約は、これから日本が外国籍の方々と協力していく過程で必ず直面する問題でもあります。

(ちなみに、HDEでは祈祷室の設置など、多様性を尊重する会社作りを進めています!)


さて、もし読者の皆さんがこういった多様性のあるチームを率いるとしたらどうしますか?

例えば、宗教的な多様性のあるチームの夕食会の幹事を務めるとしたら??


本日僕達が訪問したパートナー企業さんいわく、そんな時は名の通ったホテルのビュッフェがオススメとのこと。


名の通ったホテルならば宗教への配慮がされている場合も多いですし、ビュッフェ形式なので個々人が自由に食事を選べて、チームみんなが楽しめる可能性が高いらしいです。


さすが多民族国家シンガポールのプロフェッショナルからの、ナイスアドバイスですね!

もちろん、ビュッフェならお腹をすかせた豊崎も大満足です!!

これで次回のインタナショナルチーム夕食会は、バッチリですね!

以上、豊崎でした!

明日はいよいよIoT Asia 2018の2日目に参加してきますのでお楽しみに!

シンガポール出張 一日目

こんにちは! 初めまして。 HDEで5日間のインターンを経験させていただいた、大学三年生林元と申します! 今回シンガポールで開催されるIOTのイベントに参加させて頂けることになりましたー! 5日間のシンガポールでの出来事を毎日更新していこうと思います。 まず、初日の今日。シンガポールに行くのは実は今回が三回目の私。それでも真夏の国に行けることもあってかなりワクワクしてました。f:id:maki-hayashimoto:20180322001651j:plain

出発前に思わず撮った一枚

七時間のフライトの後到着したそこはもう真夏の世界。東南アジア独特の匂いと蒸し暑さがすごく懐かしく思えました。電車に乗ってホテルまで移動したのですが、まあとにかくエスカレーターが早い。驚くほどのスピードです。そしてメトロのカードのデザインがドラえもんだったことにも驚きましたね。 f:id:maki-hayashimoto:20180322002133j:plain

ドラえもんがデザインされた交通電子系カード

中華系の夕食をみんなで美味しく食べて無事ホテルに到着。 f:id:maki-hayashimoto:20180322002407j:plain

初日の食事
明日から本格的に始まるイベントに向けてしっかり準備して寝ようと思います! 次回もお楽しみに。

新卒インターンのシンガポール出張レポート#day1

こんにちは!新卒インターンの豊崎です。

なんと、、、昨日から4日間、HDEのメンバーとしてシンガポールに出張に来ています!

インターンの大学生を海外出張に連れてくるなんて、なんとも稀有な会社ですね。

せっかくなので、海外出張記として、大学生目線でブログを書いていこうと思います。

出張1日目の本日は、飛行機での移動がメインでした。


なので今日は、豊崎の自己紹介と、シンガポール出張の背景について書いていこうと思います。

軽く自己紹介すると、

f:id:hiroshi-hde:20180321104423j:plain

(写真は右側)

豊崎 洋(とよさき ひろし)

・都内の大学4年生

・HDEの新卒採用のインターン中

・ITはわかりそうで、よくわからない文系出身

・趣味は海外ドラマ鑑賞(3度の飯よりNetflix)


さて、そんな今回のシンガポール出張の目的は、 IoT AsiaというイベントにHDEのブースを出展するためです!

現在のHDE のメイン事業は クラウドサービスのセキュリティですが 、今回のイベントの出展内容は、HDE の新事業のプロトタイプの披露です。

現在HDEは、「オフィスの中のIoT」をテーマに、次の事業を立ち上げようとしています。

そして次の事業は、立ち上げ段階から、 世界市場がターゲット。


そんな訳で、世界のIoT企業が集まる IoT AsiaでHDEの新規事業のプロトタイプを披露し、海外市場の反応を伺います。

インターン豊崎もHDEメンバーとして、ブースの運営をお手伝いします。

IoT Asiaへの出展の他にも、現地の企業さんを訪問したりと、濃密な4日間になりそうです。

明日もブログを更新するので、お楽しみに!

豊崎

43rd Monthly Technical Session (MTS) Report

43rd Monthly Technical Session (MTS) was held on February 16th, 2018. MTS is a knowledge sharing event, in which HDE members present some topics and have QA sessions, both in English.

First session was brought by Arakawa. The topic was CMC Webhook #2, continuation of his previous CMC Webhook talk which can be found here. He briefly explained about webhook notification and compared it to polling method. He then demonstrated how it works.

Arakawa - CMC Webhook #2
Arakawa - CMC Webhook #2

Next speaker was Stephen. His presentation title was Can Cities Be Hacked? Stephen began his presentation with his personal experience of losing a phone number that was used as a 2FA device. He then wondered whether a city can be hacked, in this age that is very connected to the internet. He then found some example of cities getting hacked, such as the Ukraine Power Grid Attack. He then explained things that developers should do when developing IoT, such as:

  1. Penetration testing
  2. Consult with CSIRT/CERT
  3. Have manual override of the system in case things go bad
  4. Availability of basic service must be guaranteed

He then concluded his presentation as follows:

  1. IoT/Software should always be designed with security in mind
  2. Ethics in software engineering is very important
  3. Government regulations needs to play a key role in ensuring safety of citizens

Stephen - Can Cities Be Hacked?
Stephen - Can Cities Be Hacked?

Next in the list was Ogawa. His presentation was about Haskell programming language. He explained several things about Haskell:

  1. Purely functional programming language
  2. Static typing with type inference
  3. Pattern matching
  4. Lazy evaluation by default
  5. Type classes
  6. Green threads

He emphasized his presentation on Pattern Matching and Lazy Evaluation features of Haskell language as well as the cool development tool Stack that Haskell offers.

Ogawa - A Brief Introduction to Haskell
Ogawa - A Brief Introduction to Haskell

Iskandar was our 4th speaker. He presented his journey to Indonesia to attend first PyCon ever held in Indonesia, PyCon Indonesia 2017, as a speaker. He began his presentation by showing where the conference was held, some local language, and other interesting stories of how PyCon Indonesia was prepared. He then proceed with the project he presented at PyCon Indonesia. His project can be found here. The slides he presented at PyCon Indonesia can be found here.

Iskandar - PyCon Indonesia 2017
Iskandar - PyCon Indonesia 2017

After Iskandar we had Alisha, our Global Intern from India, gave a talk on functional programming in Python. She started the presentation with functional programming paradigm. She explained some features of true functional programming, such as no side effects, immutability, recursion instead of loops, lazy evaluation, etc. She then followed up the explanation by showing functional programming can be done in python with certain ways. She ended her presentation with some points that python lacks in functional programming, such as:

  1. No tail recursion optimization
  2. Mutable Variables
  3. Impossible to separate pure & non-pure functions
  4. No pattern matching (can use libraries though)
  5. No automatic partial application

Alisha - Functional Programming in Python
Alisha - Functional Programming in Python

The next speaker was our second Global Intern from New Zealand, Edwin, who gave a talk about his project as a university student. He explained, in a non-electrical engineer friendly way, how he built a simple wireless charging toy car. He started his explanation on power electronics, which is the foundation of his project, along with the symbols on related electrical circuit he's using. He then showed us the video of his toy car moving along the track and stops at the wireless charging station and then go again endlessly. After showing the video and explaining how it works, he shared some things that he needed to overcome to realize the project such as power loss during switching, dead beat, and reverse recovery current.

Edwin - How to Build Your Own Simple Wireless Charged Toy Car
Edwin - How to Build Your Own Simple Wireless Charged Toy Car

Last but not least, our last speaker was Wei-Ting from Taiwan, our third Global Intern. He explained the science behind self-driving car based on his project at his university. The topics covered several aspects of machine learning, which in his case he did the clustering part. In his case, he modeled the terrain, objects, etc. using LiDAR. After obtaining the model, they preprocess the LiDAR data by denoising, downsampling, and ground filtering the data. Then, they feed it to clustering algorithm to separate the objects from each other. Finally they feed the clustered data to a Convolutional Neural Network (CNN) classifier to identify the objects. He explained the clustering algorithms he used to cluster the objects, those are building the minimum spanning tree, breaking the edges, running depth first search algorithm, and finally running minimum bounding box algorithm. In a nutshell, he explains how to separate object like items from the preprocessed LiDAR data.

Wei-Ting - Self-Driving Car: Perception
Wei-Ting - Self-Driving Car: Perception

As usual, we had a party afterwards :)

Beer Bash
Beer Bash

Vue.js ではじめるシングルページアプリケーションの開発

Vue.js は JavaScript フレームワークです。 ウェブアプリケーションのユーザーインターフェイス開発を支援する様々な仕組みを提供します。

f:id:gorotan35:20180228183927p:plain

管理画面はもちろん、HTMLエディタのようにユーザの入力に対して即応性が必要なアプリケーションを簡単に作ることができます。 例えば、テキストエリアに文字を入力すると、 デザインしたページの特定のDIV要素がリアルタイムに更新されるといったデータ反映の仕組みを備えています。

また、JavaScript で大規模なユーザーインターフェイスの開発を行う場合、HTMLファイルのテンプレート化、 JSファイルの依存関係、グローバル変数汚染など様々な課題に直面します。 Vue.js は、コンポーネントという仕組みと Webpack というモジュール管理ツールと組み合わせることで、 これらの課題にうまく対処できるようになっています。

今まで jQuery + Bootstrap でユーザーインターフェイスを開発していましたが、今回のプロジェクトではじめて Vue.js での開発にトライしました。 その経験をふまえて、Vue.js の開発環境や使い方、周辺ツールなどをまとめています。 これから Vue.js で開発を始める方の入門になれば幸いです。

開発環境

Vue.js は本家サイトのドキュメントが非常に充実しており、日本語にも翻訳されています。

jp.vuejs.org

Vue.js はプロブレッシブフレームワークという考え方で設計されており、 問い合わせフォームのような小規模なアプリケーションにも、Vue.js を適用できるように考慮されています。 このようなケースでは、jQuery と同様に <script> タグでロードすることで Vue.js を簡単に導入することができます。

しかし、中~大規模アプリケーションを開発する場合は、Node.js が提供する環境やツールを活用するため、 Node.js 上に開発環境を構築します。 例えば、ユーザーインターフェイスに必要な機能を実装するためには、 様々な JavaScript ライブラリを利用する必要があります。 これには npm という Node.js のパッケージ管理の仕組みを使用します。 また、JSファイルの依存管理やブラウザにロードするJSファイルを 作成するために、Webpack という Node.js 上で動作するツールを使用します。

Node.js を使いますので Linux サーバーがあると便利です。 幸い、Windows10 には Windows Subsystem for Linux (WSL) という便利なものがあるのでこれを使いましょう。 手元の環境は以下のバージョンです。

  • Windows10 (OS)
  • Ubuntu 16.04 (WSL)
  • Node.js 8.9.1
  • npm 5.6.0

Ubuntu (WSL)

このあたりを参考にインストールしてみてください。

qiita.com

Windows の Cドライブは、/mnt/c にマウントされます。 C:\dev フォルダを作成すれば、Linux からは、/mnt/c/dev でこのフォルダにアクセスできます。 Windows と Linux でシームレスにファイル参照・編集できるので、Windows 上のエディタでコードを書いて、 Linux 上で build & run できます。これは便利です。

Node.js

Ubuntu へ Node.js をインストールします。

$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ node -v
v8.9.1
$ npm -v
5.5.1

本家のドキュメントはここにあります。ご参考まで。 Installing Node.js via package manager | Node.js

vue-cli

続いて vue-cli をインストールします。 vue-cli は、Vue.js プロジェクトを作成するための支援ツールです。

$ sudo npm install -g vue-cli
$ vue -V
2.9.1

Vue.js プロジェクトを作成する

vue-cli を使ってプロジェクトを作成します。

$ vue init webpack-simple your-project

? Project name your-project
? Project description A Vue.js project
? Author masahiro.okubo
? License MIT
? Use sass? No

   vue-cli · Generated "your-project".

   To get started:

     cd your-project
     npm install
     npm run dev

$

scaffold には webpack または webpack-simple が指定できます。 webpack を指定すると ESLint や Test Runner などの開発ツール一式をインストールしてくれるのですが、 構成が複雑であるために自分で webpack.config.js を編集するのが難しかったです。 まずは、webpack-simple で最小限のプロジェクトを作成し、少しづつ周辺ツールを理解して、 自分のプロジェクトに組み込んでいくのが良いかなと思います。

your-project の部分は、あなたの開発プロジェクトの名前を指定します。 vue-cli を実行すると、プロジェクト名のフォルダが作成されます。ここに移動して、scaffold から生成された ファイルとディレクトリを確認してみます。

$ tree
.
├── README.md
├── index.html
├── package.json
├── src
│   ├── App.vue
│   ├── assets
│   │   └── logo.png
│   └── main.js
└── webpack.config.js

なるほど。シンプルですね。

このディレクトリで、npm install した後、npm run dev とすると、ブラウザが起動して、 Vue.js アプリケーションが実行されます。素敵です。 しかし、このサンプルから管理画面のようなアプリをどうやって作っていくのか、、、 コードを読んだところ、index.html にほぼ静的なページを出力するだけのサンプルだということがわかりました(汗)

とりあえず、main.js 読みましょう。

import Vue from 'vue'
import App from './App.vue'

new Vue({
  el: '#app',
  render: h => h(App)
})

Vue.js は ES2015(ES6) で開発します。モジュール管理(import / export)、オブジェクトリテラル、アロー関数など、 慣れ親しんだ JavaScript (ES5) の知識では理解できない仕様追加が盛りだくさんです。

オブジェクトリテラルの表記については、ここに情報がまとまっていて参考になりました。

qiita.com

Vue.js は、ES2015 で開発するのですがブラウザ互換を考慮し、 babel というES2015⇒ES5 変換ツール(トランスパイラーといいます)で、ES5に変換したコードをブラウザ上で動かすのが今のところ一般的です。 Webpack は複数のJSファイルの依存関係を import / export を頼りに解決して、ブラウザにロードする bundle.js という1つのファイルを出力します。 この過程の中で babel も実行されます。

この仕組みを知った時に、ブラウザが提供している開発ツール(デバッカ)が使えないのではないか? という疑問が沸きました。 これに対しては、SourceMap という、変換前のES2015コードと変換後のES5コードの対応表のような仕組みがありまして、 Chrome や Firefox が対応しています。

SourceMap は、webpack.config.js で指定します。

 53   performance: {
 54     hints: false
 55   },
 56   devtool: '#eval-source-map'
 57 }

指定可能な SourceMap の種類はここに。 Devtool

私の環境ではこの設定で今のところ安定動作しています。

 53   performance: {
 54     hints: false
 55   },
 56   devtool: 'inline-source-map'
 57 }

ここまでをまとめます。

  • Vue.js は Node.js 上の開発環境でプロジェクトを構築していきます。
  • vue-cli というツールが最初のプロジェクト立ち上げを支援してくれます。
  • ES2015 で開発します(知らない場合は勉強します)。
  • プロジェクトの管理は Webpack で行います(知らない場合は勉強します)。
  • ES2015 で書いた複数のJSファイルは、Webpack が依存関係を解決して、babel がES5に変換してブラウザにロードされます。
  • SourceMap が必要ですが、うまく動けばブラウザ上でデバック可能です。

シンプルな管理画面を作ってみる

一般的なウェブアプリケーションを開発するには以下のような機能が必要かと思います。

  • ナビゲーション、サイドメニューなどの基本的な画面レイアウト
  • サーバーと通信するための Ajax ライブラリ
  • ナビゲーションやメニューからの画面遷移
  • 一覧(テーブル)、入力フォーム(ダイアログ)など CRUD に必要な部品

CSSフレームワークを導入する

まずは、CSSフレームワークを導入して基本的な画面レイアウトと、メニューやダイアログなどの部品を手に入れたいところです。 Bootstrap がメジャーどころですが、今回は Semantic-UI を使います。

Webpack は JSファイルのほか、CSSや画像など、 ウェブアプリケーションに必要な各種のリソースも管理できるのですが、 今回のプロジェクトでは、CSSフレームワークは Webpack の管理対象外として以下のように index.html に記述しました。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <meta http-equiv="x-ua-compatible" content="ie=edge">
      <link rel="stylesheet" href="/ext/semantic/semantic.css"/>
    <title>Sample App</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="/ext/jquery.js"></script>
    <script src="/ext/semantic/semantic.js"></script>
    <script src="/dist/bundle.js"></script>
  </body>
</html>

jQuery の使いどころ

【2018-03-12 訂正】
この記事では Semantic-UI + jQuery を使って、UIを実装していますが、 Bulma というCSSのみで実装された(=jQueryを使わない)UIフレームワークがありまして、現在はこちらを試しています。 Vue.js + Bulma を使った管理コンソールの実装は、vue-admin がとても参考になります。 また、Element, AT UI, Vuetify.js など、Vue.js には素晴らしいUIフレームワークがいくつもあります。 どのUIフレームワークの選定するかは要件によるかと思いますが、 これらのUIフレームワークはカスタムコンポーネントとして実装されており、 素のHTMLでUIデザインができないため、現時点での当方のプロジェクトでは採用を躊躇しています。

github.com

イベントハンドリングやデータバインディングの仕組みは Vue.js が提供しています。 Vue.js 2.x 系は、バーチャルDOMというレンダリング高速化の仕組みが裏で動いています。 このバーチャルDOMが実DOMに反映されるまでは、jQuery から DOM操作ができないなど、 Vue.js と jQuery の併用はちょっと注意が必要とのこと。 原則、jQuery は使わない方が良いようですが、Bootstrap や Semantic-UI など、CSSフレームワークのコンポーネントは、 jQuery で実装されているので、まったく使わないというわけにもいきません。

Vue.js のインスタンスは、ライフサイクルフックという関数があり、バーチャルDOMが実DOMに反映された際に、 mounted というフック(関数)が呼ばれるそうです。また、バーチャルDOMが再描画された際には updated というフックが 呼ばれます。これらのタイミングで、CSSフレームワークが提供する JavaScript を実行したり、 jQuery を使って CSSを操作して画面の見た目を制御するといった使い方に限定するのが安全ではないかと思います。

jp.vuejs.org

【2018-03-06 訂正】
取り消し線の部分について、Vue.js はCSS操作ができないような印象を与えてしまう書き方でしたので訂正します。 Vue.js では v-bind:class または v-bind:style を用いて CSSのクラスやスタイルを操作することができます。 後述のサンプルではページネーションのボタン制御に v-bind:class を使用する例があります。

jp.vuejs.org

Ajax 通信はどうするの?

以前は vue-resource という Ajax リクエストを処理するパッケージがあったそうですが引退されたようです。 鉄板である jQuery はできるだけ使うなと。google 先生に聞くと axios が良いとおっしゃられるので素直に axios を使いましょう。

github.com

"Promise based HTTP client for the browser and node.js" とありますが、JavaScript で非同期処理をやるには Promise 便利ですね。 インストールも npm install --save axios で OK. 使い方も簡単です。mock-adapter があるので単体試験もできます。使わない理由がありません。

github.com

開発が少し進むと、「computed で非同期処理できないの?」と思うことがあります。 vue-async-computed というパッケージがあって、Promise を返してあげればちゃんと動作するので、これいいかなーと思ったのですが、 関連する値の変化でリアクティブに動作する computed で、Ajax 通信するので、サーバー側に意図せぬ処理負荷を発生させそうな気がするのと、 Ajax通信が失敗した場合の再実行(computed は値変化がないと実行されない)などの考慮が必要だなと思いました。 computed で非同期処理はできるのですが、用途をよく考えた方が良いように思います。

GitHub - foxbenjaminfox/vue-async-computed: Async computed properties for Vue.js

画面遷移はどうするの?

Vue.js 単体では画面遷移はできません。 vue-router というパッケージを導入します。

はじめに · vue-router

vue-router の使い方は簡単です。CSSフレームワークのナビバーやサイドメニューを配置して、 <a> タグの部分を <router-link> タグに置き換えます。あとは、JavaScript で パスとコンポーネントを紐付けする定義を書いてやれば OK。 特に悩むところなく使えました。 バーチャルDOMの効果もあるのか、画面遷移はものすごい高速です。 これぞ、SPA(シングルページアプリケーション)だ!という感じでちょっと感動します。

画面はどうやって作るの?

CRUDの入り口になる一覧画面や、データ編集のためのダイアログは、Vue.js の単一ファイルコンポーネントで作っていきます。

jp.vuejs.org

単一ファイルコンポーネントは、.vue ファイルに、HTMLと CSS と JavaScript をまとめて書けるので依存関係の可視性が良いです。 どのような単位でコンポーネント化していくかは、プロジェクトの方針やアプリケーションの特性によるかと思います。 今回のプロジェクトでは、CRUDの画面単位にコンポーネント化することにしました。

画面はどのように制御するの?

単一ファイルコンポーネントで実装したユーザ一覧画面をサンプルに、Vue.js での画面の制御を見ていきます。

f:id:gorotan35:20180228172633p:plain
ユーザー一覧画面

赤枠の部分がコンポーネントになっています。

<template>
  <div class="ui segment">
    <!-- loader -->
    <div id="loader" class="ui inverted dimmer">
      <div class="ui text loader">Loading</div>
    </div>
    <!-- title -->
    <h3 class="ui dividing title header">ユーザー管理</h3>
    <!-- control -->
    <div class="ui small stackable control form">
      <div class="fields">
        <div class="four wide field">
          <button class="ui blue button" v-on:click="add">追加</button> ・・・①
        </div>
        <div class="four wide field">
          <select class="ui fluid dropdown" v-model="cond.workspace" v-on:change="search">・・・②
            <option value="all" selected="selected">全てのワークスペース</option>
            <option value="wid1">ワークスペース#1</option>
            <option value="wid2">ワークスペース#2</option>
          </select>
        </div>
        <div class="four wide field">
          <input type="text" placeholder="アカウント"
            v-model="cond.account" v-on:keyup.enter="search">・・・③
        </div>
        <div class="two wide field">
          <button class="ui button" v-on:click="search">検索</button>
        </div>
        <div class="two wide right aligned field">
          <div class="ui narrow buttons">
            <button class="ui icon button" v-bind:class="{'disabled': isMinPage}" v-on:click="prev">・・・④
              <i class="left chevron icon"></i>
            </button>
            <div class="ui button">{{ page }}</div>
            <button class="ui icon button" v-bind:class="{'disabled': isMaxPage}" v-on:click="next">
              <i class="right chevron icon"></i>
            </button>
          </div>
        </div>
      </div><!-- ./fields -->
    </div><!-- ./ui form -->
    <!-- content -->
    <table class="ui celled striped table">
      <thead>
        <tr>
          <th class="four wide">アカウント</th>
          <th class="three wide">権限</th>
          <th class="four wide">氏名</th>
          <th class="three wide">最終ログイン</th>
          <th class="one wide center aligned">2FA</th>
          <th class="one wide center aligned">操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="user in users" v-bind:key="user.id">・・・⑤
          <td><div class="ui link" v-on:click="edit(user)">{{ user.account }}</div></td>・・・⑥
          <td>{{ user.role }}</td>
          <td>{{ user.name }}</td>
          <td>{{ user.lastlogin }}</td>
          <td>{{ user.tfa | labeled2fa }}</td>
          <td class="center aligned">
            <button class="ui icon mini orange button" data-content="削除する" v-on:click="remove(user)">
              <i class="remove icon"></i>
            </button>
          </td>
        </tr>
      </tbody>
    </table>
    <users-edit v-bind:user="target"></users-edit>・・・⑦
    <users-remove v-bind:user="target"></users-remove>
  </div><!-- ./ui segment -->
</template>

<script src="./list.js"></script>

HTMLソースに①~⑧までの番号があります(横スクロールして確認してください)。 それぞれ何をしているのか説明します。

①ボタン
Vue.js では、HTMLタグに、「v-on:イベント名="処理(または関数)"」という書式でイベントハンドラを登録します。 この例では、「追加」ボタンが押されたら、add 関数を呼び出しています。 (JavaScript については、後述を参照ください)

②リスト
select タグの値は、v-model="cond.workspace" でバインディングしています。 これにより選択リストの値が変更されると、Vue.js が cond.workspace に自動的に値を代入してくれます。 また、v-on:change="search" で、リストの選択値が変更された場合、search 関数を呼び出して一覧を更新します。

③入力フィールド
select タグと同様、v-model="cond.account" でデータバインディングします。 また、 v-on:keyup.enter="search" で、改行キーが入力された場合、search 関数を呼び出して一覧を更新します。 (自分で実装したら結構面倒なコードを書く必要がありますよね。これは便利だと思います)

④ページング
ページングの「前へ」「次へ」ボタンの制御です。 v-bind:class="{'disabled': isMinPage}" は、 isMinPage が true を返したら disabled というCSSクラスを追加する。 という制御をしています。Semantic-UI のボタンは、disabled が指定されると見た目を制御し、かつ、 クリックイベントも発生しなくなるので、これだけでページングボタンの制御はおしまいです。 v-on:click="prev" で「前へ」ボタンがクリックされたら、prev 関数を呼び出して前ページを表示します。 同じ制御を、「次へ」ボタンの方でも行います。

⑤テーブル(行)
v-for="user in users" で、コンポーネントが持つ、users 配列から user オブジェクトを取得します。

⑥テーブル(列)
⑤で取得した user オブジェクトを使って一覧に必要な情報を表示します。 td タグの中に、{{ user.account }} と書けば、user オブジェクトの account プロパティが表示されます。 また、v-on:click="edit(user)" の部分では、アカウントのリンクをクリックしたら、編集ダイアログを表示する制御をしています。 edit 関数には、※この行の user オブジェクト※が渡されます。

⑦ダイアログ
アカウントのリンクをクリックした際に表示されるダイアログは、別コンポーネントとして実装しています。 ※この v-bind がうまく動いておりません。ただいま調査中

続いて、JavaScript です。 単一ファイルコンポーネントでは、script タグに直接 JavaScript を書けますが、 .vue ファイルは、SourceMap に対応していないようなので、ブラウザ上でのデバックを考慮して、JSファイルに記述しています。

import UsersEdit from './edit.vue';
import UsersRemove from './remove.vue';
import UsersAPI from '@/apis/setting/users.js';

export default {
  components: {
    UsersEdit,
    UsersRemove
  },
  data () {・・・①
    return {
      cond: {
        offset: 0,
        limit: 10,
        workspace: 'all',
        account: ''
      },
      users: [],
      target: {}
    }
  },
  filters: {・・・②
    labeled2fa: function(tfa) {
      return fta ? "有効" : "無効";
    }
  },
  computed: {・・・③
    page () {
      return (this.cond.offset / this.cond.limit) + 1;
    },
    isMinPage () {
      return this.page <= 1;
    },
    isMaxPage () {
      return this.page == 10 || this.users.length < this.cond.limit;
    }
  },
  methods: {・・・④
    add () {
      $('#setting-users-edit').modal('show');
    },
    edit (user) {
      this.target = user;
      $('#setting-users-edit').modal('show');
    },
    remove (user) {
      this.target = user;
      $('#setting-users-remove').modal('show');
    },
    prev () {
      this.cond.offset -= this.cond.limit;
      this.find();
    },
    next () {
      this.cond.offset += this.cond.limit;
      this.find();
    },
    search () {
      this.cond.offset = 0;
      this.find();
    },
    find () {
      var self = this;
      $('#loader').dimmer('show');
      UsersAPI.find(this.cond,
        function(users) {
          $('#loader').dimmer('hide');
          self.users = users;
        },
        function(message) {
          $('#loader').dimmer('hide');
          // TODO show error message
        });
    }
  },
  mounted () {・・・⑤
    this.find();
    $('.ui.orange.button').popup();
  },
  updated () {
    $('.ui.orange.button').popup();
  }
}

①データ
Vue.js のコンポーネントは、data プロパティで取り扱うデータを定義します。 マニュアルにもありますが、コンポーネント化する場合は、取り扱うデータオブジェクトを返す関数として定義します。 cond プロパティには、検索条件とページングのための offset / limit を持っています。 cond.workspace と cond.account はHTML部分で説明した通り、v-model でバインドされているので勝手に値が入ってきます。 users は初期値は空配列ですが、UsersAPI.find() で、サーバーからデータを取得して users にセットします。 すると、v-for が反応して users の内容がテーブルにレンダリングされます。

②フィルタ
user.tfa は2要素認証する/しないの boolean 値なので、フィルタを使って表示用のラベルに変換しています。 HTMLの該当箇所が、{{ user.tfa | labeled2fa }} という表記になっていますが、これで、user.tfa が labeled2fa(tfa) の引数 tfa に渡ります。

③算出プロパティ
これが Vue.js の一番面白い機能ではないかなと思います。 算出プロパティの中で、data に定義した値を使った処理を実装します。 data の値が変化すると、算出プロパティが自動で再計算されます。 このサンプルでは、cond.offset と cond.limit からページ番号を計算する部分と、最小/最大ページの判定に、 算出プロパティを使っています。

④メソッド
イベントハンドラから呼び出したい関数や、このコンポーネントの内部処理は、methods プロパティに記述します。 メソッドは、Vue インスタンスの this に直接登録されるらしく、this.メソッド名でアクセスできます。 ダイアログの表示は、Semantic-UI のライブラリを呼び出しており、このあたりで jQuery を使う必要があります。

⑤インスタンスライフサイクルフック
ここがベストのタイミングなのか悩んでいますが、mounted した際にサーバーからユーザリストを取得して、 users に値代入しています。users に値代入するとリアクティブに v-for が動いてテーブルがレンダリングされます。 $('.ui.orange.button').popup() は、データ削除のための「×」ボタンにマウスオーバーすると「削除します」というツールチップ を表示させるために実行しています。 検索条件を変えて、再度一覧を表示すると、行列要素( tr / td タグ)が書き換えられるので、 updated で再描画があったら、popup を再登録するようにしています。 このあたりが jQuery との併用に注意しなければならない部分だと思います。

まとめ

学習コストはけっして安くはありませんが、 非常によく考えられたフレームワークだと思います。 複雑になりがちなフロントエンドのソースコードを、 とてもシンプルに記述することができるという印象を持ちました。

少ないコード量で業務に必要な処理が実装ができれば開発速度も上がりますし、 バグ混入リスクが減るため品質も上がるのではないかと期待しています。

最後に、HDEではフロントエンドエンジニアを募集しています。 ぜひ、当社リクルートサイトもご覧ください。

recruit.hde.co.jp

42nd Monthly Technical Session (MTS) Report

42nd Monthly Technical Session (MTS) was held on January 19th, 2018. MTS is a knowledge sharing event, in which HDE members present some topics and have QA sessions, both in English.

The moderator of the 42nd MTS was Hayashi. f:id:michael-wangsa:20180202200312j:plain

First topic was Okubo's introduction on JavaScript framework Vue.js. He began his explanation on reasons we should use vue.js by showing us a video from https://vuejs.org/index.html. Then he continued with the history of technology stack evolution throughout his career. He concluded his presentation with tips and tricks on how to develop vue.js applications.

f:id:michael-wangsa:20180202195639j:plain

Second topic was about WebAssembly and Go by Shinohara. He began with the explanation of WebAssembly and why WebAssembly is needed. Then he proceeded with the use cases of WebAssembly. He also explained why WebAssembly is fast. After explaining WebAssembly, he went on explaining WebAssembly support in Golang. Golang support will be released with version 1.11 around this summer. He tried the Golang support for his project and it failed for several reasons. One of the reasons is there are too many TODO to support WebAssembly in Golang.

f:id:michael-wangsa:20180202200229j:plain

Third topic was brought by Xudong. His talk was about how to optimize memory usage within embedded system's SoC. SoC (System on a chip) has built in RAM and ROM memory for programming, but the their sizes are limited. Their sizes are so limited that he has to do some careful planning on things that really matter to be put inside the ROM and runtime execution of the program not to go beyond limited size of the RAM. He shared some of his experiences, tips, and tricks to do programming on such system.

f:id:michael-wangsa:20180202200518j:plain

Fourth topic was about AWS Batch brought by Doi. In the beginning of his presentation he recommended us to watch the video from AWS Re:Invent 2017 titled CMP323 - AWS Batch: Easy and Efficient Batch Computing on AWS for deeper understanding on AWS Batch. He began his presentation by explaining in simple terms about AWS Batch and showed an example of system architecture built in AWS Batch. He explained some components that are important in running AWS Batch, which are AWS Batch Definitions, Job Submission, and VPC Configuration. He stressed the important points in VPC configuration that should be enabled are MapPublicIpOnLaunch, EnableDnsSupport, EnableDnsHostnames which might not be enabled by default when building new VPC. He then showed us some demo on AWS Batch.

Here are some links that Doi recommends to start using AWS Batch:

f:id:michael-wangsa:20180202200606j:plain

Fifth topic was brought by Bumi, it's the continuation of his previous Elasticsearch MTS Presentation. He explained various use cases of Elasticsearch and recommendation on where to host it. Bumi began his presentation by explaining the application search feature of Elasticsearch and why we would want that. Then he moved to a real use case: operational log analytics. He explained that analyzing logs is arguably the most popular use-case of Elasticsearch because search is not only about matching text but matching everything including timestamps, app code, IP addresses, etc. Combined with its partner, Kibana, the logs can be transformed into interesting visualizations which are easy to digest for both programmers and decision makers. He mentioned three ways to host Elasticsearch:

Bumi didn't recommend building your own cluster because it might be too much of a burden for your organization. He also presented some pros and cons of using hosted Elasticsearch service between Elastic Cloud and AWS Elasticsearch Service.

f:id:michael-wangsa:20180202200701j:plain

Last but not least, our intern Jazman presented The Art of Storytelling. The presentation content was about his internship experience in Japan. He began his presentation with his story of new year holiday to Kyoto. He went to Kyoto using the local train with Seishun-18 Ticket and got on the wrong train on the way to Kyoto, but he managed to correct his course and reach Kyoto safe and sound. He also shared another story of his train trip when he went back from Asakusa to Shibuya but he ended up in Saitama. Then he explained the point of telling his story, everyone's story is unique and different.

He stressed several points about stories:

  • Stories connects people.
  • Stories makes people understand.
  • Stories gives people a new perspective.
  • Stories enables people to learn something new.

f:id:michael-wangsa:20180202200809j:plain

As usual, we had a party afterwards :) f:id:michael-wangsa:20180202200856j:plain f:id:michael-wangsa:20180202201043j:plain f:id:michael-wangsa:20180202201139j:plain

41st Monthly Technical Session (MTS) Report

41st Monthly Technical Session (MTS) was held on December 15th, 2017. MTS is a knowledge sharing event, in which HDE members present some topics and have QA sessions, both in English.

The moderator of the 41st MTS was Tanabe-san.

f:id:bagus-rahman:20171220202715j:plain

The first topic was "GIP Brand: Redefined" by Jazman-san. He is one of our Global Internship Program (GIP) participants. According to Business Dictionary, brand is a unique design, sign, symbol words, or a combination of these, employed in creating an image that identifies a product and differentiates it from its competitors. His task during his internship is to refresh the brands of GIP and HDE as an employer.

In order to achieve those tasks, Jazman-san is going on a 2 months long campaign on social media. Based on his analysis, there is a loss of potential applicants due to the lack of showcasing internship activities. Naturally then, his goal with the campaign is to gain more GIP applicants by showcasing internship activities at HDE, Inc. in a fun, exciting, and comprehensive way.

He went on to explain various aspects of the campaign, such as its objectives, identity (logo, title, mood and tone, color palette) target audience, framework, and timeline. He ended his session by reporting the progress of the campaign. In a relatively short time, the campaign has significantly improved the reach, post engagements, and net likes of GIP's Facebook page.

f:id:bagus-rahman:20171220202741j:plain

The second topic was "Basic Knowledge about Authentication" by Okumura-san. He explained several standards related to authentication and authorization. To put it simply, authentication is the process of ascertaining that someone really is who one claims to be. On the other hand, authorization refers to rules that define who is allowed to do what.

Okumura-san explained standards such as SAML, OpenID, OAuth, and OpenID Connect. In very general terms, in SAML, service providers redirect users to a predefined identity provider, which does the authentication. One of the ways OpenID differs from SAML is in the way that relying parties provide users options of OpenID providers.

OAuth is an authorization standard. Similar to SAML, service providers redirect users to a predefined identity provider. However, instead of an assertion of identity, the response from an identity provider is an access token that may grant service providers access to the identity provider's APIs on the user's behalf. OpenID Connect is a simple identity layer on top of OAuth 2.0. It allows clients to verify a user's identity based on the authentication performed by an authorization server.

f:id:bagus-rahman:20171220202814j:plain

The third topic was "Rust and the Web Platform" by Hugo-san. He was also one of our GIP participants. He began by explaining the concepts related to Rust itself, such as asm.js, WebAssembly, and emscripten. asm.js is a low-level strict Javascript subset. It is still JavaScript, with some performance benefits. WebAssembly is a low-level bytecode format. Recently, Rust supports compilation to WebAssembly. Emscripten is a source-to-source compiler. It allows code written in statically-typed languages with memory management to be translated to JavaScript.

According to Hugo-san, some of the main properties of Rust are safety and control. He likes that Rust has types, sets variables as immutable by default, uses modern syntax but can also be low-level, and provides validations during compilations. One downside of Rust that he pointed out was the absence of a garbage collector. Instead, it utilizes lifetimes to keep track of usage scope and object destruction. He also explained how to compile a Rust code to WebAssembly.

f:id:bagus-rahman:20171220202839j:plain

The fourth topic was "Our AI Overlords" by Kirby-san. He was also one of our GIP participants. AI has been advancing rapidly in recent years. In his talk, Kirby-san explained the many feats AI has achieved. He first explained AlphaGo, the first computer program to defeat a professional human Go player (in 2015). Fast forward two years later, AlphaGo managed to defeat a Go world champion. Its most recent incarnation, AlphaGo Zero, is an AI neural network with 0 human data.

DeepMind, the team behind AlphaGo, is now aiming to conquer another game, StarCraft II. The game's rich and multi-layered gameplay makes it an ideal environment for AI research. Another team, OpenAI created a bot which beat the world's top professionals at 1v1 matches of Dota 2 under standard tournament rules. Interestingly, players eventually managed to beat the bot (for now?) by way of unconventional strategies.

Obviously, AI can do so much more than win games. It can drive cars, recognize faces, reduce data center cooling bill, and even recreate Nobel-winning physics experiment. The potential of AI had a lot of people talking. Some believe AI will eventually supersede humans, which raised concerns of regulation. Still, some others believe it is still too early to regulate or worry to much about AI.

f:id:bagus-rahman:20171220202908j:plain

The fifth topic was "Hands on AWS Fargate" by Michael-san. AWS Fargate, introduced at AWS re:Invent 2017, is a technology for Amazon ECS and EKS that allows you to run containers without having to manage servers or clusters. In other words, it is the ECS and EKS you know, only without the need to manage EC2 instances. There's no need to manage EC2 count, ECS agent, auto scaling groups, task placement, networking, etc.

According to Michael-san, what's so good about AWS Fargate is that it makes scaling easier, integrates with load balancers seamlessly, and equips each task with its own network interface. On the other hand, Fargate is not cheap and provides limited log processor choice, at least for now. He ended his talk by demonstrating how AWS Fargate works.

f:id:bagus-rahman:20171220202942j:plain

The sixth topic was "QQ English in Cebu" by Tsukuda-san. He went to Cebu last month to learn English for 4 weeks. QQ English is located in Cebu IT Park. There are about 1,000 teachers in QQ English, all of which have international licenses for teaching English.

On the first day, students had a placement test. Classes started at 9 AM and ended at 6 PM. There were 8 classes in a weekday, each of which lasted for an hour. Tsukuda-san's curriculum consisted of listening, grammar, pronunciation, reading, group discussion, and more. On the last day, students had another test to check their progress.

Tsukuda-san also shared how he spent his weekends at Cebu. He went to a shooting club in Mactan and spent some time in Pandanon Island. He also introduced some Filipino foods, such as Lechon and Balut.

f:id:bagus-rahman:20171220203016j:plain

The seventh topic was "ServerlessConf Tokyo 2017" by Jeffrey-san. ServerlessConf Tokyo 2017 was held on November 2nd and 3rd. The first day was for workshops. In the AWS track of the workshops, participants were separated into teams and asked to create either a dashboard, chat, or dating application using only AWS serverless technology. After 8 hours of coding, his team became one of the few ones that managed to finish their application.

The second day was for the conference itself. Jeffrey-san learned quite a lot of interesting things, the first of which is Serverless Event Gateway. It allows serverless functions to communicate across different cloud providers using a set of standardized event format, using a publisher/subscriber model. Microsoft came full force to the conference with Microsoft Azure Functions, which supports JavaScript, C#, and F#. Durable Functions is its extension which allows user to write stateful function in a serverless environment. There was also a talk about serverless patterns.

Jeffrey-san was not only an audience of the conference, but he was also a speaker. The title of his talk was "AWS Lambda Pain(less): Adventures in Stream Processing". He taught the audience the high-level architecture of one of his projects and the lessons he learned from its development.

f:id:bagus-rahman:20171220203047j:plain

The eighth topic was "Office Tour in San Francisco" by Doi-san. The intent of this office tour is to learn how the companies in San Francisco are organized, how they run their business, and how they build successful company cultures. He went to several offices in San Francisco, like Oracle and Box. He also visited Googleplex and Apple Park Visitor Center.

Doi-san learned the most from his visit to Box' office. The office itself has many interesting features, such as cafetaria, bar, pool tables, table tennis tables, presentation halls, and more. Apparently, Box' employees regard the office as one of their communication tools. They display customers' use cases at the entrance and use customer names as room names. Box define their core values and applies them everywhere, on their products, working style, hiring process, etc. He also learned about Box' release flow and how they automate parts of their customer success efforts.

f:id:bagus-rahman:20171220203126j:plain

The ninth topic was "re:Invent 2017" by David-san and Ito-san. As you may have already known, re:Invent is Amazon Web services' global customer and partner conference, which is held annually. This year, the event was held November 27 - December 1. They began by explaining what Las Vegas was like, such as the weather, the hotels, and the gambling.

The impression that they got from attending re:Invent 2017 is that the world of cloud computing is shifting to serverless and container. re:Invent 2017 is considerably larger than its past iterations. There were more than 40,000 attendees (an increase of 35% from last year), 6 venues (twice compared to last year), and about 1,000 sessions. Some of the sessions they found interesting are "NEW LAUNCH! AWS Serverless Application Repository", "Deep Dive on AWS CloudFormation", "Advanced Design Patterns for Amazon DynamoDB", "Tools Won't Fix Your Broken DevOps", "Life of a Code Change to a Tier 1 Service", and "Serverless Architectural Patterns and Best Practices". Besides these sessions, they also took interests in Amazon Alexa, AWS X-Ray, Amazon Neptune, AWS Cloud9, and many more.

They also participated in some non-technical activities such as Pub Crawl and re:Play Party. There were even activities such as Tatonka Challenge, 4K Run and Harley Ride. They ended this session by giving various advice for next year's participants.

We've also written an article about AWS re:Invent 2017 on-site activities. The article elaborates on workshop, hands-on, and JAM sessions.

f:id:bagus-rahman:20171220203204j:plain

The day of the 41st MTS was also the last day of Hugo-san and Kirby-san's internships. We had a small event for them and gave them some souvenirs. In turn, they shared their impressions of their time working for us. Thank you very much for your contributions, Hugo-san and Kirby-san!

f:id:bagus-rahman:20171220203254j:plain

f:id:bagus-rahman:20171220203326j:plain

As usual, we had a party afterwards :)

f:id:bagus-rahman:20171220203453j:plain