狛ログ

2020年2月5日水曜日

Spring Fest 2019に参加してきました。

2月 05, 2020

オフィス狛 技術部のJoeです。

去年、Spring Fest 2019(12/18 御茶ノ水ソラシティ)が開催されました。
弊社プロジェクトの一部でSpring Bootを使用しているため、情報収集を目的に今回初めて参加してみました。
年々参加者数が増えているとのことで、とてもたくさんの方が来場されていました。

と言うことで、年は明けてしまいましたが、感想をブログに残したいと思います。

【公式ページ】
https://springfest2019.springframework.jp/

基調講演

Spring Boot 2.2の概要、2.3の紹介がありました。
そのなかでも気になったのが、今後、Spring Bootはリリース周期が1年から6ヶ月と短くなるそうで、バージョンアップのタイミングにも注意が必要になりそうです。また、2.1系は2020/11にEOLとなるそうです。

Spring Boot爆速開発超絶技巧

サムライズムさん
https://speakerdeck.com/yusuke/spring-boot-and-intellij-idea-technique
これまで開発では、STSしか使用したことが無かったのですが、「IntelliJ IDEA」とはどのようなものか、タイトルにも興味があり参加してみました。
極力キーのみで操作するということで、様々なショートカットを使用したデモでは、早い、便利と大変驚きました。
機会があれば無料版を弄ってみようと思います。

徹底解剖Spring MVCアーキテクチャー -DispatcherServletの中身を覗いてきました

カサレアルさん
https://www.slideshare.net/ssuser070fa9/spring-fest-2019spring-mvc
Spring MVCのアーキテクチャーをソースコードリーディングで解説されていました。
スライドの内容が主にソースコードでしたので、なかなか説明に追いつけずに苦労しましたが、内部構造まで説明があり、他のセッションと比べて内容が深かったです。
(周りの参加者の皆さんは、ノートPCやタブレットでスライドを参照されて便利そうでした。。。次回は用意しようと思います)

システム間連携を担うSpring Integrationのエンタープライズ開発での活用

NTT DATAさん
https://www.slideshare.net/apkiban/spring-integration-207667949
異なる仕様やオンプレ×クラウドなどのシステム間連携が増える中で、システム間連携の技術として、Enterprise Integration Patternsで推奨されている「非同期メッセージング」を実現するために「Spring Integration」を紹介されていました。
「Message」、「Channel」、「Endpoint」のキーワードとフローを用いた概要と、実際の作成ステップなど説明があり、勉強になりました。

Spring Developer のための コンテナ入門

Google Cloudさん

Kubernetes、Jibと勉強不足で初めて聞く単語でしたが、Jibを使用することでJavaのアプリケーションのDockerコンテナを簡単に作成できることに驚きました。Kubernetesについては、コンテナ管理(監視や制御)を知ることができました。

JSP/JSF から Spring Web + Thymeleaf への移行

伊賀 敏樹さん
https://www.slideshare.net/ssuser2e0217/practical-migration-from-jsp-to-thymeleaf
Thymeleafの紹介と利点についてのセッションでした。Thymeleafは使用しているので復習になりました。

Springアプリケーションのテスト道具 使いどころ、使わないどころ

いろふさん
https://speakerdeck.com/irof/decide-to-use-test-tool-for-spring-application
Springのテスト道具として、JUnit 5、Mockito、Spring Test、Selenium、Dockerの紹介から始まり、
「原則として、テストしたいことの近くでテストを行う」、「道具の向き不向きを考えてテスト道具の使いどころを見極める」ということに重点を置いて説明されていました。
Springというより、テストについて改めて勉強になったセッションでした。


1日のセッションを通じて、自身はまだまだスキル不足だと実感しましたが、新しい情報を得ることができ、非常に勉強になりました。
次回も是非参加したいと思います。


Illustratorで作ったボタンをCSSで再現したい。

2月 05, 2020

こんにちは、オフィス狛 デザイン部のSatoです。

今回はIllustratorでデザインを作ったオブジェクトのグラデーションなどの設定をCSSで再現したい時に使える機能をご紹介します。
この機能のを使えばグラデーションが細かいボタンをの色をCSSで数分で再現できるのでコーディングがかなり楽になります。最高の機能なのでもうAdobeに足を向けて寝れません!


Illustratorのグラデーション機能を使い作成したボタンを用意しました。
色が多くて設定も少し複雑なのでCSSで再現するのが大変そうです。


今回は「CSSプロパティ」という機能を利用してグラデーションの色味などの設定を書き出していきます。

最初にCSSプロパティパネルをワークスペースに表示させます。
Illustratorメニューバーの「ウィンドウ」の「CSSプロパティ」をクリックします。
CSSプロパティパネルがワークスペースに表示されます。

グラデーションの設定をコピーしたいオブジェクトのオブジェクト名を設定します。
オブジェクト名がclass名になるので、class名で使用できる文字以外(全角英数字や日本語など)を入れると何も設定を変更していない場合エラーでCSSを生成してくれません…(書き出しオプションで「名称未設定オブジェクト用に CSS を生成」にチェックを入れると書き出してくれるようになるようです)

グラデーションの設定をコピーしたいオブジェクトを選択するとCSSプロパティパネルにCSSが表示されます。
選択スタイルをコピーボタンをクリックすると生成されたCSSが全てコピーされます。
これをcssファイルにペーストすると色、角丸の角度などが設定できました。

ボタンの高さや幅、ボタンの中のフォントサイズなどの調整は必要ですがIllustratorで作ったボタンをほぼそのまま再現できます。
CSSのグラデーションに苦手意識があったのでいつも時間がかかっていたのですが、この機能を知ってから数分でグラデーションを再現できるようになったので助かっています。


2020年1月27日月曜日

2020年オフィス狛の年賀状の制作秘話

1月 27, 2020


新年あけましておめでとうございます!オフィス狛 デザイン部のSatoです。
今年もどうぞよろしくお願いいたします。

もう一月も終わってしまいそうですが、デザイン部の年明け初めての記事ですので今年の年賀状のおはなしをしようと思います。
(今まで全然紹介してこなかったのですが、2018年の年賀状から毎年私がイラストを描いています)


2020年の年賀状はこちら!

弊社サイトやSNSなどのアイコンなどで登場している狛犬ちゃん(社内ではたまに「こまちゃん」と呼ばれています)が今年の干支であるネズミの着ぐるみを着ている……という可愛い(自画自賛)テイストなイラストがメインな年賀状です。


最初は時事ネタを毎年取り入れているので元号発表のシーンのパロディっぽくしてみたり迷走していたのですが、
「Satoさん、ジョ●ョって知ってますか?
ジョ●ョ6部の主人公がスタ●ド攻撃のせいで小さくなってネズミの毛皮を着ぐるみのように被るシーンがあるんですよ……。
あれみたいにこまちゃんがネズミの着ぐるみを着ていたらすごく可愛いと思うんです」
というアドバイスを受けて、ファンシーグッズを出しているメーカーの年賀状を色々参考にしつつシンプルにネズミ着ぐるみ可愛いですよという直球なイラストを描きました。
(ここだけの話ですが、ジョ●ョは3部までしか読んでいないので6部の主人公がネズミの毛皮を被るシーンはいまだに見ていません

年賀状用に描いたイラストに辿り着くまでこんな感じのラフを描いたりしていました↓


メインのイラスト以外にも、ネズミのイラストに合わせてブラシツールで描いた四角を散らしてみたり手書きっぽい雰囲気のフォントを使ってみたりしてみました。
Happy New Year!の部分のフォントはフリーフォントのしろくまフォントを使用しています。
手書き風なのに幼くなりすぎないオシャレなフォントなので大好きです。


今年は来年の年賀状はどうしようかな?と考えたり普段描かないのでイラストを練習したり一年を過ごそうと思います!ガンバルゾ💪(´・_・`💪)

2019年12月26日木曜日

C#でExecuteScalarメソッドを使うときの注意点。

12月 26, 2019

オフィス狛 技術部のHammarです。

C#のSQL実行メソッドに「ExecuteScalar」というのがあります。
これはクエリを実行し、そのクエリが返す結果セットの最初の行にある最初の列を返してくれます。
このメソッドを使って、ちょっとハマってしまったことについて書こうと思います。

例えば、テーブルの主キーとなるidが自動インクリメントになっているテーブルに、INSERTすると同時に登録したidを取得したい時などがあると思います。
今回試した環境はSQLServerだったので、INSERT実行時に
SELECT SCOPE_IDENTITY();
を使えばそれが可能なのですが、INSERT文が別テーブルからの「INSERT SELECT」の場合、SELECTの結果が条件によっては取得できない場合があります。
そのときの結果の挙動で自分が想定した結果ではなかったので、ちょっと戸惑いました。

まず、上記の「INSERT SELECT」と「SELECT SCOPE_IDENTITY」を使って「ExecuteScalar」を実行するサンプルコードとして

SqlConnection Connection = new SqlConnection();
SqlCommand cmd = new SqlCommand("INSERT INTO users(...) SELECT ...; SELECT SCOPE_IDENTITY();", Connection);
decimal id = (decimal)cmd.ExecuteScalar();

上記は、別テーブルから取得した情報を登録し、登録した時のidを取得するというような処理になります。

で、基本SELECTでデータが取得できる前提であれば問題ないんですが、このSELECTでデータが取得できない場合、
「指定されたキャストは有効ではありません。」
というエラーが発生してしまいます。

恐らくこのエラーは、「SELECTでデータ取得できない」→「INSERTするデータなし」→「SELECT SCOPE_IDENTITYでid取得できない」
ということなので、返り値としてはNullが返ってくると思います。
なので、結果decimalにキャストできなくてエラー発生していると思ったので、以下のように、Nullが入ってくることを許容すればいいと思い、返り値にNullable型を使って

SqlConnection Connection = new SqlConnection();
SqlCommand cmd = new SqlCommand("INSERT INTO users(...) SELECT ...; SELECT SCOPE_IDENTITY();", Connection);
decimal? id = (decimal?)cmd.ExecuteScalar();
if (id.HasValue)
{
    string insertId = id.ToString();
}

という感じにしました。
返り値の型decimalに?を付けてNull許容(Nullable)とすれば、仮にNullが返っても問題ないのかなと。
その後で、Nullの場合の判定を加えてやれば処理的にうまくいくかなと思いましたが、やはり同じく「指定されたキャストは有効ではありません。」のエラーが発生しました。

よくよく考えてみると、そもそもここでdecimal型にキャストして、基本的に値が返ってくる前提のような作りがよくないのと、SELECT時データが取得できない場合は、返り値が「Null」ではなくて、「DBNull」という別物だということを知りました。

ということで、返り値の型をobject型に変更し、下記のように変更しました。

SqlConnection Connection = new SqlConnection();
SqlCommand cmd = new SqlCommand("INSERT INTO users(...) SELECT ...; SELECT SCOPE_IDENTITY();", Connection);
object id = cmd.ExecuteScalar();
if (!DBNull.Value.Equals(id))
{
    string insertId = id.ToString();
}

これでデータが取得できた時だけ、登録時のidを取得できるようになりました。

もしかしたらこういったケースはあまりないかもしれませんが、「ExecuteScalar」メソッドを使って「INSERT SELECT」するときには、ご参考にしてみてください。

2019年12月18日水曜日

zshでプロンプトをコマンドの実行結果によって変更する方法。

12月 18, 2019

オフィス狛 技術部のmmm(むー)です。

TL; DR

zsh(oh-my-zsh)をインストールして、下記のようにプロンプト(➜ 😶/ ➜ 🙃🙃🙃)をコマンドの実行結果によって変更する設定を説明します。さよなら、bash。
※特に意味はありませんが、あえて良い点をあげるとローカルとリモートの区別が簡単につきます。
【環境】
MacOS Mojava
バージョン 10.14.5

【ターミナルアプリ】
iTerm2
https://www.iterm2.com/
※これは好みの問題なので、Macのデフォルトのターミナルでも問題ありません。

1. Homebrewのインストール

Homebrewをインストールします。
(HomebrewとはMac専用のパッケージマネージャーで、インストールしておくと便利です。)
➜ 😶/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

インストールできていることの確認
➜ 😶brew -v
Homebrew 2.2.1
Homebrew/homebrew-core (git revision 0105; last commit 2019-12-10)

参考)Homebrew
https://brew.sh/index_ja

2.zshのインストール

zshをインストールします。
➜ 😶brew install zsh zsh-completions

インストールできていることの確認
➜ 😶zsh --version
zsh --version
zsh 5.7.1 (x86_64-apple-darwin18.2.0)

3.oh-my-zshのインストール

oh-my-zshとは、zshのフレームワークです。
➜ 😶sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

参考)of-my-zsh
https://github.com/ohmyzsh/ohmyzsh

oh-my-zshにはたくさんのカラーテーマが用意されています。
テーマ等修正したい場合、~/.zshrcを修正すると適用されます。
robbyrussellはデフォルトのテーマで私はデフォルトのままにしています。
➜ 😶vi ~/.zshrc

~省略~
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
ZSH_THEME="robbyrussell" #ここを変更する
~省略~

参考)oh-my-zshカラーテーマ一覧
https://github.com/ohmyzsh/ohmyzsh/wiki/Themes

4.プロンプトの修正

現在使用しているzshのテーマを確認。
先ほど変更したものは変更したものに、変更していない人はrobbyrussellが表示されます。
➜ 😶echo $ZSH_THEME
 robbyrussell

自分が使用しているカラーテーマの対象のファイルを修正します。
※変更後は適用を反映するため、ターミナルを起動しなおしましょう。
➜ 😶vi ~/.oh-my-zsh/themes/robbyrussell.zsh-theme

 PROMPT="%(?:%{$fg_bold[green]%}➜ 😶:%{$fg_bold[red]%}➜ 🙃🙃🙃 )"  #ここが基本のプロンプト
 PROMPT+=' %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)'
 
 ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
 ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
 ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗"
 ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"

🍭~/.oh-my-zsh/themes/robbyrussell.zsh-themeファイルの設定の補足
※ここは読まなくても、設定は完了しています。

%(?:%{$fg_bold[green]%}➜ 😶:%{$fg_bold[red]%}➜ 🙃🙃🙃 )」の部分ですが
 %(?:true:false)なので、下記のようになります。

成功した場合「%{$fg_bold[green]%}➜ 😶
echo $?の結果が0 (直前の処理が成功)

失敗した場合「%{$fg_bold[red]%}➜ 🙃🙃🙃
false:echo $?の結果が0以外 (直前の処理が失敗)

$?で終了ステータス(直前のコマンド実行結果)を取得することができます。
0が成功。1は失敗の意味です。
(コマンドによっては、上記ルールに適していないものもあります。例えば、diffは差分がない場合0、差分が有れば1、失敗すると2です...)
# 直前の処理が成功
➜ 😶ls test.txt
test.txt
➜ 😶echo $?
0

# 直前の処理が失敗
➜ 😶ls a
ls: a: No such file or directory
➜ 🙃🙃🙃echo $?
1

残りの箇所ですが、文字の色を変更しています。
 %{$fg_bold[green]%}:文字の色を緑に
 %{$fg_bold[red]%}:文字の色を赤に

最後の補足が長くなってしまいましたが、以上となります。
オリジナルのプロンプトをぜひ作成してみてください。

2019年12月16日月曜日

Angular で作られたプロジェクトをPWAにしてみよう。(後編)正しくPWA化されているか確認する

12月 16, 2019

オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

前編(Angular 7 から 8 へのアップデート)中編(PWA化の実施)の続きです。
今回は、PWA化したプロジェクトが、正しくPWA化されているか確認しましょう。

(1)前提条件

・ビルドはproduction設定の「ng build --prod」で行う。
・サイトへの接続はHTTPSであること。

最初のproduction設定については、後でいくらでも変更は出来るのですが、デフォルトだと「serviceWorker」がproductionの場合のみ有効になるので必須となります。
2番目の「HTTPS」ですが、チェックツールの「Chrome デベロッパーツールのAudits」がHTTPS接続でないと、そもそも使えないので、これも致し方ないです。

(2)PWAかどうかチェックする

さて、早速チェックしていきます。Chromeで対象のサイトを表示し、デベロッパーツールを起動します。(右クリックから「検証」を選ぶと早いです。)
デベロッパーツールが起動したら、Auditsと言うタブがあるので、そのタブを選択します。


続いて、Auditsの設定を行います。


今回は、PWAのチェックだけ実施したいので、他のチェックは外します。

それでは実行してみましょう!


???
チェック出来てない・・・。
あ、なるほど。
このプロジェクトは、AWSのEC2に配置し、ALB(ロードバランサ)でバランシングしているのですが、
ロードバランサ側でhttp接続は処理しないようになっていました。
と言う事で、設定を変更し、HTTPはHTTPSにリダイレクトするようにしました。

気を取り直して、もう一度、チェック実行してみます。


とりあえず、「?」マークはなくなりましたね。
後は、
Does not have a <meta name="viewport"> tag with width or initial-scaleNo viewport meta tag found
Add a viewport meta tag to optimize your app for mobile screens.
ですね。
こちらは、エラー内容の通り、metaタグ(viewport)が無い事で発生しています。

そして、もう一つ
Does not provide a valid apple-touch-icon
For ideal appearance on iOS when users add to the home screen, define an apple-touch-icon. It must point to a non-transparent 192px (or 180px) square PNG.
こちらはiPhone・iPadのホーム画面用アイコンapple-touch-iconnの指定がありませんよ、と言う事で発生しています。

いずれも、「index.html」に記述する事で解決しそうです。
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="manifest" href="manifest.webmanifest">
  <meta name="theme-color" content="#1976d2">
  <meta name=”viewport” content=”width=device-width,initial-scale=1.0,minimum-scale=1.0″><!-- ←追加 -->
  <link rel="apple-touch-icon" href="assets/icons/icon-192x192.png"><!-- ←追加 -->

Angular CLIで、ここまでやってくれると嬉しいですけどね。

という事で、再度、チェック実行してみます。


無事にPWAにチェックマーク✅が付きました!

と言う事で、三回に渡って、Angular で作られたプロジェクトをPWAにしてみました。
途中でAngularアップデートをやっていたので、時間が掛かってしまいましたが、
PWA化自体は非常にお手軽に出来たので、かなり良い感じだと思います。

では、より良いAngularライフを!


Angular で作られたプロジェクトをPWAにしてみよう。(中編)PWA化の実施

12月 16, 2019

オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

前編(Angular 7 から 8 へのアップデート)の続きです。
今回は、実際にPWA化を行って行きます。
既にPWA化作業が終わっていて、正しくPWA化されているかを確認したい方は、
後編(正しくPWA化されているか確認する)をご覧ください。

では、早速PWA化を行って行きましょう。

(1)PWAパッケージの追加

前編で、Angular8にアップデートしたプロジェクトを使用します。
そのプロジェクトにPWAパッケージを追加します。

追加のコマンドは「ng add @angular/pwa」です。
$ng add @angular/pwa
+ @angular/pwa@0.803.5
added 5 packages from 2 contributors and audited 22482 packages in 22.952s
Installed packages for tooling via npm.
Could not read file (/src/@app/app.module.ts).
エラーになりました。「app.module.ts」が読めないと言っていますね・・・。

「app.module.ts」をimportしているのは、確か「main.ts」なので、そちらを見てみましょう。
import { AppModule } from '@app/app.module';
「@app」になっているのが駄目なのでしょうね。
(でも、元々これはAngular CLIが勝手に作ったような・・・)

とりあえず、
import { AppModule } from './app/app.module';
に修正しました。

では、再度、「ng add @angular/pwa」を実行します。
$ng add @angular/pwa
CREATE ngsw-config.json (620 bytes)
CREATE src/manifest.webmanifest (1119 bytes)
CREATE src/assets/icons/icon-128x128.png (1253 bytes)
CREATE src/assets/icons/icon-144x144.png (1394 bytes)
CREATE src/assets/icons/icon-152x152.png (1427 bytes)
CREATE src/assets/icons/icon-192x192.png (1790 bytes)
CREATE src/assets/icons/icon-384x384.png (3557 bytes)
CREATE src/assets/icons/icon-512x512.png (5008 bytes)
CREATE src/assets/icons/icon-72x72.png (792 bytes)
CREATE src/assets/icons/icon-96x96.png (958 bytes)
UPDATE angular.json (5936 bytes)
UPDATE package.json (2638 bytes)
UPDATE src/app/app.module.ts (1597 bytes)
UPDATE src/index.html (542 bytes)
無事に完了したようですね。(*1)
*1)警告が出る場合、「npm audit fix」しておきましょう

では、自動作成・更新されたファイルについて、エラーが出ていないか確認しておきましょう。

私が試したプロジェクトだと、「app.module.ts」がエラーになっていました。
import { environment } from '@environment/environment'; // ←元々

import { ServiceWorkerModule } from '@angular/service-worker'; // ←追加された行
import { environment } from '../environments/environment'; // ←追加された行

元々の表記が「@environment」だったので、別パスと判断して、新たな「environment」を追加したのですかね。
(でも、元々これはAngular CLIが勝手に作ったような・・・(2回目))

まあ、ここは、追加された行を残して、元々の行を削除しようと思います。

(2)App Shellの導入

続いて、App Shellを導入します。
App Shellは、簡単言うと、画面のキャッシュを行う機構の一つです。
詳細は、この辺を参照してください。

Angularに導入するには、以下のコマンドを実行します。
ng generate app-shell --client-project my-app --universal-project server-app
・my-app はクライアントアプリケーションの名前です。
・server-app はユニバーサル (またはサーバー) アプリケーションの名前です。

と言う事で、今回は、以下のコマンドを実行します。
ng generate app-shell --client-project koma-system-pwa --universal-project koma-system-pwa
エラーになりました。
Could not find /src/app/@app/core/containers/app/app.component.ts.
先程までと同じ、「@app」問題ですね。
(でも、元々これはAngular CLIが勝手に作ったような・・・(3回目))

先程と同じように、
import { AppComponent } from '@app/core/containers/app/app.component';
上記を下記のように書き換えます。
import { AppComponent } from './core/containers/app/app.component';
弊社のプロジェクトの場合、ちょっと特殊な場所に「app.component」を配置しているので、それぞれ環境にあったパスに修正してください。

それでは、再度、実行してみます。
$ng generate app-shell --client-project koma-system-pwa --universal-project koma-system-pwa
CREATE src/main.server.ts (220 bytes)
CREATE src/app/app.server.module.ts (590 bytes)
CREATE src/tsconfig.server.json (270 bytes)
CREATE src/app/app-shell/app-shell.component.css (0 bytes)
CREATE src/app/app-shell/app-shell.component.html (24 bytes)
CREATE src/app/app-shell/app-shell.component.spec.ts (643 bytes)
CREATE src/app/app-shell/app-shell.component.ts (280 bytes)
UPDATE package.json (2679 bytes)
UPDATE angular.json (7231 bytes)
UPDATE src/main.ts (469 bytes)
UPDATE src/app/app.module.ts (1650 bytes)
これでPWA化は完了となります。簡単ですね。

後は、自動生成された画像(src/assets/icons)をそれぞれのプロジェクト用で置き換えてください。

では、次回で最後、Chrome デベロッパーツールのAuditsで、正しくPWA化されている事を確認するところまでやって行きます

次回:Angular で作られたプロジェクトをPWAにしてみよう。(後編)正しくPWA化されているか確認する