OmniAICreator/Qiita-1.07M huggingface dataset:
Spring Bootで「HelloWorld」まで

自分の勉強用。

#SpringBootってなんだろう
- 各種ライブラリやミドルウェア組み合わせの共通化・最適化の道具なイメージ
 - SpringFrameworkの設定ファイルの複雑さをできる限り排除、少しの設定でアプリの開発・起動実行できるようにするよ
- SpringFramworkとイコールではない
 - SpringFrameworkはSpringプロジェクトのベースとなる（[DI:依存性の注入]とか[AOP:アスペクト指向プログラミング]とか）
 - SpringFramworkはニーズに応じてプロジェクトを増やしてきた(SpringBatchとかSpringDataとか)
 - 「Spring」=「SpringFramework」として使う方が多いと思う
- SpringFrameworkは基本XMLで設定を定義し外部ファイル化
 - 最近はXMLではなくJavaソース本体に設定を記載するスタイルの方が主流？
 - 大きなサービスになると設定ファイルが肥大化してなかなか大変みたい
- Webコンテナをjarに含めることができる
 - Tomcatを内包した形で提供できるみたい
 - warファイルをとしてエクスポートし通常のサーバーにのせることも可能
- SpringBootでは目的のシステムを実現する設定やライブラリの依存関係を「定義セット(Starter)」として管理
 - これまで通りMavenやGradleを使うけど、自分で設定しないで済むよう設定ファイルを用意してくれているイメージ
 - 公式に多くのStarterがあり。目的に応じてカスタマイズしていけばOK
- AutoConfigureの仕組みで、Bean定義を自動で定義してくれるらしい
- アノテーションで実現できること多々
 - [?]純粋なSpringでも使えるのかな→使えそう
 - AutoConfigureを実現する際は
   「 @AutoConfigureAfter、@AutoConfigureBefore、@AutoConfigureOrder」など使うみたい

# 開発環境について
- STS(Spring Tool Suite)を使用するのが一般的。簡単なのかな？
- STSの日本語化はEclipseを日本語化するPleiades日本語化プラグインを利用できる
- Eclipseにプラグインを入れて開発するのもよさそう！

# ビルドツール
- Mavenを使おうと思います
- AntやGradleと同じようなツール
 - [?]"SpringBootならMavenでいい"って見かけるけど、理由がわかってないよ
- C言語をビルドする際のmakeみたいな
- Mabenのビルド設定は「pom.xml」に

# やっとモノづくりをはじめるよ
1. 前提環境
Windows 10 64bit

2. Pleiades All in One ダウンロード
http://mergedoc.osdn.jp/
新しめのやつで

3. 環境変数設定
[参考]https://www.javadrive.jp/start/install/index4.html
今回はPleiadesのJava8を使うよ
追記）深く考えず環境変数設定までしたけど、今回の内容ならやらなくてよかったね

4. Eclipseに必要なプラグインを入れる
STSを使うなら不要かもしれないけど、Eclipseベースで作るのでプラグインを入れるよ
[ヘルプ]＞[Eclipseマーケットプレース]で「STS」を検索
![EclipseでSTS.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/ecf9b9fc-40f9-c02c-466b-8c235e6da1ae.png)

5. プロジェクト作成
[ファイル]＞[新規]＞[その他]＞Spring Starter Project
サービスURL「https://start.spring.io」
名前「springbootdemo」
型「Maven」
パッケージング「jar」
Javaバージョン「8」
言語「Java」
グループ「com.bootsample」
成果物「springbootdemo」
バージョン「0.0.1-SNAPSHOT」←デフォルトの
説明：「SpringBoot Sample Project」
パッケージ「com.springbootdemo」
↓[次へ]を押したあと
![新規Springプロジェクト依存関係.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/50d13267-91f1-61b7-b6e8-9b61efd74110.png)

6. ビルドの設定的な
プロジェクト上で右クリックして以下の操作をしてください
　・Maven→プロジェクトの更新→OK
　・実行→Maven install
　（インストールされていく...

7. コントローラーの作成
パッケージ「com.springbootdemo」を右クリック
[新規]＞[クラス]
で、新しいクラスを作成
![コントローラーの作成.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/48f0672f-bef4-ff3e-885f-58c232d0a57c.png)
![とりあえずコントローラー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/c77f8278-ed6c-38ad-19a5-d2a48fa0cd79.png)

8. 起動
プロジェクトを右クリック
[実行]＞[SpringBootApp]をクリック
アプリケーションが起動
http://localhost:8080/
へアクセスすると、以下が表示されるはず
![ブラウザの表示.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/e3077948-801a-4e1c-ddf4-9ea5bac9b339.png)


とりあえずここまで。

※日本語化前と後でメモしたので、メニュー名がその時々によっていちょっと違うかも
rsyncで世代管理バックアップ(--link-destオプションを使用)

自分用メモ。
--link-destオプションを使って複数世代バックアップの容量を削減する。

```bash:rsync_backup.sh

#!/bin/bash

### ヘルプ表示 ###
if [ "x$1" = "x--help" -o "x$1" = "x-h" -o "x$1" = "x/?" ]; then
   echo '[usage]:$ rsync_backup.sh [source directory] [destination directory]'
   echo '[note]:引数に指定するディレクトリは絶対パスで指定し、末尾の"/"まで入力してください.'
   exit 0
fi

### 引数のチェック (第一引数:バックアップ元ディレクトリ 第二引数:バックアップ先ディレクトリ) ###
if [ "x$1" = "x" -o "x$2" = "x" ]; then
   echo "[error]:引数を指定してください."
   echo "[usage]:nfsbackup.sh [バックアップ元ディレクトリ] [バックアップ先ディレクトリ]"
   echo "[error]:処理を終了します."
   exit 1
fi

### 引数が絶対パスで指定されていか確認(先頭に"/"が指定されているかチェック) ###
PATH1=$(echo $1 | cut -c 1)
PATH2=$(echo $2 | cut -c 1)
if [ ! "x${PATH1}" = "x/" -o ! "x${PATH2}" = "x/" ]; then
   echo "[error]:引数に指定するディレクトリは絶対パスで指定してください."
   echo "[error]:処理を終了します."
   exit 1
fi

### 引数からバックアップ元、先のディレクトリを変数に格納 ###
# 引数の最後が"/"で指定されているかチェックし、されていない場合は"/"を追加する
SRCCHK=$(echo $1 | rev | cut -c 1)
DSTCHK=$(echo $2 | rev | cut -c 1)
if [ "x${SRCCHK}" = "x/" ]; then
   BKSRC="$1"
else
   BKSRC="$1/"
fi
if [ "x${DSTCHK}" = "x/" ]; then
   DST="$2"
else
   DST="$2/"
fi

### バックアップ元ディレクトリが存在するかチェックする ###
if [ ! -d ${BKSRC} ]; then
   echo "[error]:指定したバックアップ元ディレクトリが存在しません."
   echo "[error]:処理を終了します."
   exit 1
fi

# バックアップ先ディレクトリを定義 #
BKDST="${DST}$(hostname)/$(date +%Y%m%d)/"
# バックアップログ出力先を定義 #
BKLOG="${DST}$(hostname)/$(date +%Y%m%d)_backup.log"
# 前日のバックアップ先ディレクトリ #
BKDSTTDB="${DST}$(hostname)/$(date -d '1day ago' +%Y%m%d)/"

### バックアップ先ディレクトリ作成 ###
mkdir -p ${BKDST}

### rsync実行 ###
echo "### Backup start at [ $(date -R) ] ###" >> ${BKLOG}
if [ ! -d ${BKDSTTDB} ]; then
   rsync -av ${BKSRC} ${BKDST} >> ${BKLOG} 2>&1
else
   rsync -av --link-dest=${BKDSTTDB} ${BKSRC} ${BKDST} >> ${BKLOG} 2>&1
fi
echo "### Backup end at [ $(date -R) ] ###" >> ${BKLOG}
```
【未経験90日間開発】困窮するセブ島留学生のためにWEBサービスをつくった話

「財布の中、レシートとKTV（キャバクラ）の名刺しか入ってねえ」。こちらセブ島に留学していた頃、毎週金曜日夜になると毎回私が直面していた事態です。先進国の半分以下と聞いて意気揚々と過ごしていたフィリピンでの生活。気づけば日本食レストランに入り浸り、一杯1000円を超えるフィリピン豚骨ラーメンに慣れ、一回2000円のマッサージに週5回で通い、基本的に交通手段はすべてタクシー。そんな生活を続けていけば財布はおろかATMの中もみるみる残高が減っていく、楽しく哀しきセブ島留学。困窮する同士に本記事を捧げます。


##「セブ島留学生のための節約診断サイト」とは
セブ島に英語（やプログラミング）留学をしている人が生活費を診断するサイトです。ユーザーは「年齢」や「交通手段」、「食事のレベル」など16個の質問に答えると、節約レベルが「超人」〜「素人」まで5段階のレベルで診断結果が表示されます。診断結果はグラフで表示され、これまで回答した人たちのレベルごとの配分も確認することができます。

<img width="1073" alt="スクリーンショット 2019-07-18 17.17.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351773/52839f28-7bdf-bc52-7199-926305a2a7dd.png">
[「セブ島留学生のための節約診断サイト」（リンクに飛びます）](https://cebucost.herokuapp.com/)


#なぜつくったのか
近ごろ、フィリピンのセブ島に留学に訪れている人が多いみたいです。私もそのひとり。一説によると、日本人学生の留学先としてはオーストラリアを抜き、アメリカに次ぐ第2位になったとか……（物価が安くて、かつアジアで唯一英語が公用語であることが理由のようです※シンガポールのぞく）。

で、そんなセブ島に私自身留学したときの悩みが「これ……意外とお金かかるぞ！」というもので。物価が安いとはいえ、暴飲暴食したりナイトスポットで遊びまくっていたらやはり財布が爆発してしまう。そんな私、そして今後留学をするであろう同胞にとって、コスト管理の一助となればと思い、制作しました。

<img width="989" alt="スクリーンショット 2019-07-18 17.30.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351773/6c96ac2b-a228-b22d-a79e-1e52c4046a63.png">

#このサービスでできること
###一般ユーザー
上記に記載している通り、16個の質問に答えることで、自身のレベルを確認することができます。診断ページでは回答に基づいて、食費、交通費、生活費、交際費、衣服・美容費、趣味・娯楽費の7項目の分布を円グラフで確認することができました。

###運営者
ページ上部のログインのリンクからは運営者ページに遷移することができます（現状では運営者である私が設定しているメールアドレスとパスワードからのみ遷移可能）。運営者ページでは回答したユーザーの年齢層、男女比の分布を確認できます。また、管理者画面から診断する問題や問題に紐づく数値を編集することもできます。

<img width="715" alt="スクリーンショット 2019-07-22 14.08.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351773/7f2d89dc-bfe5-bf8d-c5fa-cd758e104c32.png">

#使ったもの
###Bootstrap
テンプレートを導入するはずでしたが、もともと入っているリッチな機能が自由に動かせない（力量不足……！）のと、シンプルなデザインにしたかったため、テンプレートは使わずに実装することにしました。

###Chart.js
診断結果にはJSのチャートライブラリであるChart.jsを使用しました。円グラフと棒グラフをそれぞれぬるっと表示させることにこだわりました。

###Google Fonts
Noto+Sans+JPを使用しています。導入はチュートリアル通りにやったため、比較的容易でした。

###Cacoo
ワイヤーフレームを制作するにあたり、オンライン作図ツールを使用しました。無料で利用できるのは機能的に制約がありますが、今回のサービスのレベルであれば、問題ありませんでした。

###Sourcetree
GitHubの管理をするため、使用しました。

#参考
[「育休診断シュミレーター」](https://13imi.me/ikusim/)
Webディレクター・エンジニアのイミーさんと、奥さまがデザインをつとめられたサイト。ユーザーが選択しやすい選択肢の設定とわかりやすい結果のデザイン。テキストも優しさにあふれてます。

[「Payme」](https://payme.tokyo/)
ポップな色使いとグリグリ動くアニメーションを参考にさせていただきました。

[「SANKO!WEBサイトの参考集」](https://sankoudesign.com/category/background-move/)
もともと、背景が動くデザインにしたかったこともあり、リファレンスが集まっている本サイトは毎日のように見て、「あ〜こんなサイト作りたい…………」と憧れておりました。





#もっとこうしたい！こと
###サーバーを移転したい
Herokuの無料プランでデプロイしているのどうしても重い……。サーバーについてより学習して、AWSなど普及しているサービスにを使用してみたいです。

###運用についてもっと考えたい
リリースした当初は周囲の友人がおもしろがって使ってくれたのですが、なかなかそこからの実際に多くの人に使ってもらうのは難しかったのです。発信力をつけねば、引いては開発段階から運用について考えておくべきだったとやや反省しております。この記事をきっかけに新たなセブ島留学生の方の目に留まることになれば……！


今回の開発は、私にとってまったくもって初めての体験で困難と挫折の連続でした。そんなときにQiitaの初心者開発投稿を見て勇気をもらったので、今回私も筆をとりました。ご覧いただき、ありがとうございました。
Java、SpringのRESTControllerで画像を表示したい！

# Javaで画像を表示したい！
YuruFuwaFoxです。Javaを勉強しています。
今回はSpringのRESTControllerで画像を表示するにはどうすればいいんだろう？ということで色々調べながら実装したので、その方法をメモがてら共有したいと思います！

###注釈
この記事はJavaのかなりの初心者に向けた内容です。
我こそはつよつよエンジニア、という人向けではないのでそこについてはよろしくお願いします。
それでも読んでくださるならありがとうございます！
（間違っているところの指摘なども大歓迎です！）

##RESTControllerで画像を表示するって？？？
まず、RESTControllerとはなんぞや？からを説明していきます。
RESTControllerというのは返り値にJSONやxmlを返す、いわゆるAPIのためのものです。
普通のControllerであれば基本的にViewを返すところを、単純にデータのみを渡すという感じですね！
つまりViewを返すのであれば、単純にViewに画像を渡してどうにか表示できそうですが、JSONやxmlを返すRESTControllerではどうすればいいんでしょうか？

##バイナリ形式でデータを渡す
画像はバイナリデータで渡すことで表示できます。
そこで、画像をバイナリ形式にして渡すことで画像を表示することにしました。

##HttpEntityにデータを渡して画像を表示させる
画像の表示はブラウザで表示させることにします。
そこで、HttpEntityを利用してレスポンスボディーに画像を入れてあげることにします。

```Java:showImgService.java
public HttpEntity<[byte]> showImg(String image) throws IOException{
    //画像の取得
    Resource resource = resourceLoader.getResource("File:" + staticPath + imgPath);
    //画像形式取得のため
    String format;
    //バイトデータ格納のため
    ByteArrayOutputStream bout;
    //画像をバイトデータに
    try (InputStream img = resource.getInputStream()) {
        format = URLConnection.guessContentTypeFromStream(img);

        bout = new ByteArrayOutputStream();
        int c;
        while ((c = img.read()) != -1) {
            bout.write(c);
        }
    }
    //バイトデータを取り出す
    byte[] bytes = bout.toByteArray();

    //ヘッダーを作成
    HttpHeaders headers = new HttpHeaders();
    //ヘッダーにコンテンツの情報を収納
    headers.setContentType(MediaType.valueOf(format));
    headers.setContentLength(bytes.length);
    //HttpEntityにバイトデータとヘッダーを渡して返す
    return new HttpEntity<>(bytes, headers);
}
```

###終わりに
本当にメモ程度になったため、雑な感じです。
画像のバイトデータ変換も、IOUtilsを利用すれば実は一行でできますが、今回は忘れていたため、こんな形になりました。
誰かの役に立てれば幸いです！
Mathematicaで変数名を文字列として利用する

#目的
Mathematica で変数名そのものを文字列として利用したいときがある。例えばグラフをファイルに出力するときに、グラフが入っている変数の変数名をそのままファイル名にしたいときなど。

#方法
`HoldForm`関数や`ReleaseHold`関数を使う。ここで、`HoldForm`関数は与えられた引数を未評価のまま出力する関数、`ReleaseHold`関数は`Hold`関数の出力を評価する関数である。

#例
グラフのプロットを変数に納めて、その変数名のファイルにグラフを出力してみよう。

```
plt = Plot[ x, {x, -1, 1} ];
Export[ ToString[ #1 ] <> ".png", ReleaseHold[ #1 ] ] & [ HoldForm[ plt ] ];
```

`Export`関数の第1引数は変数名`plt`に拡張子として`.png`をつけた文字列になっていて、第2引数は未評価のまま渡された`HoldForm[ plt ]`を評価したもの、つまりグラフそのものとなっている。注意点は、純関数の引数に`plt`を与えて`Export`関数の第1引数を`ToString[ HoldForm[ #1 ] ]`として__しまわないことだ__。こうしてしまうとうまくいかないのだが、理由は`plt`が評価された後に`HoldForm`関数に渡されることだと考えられる。
SpreadSheetAPIでセルの背景に色を付ける

```php5
    /**
     * セルに色付け（背景色を赤にする）
     * @param $rowNum
     */
    private function setColorCellBackground($rowNum)
    {
        // 新規で作成したシートのIDを首取得
        $result = $this->service->spreadsheets->get($this->spreadsheetId);
        $newSheetId = $result->sheets[0]->getProperties()->sheetId;
        // 背景色を塗りつぶす行を取得
        $gridRangeRequest = new Google_Service_Sheets_GridRange();
        $gridRangeRequest->setSheetId($newSheetId);
        $gridRangeRequest->setStartRowIndex($rowNum-1);
        $gridRangeRequest->setEndRowIndex($rowNum);
        // 背景色を作成（RGBを作成）
        $sheetsColorRequest = new \Google_Service_Sheets_Color();
        $sheetsColorRequest->setBlue(0.7647059);
        $sheetsColorRequest->setRed(0.95686275);
        $sheetsColorRequest->setGreen(0.78039217);

        // セルフォーマットを生成
        $cellFormat = new \Google_Service_Sheets_CellFormat();
        $cellFormat->setBackgroundColor($sheetsColorRequest);
        $cellDataRequest = new \Google_Service_Sheets_CellData();
        $cellDataRequest->setUserEnteredFormat($cellFormat);

        $repeatCellRequest = new \Google_Service_Sheets_RepeatCellRequest();
        $repeatCellRequest->setCell($cellDataRequest);
        $repeatCellRequest->setRange($gridRangeRequest);
        $repeatCellRequest->setFields("userEnteredFormat(backgroundColor)");

        $requestBody = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
        $requestBody->setRequests(["repeatCell" => $repeatCellRequest]);
        $this->service->spreadsheets->batchUpdate($this->spreadsheetId, $requestBody);
    }
```
#PowerApps のJSON関数を利用した写真の一括登録

# はじめに
PowerAppsではコレクションやテーブルからJSONデータを、画像、音声等からdatauriを生成するJSON関数が用意されています。
本投稿では、このJSON関数を利用して、PowerAppsのカメラで撮影した画像をFlowを経由してSharePointドキュメントライブラリに（複数画像を）一括登録する方法を記載します。
なお、JSON関数については[こちら](https://powerapps.microsoft.com/en-us/blog/json-for-canvas-apps/)をごらんください。
※モバイル対応しています。

PowerApps側は簡単に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/66e4a022-a5ba-d325-1580-4c8b6d9bb75a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/aa8fd79c-e32a-6043-045e-7da542017af4.png)


##レシピ
###PowerAppsサイド
カメラコントロール・・・1個
ギャラリー・・・1個（ためる写真を表示する用）
ボタン・・・2個 （CollectionをJSONに変換する用、Flow実行用）
###Flowサイド
Parse JSON・・・1個（PowerAppsから受け取ったデータをParse）
Create file・・・1個（SharePointドキュメントライブラリにファイル作成）


# カメラ画像をdatauriに変換する
まずカメラ画像をdatauriに変換します。カメラコントロールのOnSelectに以下の関数を設定します。

```Camera.OnSelect
UpdateContext(
    {
        photouri: 
            JSON(Camera1.Photo,JSONFormat.IncludeBinaryData) //ここでdatauriを作成
    }
);
```
ポイントは**JSON(Camera1.Photo, JSONFormat.IncludeBinaryData)**です。これによってカメラ画像のdatauriがPowerAppsの変数にセットされます。

# Collectionにためる
複数の画像（のdatauri）をCollectionに格納するためにCamera.OnSelectを書き換えます。

```Camera.OnSelect
UpdateContext(
    {
        photouri: JSON(Camera1.Photo,JSONFormat.IncludeBinaryData)
    }
);
Collect(
    CamPhoto,
    {
        ID: idnum,
        data: Substitute(
            photouri,
            """", //ダブルクォーテーションを消す
            ""
        )
    }
);
UpdateContext({idnum: idnum + 1})
```
Collectionに入れる際には、のちのちFlowで処理しやすいように、変数に入れたdatauriの前後についている"をはずしておきます。

# Flowに渡すためのJSONを作る
Flowに渡すためのJSONはたったの一行です。まさにこれがJSON関数のすごいところです。
```Set(postBody,JSON(CamPhoto));```
(SetかUpdateContextかはアプリに合わせてください)
これで撮りためた画像とIDを含むJSONが作成されました。


# Flow実行＋Flow側の処理
Flowの実行は単純に、postBodyをFlowの引数に渡すだけです。
```CreatePhotos.Run(postBody)```

Flow側では以下のように処理しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/a223b9e5-7b52-33c2-8a3d-272b8baeeff2.png)

ここではParseJSONのスキーマは

```
{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "ID": {
                "type": "integer"
            },
            "data": {
                "type": "string"
            }
        },
        "required": [
            "ID",
            "data"
        ]
    }
}
```
CreateCreate fileのFile Contentは
```dataUriToBinary(items('Apply_to_each')?['data'])```
としています。

# うごき
こんなかんじで動きます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">複数ファイルの一括登録 <a href="https://t.co/fhYokTpd1N">pic.twitter.com/fhYokTpd1N</a></p>&mdash; Hiro (@mofumofu_dance) <a href="https://twitter.com/mofumofu_dance/status/1153168013798993920?ref_src=twsrc%5Etfw">July 22, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

できたファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/f7fbb3fd-ca8a-4d1d-df2a-dcae8ba6430f.png)
自作フォントを作って流し込み作業を楽にする

#概要

イラレなどで流し込みの作業をするときに、ロゴを画像データとして作業するより、フォントとして作業した方が楽になる場合があるよという話。

##例えばこんなとき

- 何かしらのランクに対して、そのランクに応じたロゴを表示するとき

#自作フォントの作り方

下記サイトを参考にしました。
https://pc-pier.com/blog/2017/05/01/calligraphr/

他にも、自作フォントを作れるサイトはあるので、自分で探してみてもいいかもしれません。

##流れ

1. 専用の用紙に作ったフォント(ロゴ)を書き込んでアップロードする。
2. できたフォントファイルをインストールします。
3. 使えるようになります。(使えない場合は、再起動すると使えるようになるかもです。)

#特徴

##メリット

フォントとして扱えるので、流し込みのスプリクトを大きく変えなくても使えるようになる。

##デメリット

解像度が粗くなる。細かいロゴには向いていない。
GPSカー その15

#概要

GPSで自動走行する、コンテストがある。
実機を借りて、アプリから操作する部門が今年は無いらしい。
実機を作ってみた。
8の字運転してみた。

#動画

https://www.youtube.com/watch?v=vxWgF3fN2ZI

以上。
Azureアーキテクチャガイドまとめ 1 【はじめに】

## はじめに
[**Azureクラウドアプリケーションアーキテクチャガイド**](https://azure.microsoft.com/ja-jp/campaigns/cloud-application-architecture-guide/)。皆さんご存知でしょうか?

いわば、Azure版のWell-Architectedフレームワークです。非常に示唆に富む内容なので、分からない用語や概念を調べつつ、まとめようと思います。

本稿では、「はじめに」から、第一章「アーキテクトスタイルの選択」の導入部までを扱います。

#### 連載目次
Azureアーキテクチャガイドまとめ 1 【はじめに】 → 本記事
[Azureアーキテクチャガイドまとめ 2【N層】](https://qiita.com/Catetin0310/items/1ab0ae1130f767d770d3)
[Azureアーキテクチャガイドまとめ 3 【Webキューワーカー】](https://qiita.com/Catetin0310/items/fe0729549faeee843e8a)
[Azureアーキテクチャガイドまとめ 4 【マイクロサービス】](https://qiita.com/Catetin0310/items/06ab890a04baa161cac6)
[Azureアーキテクチャガイドまとめ 5 【CQRS】](https://qiita.com/Catetin0310/items/d0e8b489f6501e4da90b)
[Azureアーキテクチャガイドまとめ 6 【イベントドリブンアーキテクチャ】](https://qiita.com/Catetin0310/items/58f65242a7b71620825b)
[Azureアーキテクチャガイドまとめ 7 【ビッグデータアーキテクチャ】](https://qiita.com/Catetin0310/items/d515fc3fdff68b54f408)
[Azureアーキテクチャガイドまとめ 8 【ビッグコンピューティングアーキテクチャ】](https://qiita.com/Catetin0310/items/eebd754637dcda8ad14d)


## 従来のオンプレ環境と最新のクラウド環境

ご存知の通り、クラウドまわりの技術は急速に進化しています。マイクロサービス、コンテナ、AI/MLなどなど。

流れが早すぎて潮流が読めないなと感じることも多いと思います。以下はオンプレ環境と最新のクラウド環境の比較です。

![00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/5cd1ed01-0139-7ecf-1ff0-f264d98d92bf.jpeg)

本ガイドはその指針として活用できます。

> このガイドでは、スケーラブルで回復性と可用性が高いクラウド アプリケーションを設計するための**構造化されたアプローチ**について解説します。
(本文より抜粋)

詳しく見ていきます。

## ガイドの構成
ガイドは以下の5つステップで構成されています。

**1. アーキテクチャスタイルの選択
2. コンピューティングおよびデータストア用テクノロジの選択
3. Azureアプリケーションの設計 10の原則
4. ソフトウェア品質 5つの柱
5. クラウド設計パターンの適用**

ステップ1を行う前に、アーキテクチャの要件の明確化が必要になります。

というより、明確にしないと先に進めないようになっています。

設計後半で要件の見落しに気づいて大幅な手戻りが...なんて場面を回避できます。ついつい技術要素に目が向きがちなので、これはありがたい。

## アーキテクチャスタイルの選択
**要件の集合からテンプレートを選択**というイメージです。**合計7パターン**。

![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/ebdc4cb1-ae2c-224a-9979-2ad61fdd00c6.jpeg)

各スタイルの概要は下記の通り。

|アーキテクチャスタイル|ドメインの種類|依存関係の管理|
|:---|:---|:---|
|N 層|一般的ビジネスドメイン。更新は低頻度|サブネットに分割された水平方向の層|
|Webキューワーカー|比較的単純なドメインで、リソースを集中的に使用するタスクが存在する場合|フロントエンドとバックエンドのジョブを非同期メッセージングによって分離|
|マイクロサービス|複雑なドメイン。更新は高頻度|垂直方向 (機能的) に分解されたサービスがAPIを通じて相互に通信|
|CQRS|多くのユーザーが同じデータにアクセスする共同作業ドメイン。|読み取り/書き込みの分離。スキーマとスケールを個別に最適化。|
|イベントドリブンアーキテクチャ|IoTやリアルタイムのシステム|プロデューサー/コンシューマー。サブシステムごとに独立したビュー|
|ビッグデータ|バッチおよびリアルタイムのデータ分析。MLによる予測分析|大規模なデータセットを小さいチャンクに分割。ローカルデータセットを並列処理|
|ビッグコンピューティング|数値計算を集中的に使用するドメイン (シミュレーションなど)|数千個のコアにデータを割り当て|

用語は聞いたことあっても、具体的に何のことを言っているのかわからない、というのが正直な感想。

## 制約・課題・利点
それぞれのスタイルの説明に移る前に、なぜこの段階で型にはめる必要があるのかを整理します。

- スタイルの選択は、**制約**をもたらす
- 各スタイルは、固有の**課題**を持っている
- 制約を満たす場合、**利点**が生まれる

制約、課題、利点の概要と関係性を図示します。

![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/254513d3-b7c0-99bd-45c6-f8594793b86e.jpeg)

もっとも**利点マイナス課題**が大きくなるスタイルを見つけることで、最適なアーキテクチャに最短距離で近づくことが出来る、という格好です。

## おわりに
次回以降は各アーキテクチャスタイルについて解説します。お楽しみに！

## 参考リンク
[**Azureアーキテクチャセンター**](https://docs.microsoft.com/ja-jp/azure/architecture/)

[**Azureクラウドアプリケーションアーキテクチャガイド ダウンロードページ**](https://azure.microsoft.com/ja-jp/campaigns/cloud-application-architecture-guide/)
vim-deviconsで格好いいvimを作ろう。

<img width="1067" alt="スクリーンショット 2019-07-21 20.46.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93752/70b4fdf8-3626-93ca-c9fe-02932608f962.png">

## TL;DR

* 格好いいvim使いの決定版 __vim-devicons__ を紹介
* vim-deviconsの[スクリーンショット](https://github.com/ryanoasis/vim-devicons/wiki/screenshots)

## Nerd Fontをインストール

vim-deviconsはNerd Fontを使う。
使えるFontがないと文字化けになるので、先にインストールしなければならない。

Fontのインストール方法は多数存在する。
詳細が知りたい場合は、次のページを参照しよう。

* https://github.com/ryanoasis/nerd-fonts#font-installation

ここでは４と6の方法を使う。どちらか一つだけを選んでFontをインストールしても構わない。
使えるFontの数と種類に少し違いがあるだけだ。

* Options 4: Homebrew Fonts

  ```sh
  brew tap homebrew/cask-fonts
  brew cask install font-hack-nerd-font
  ```

* Options 6: Ad Hoc Curl Download

  __Linux__

  ```sh
  mkdir -p ~/.local/share/fonts
  cd ~/.local/share/fonts && curl -fLo "Droid Sans Mono for Powerline Nerd Font Complete.otf" https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/DroidSansMono/complete/Droid%20Sans%20Mono%20Nerd%20Font%20Complete.otf
  ```

  __macOS__

  ```sh
  cd ~/Library/Fonts && curl -fLo "Droid Sans Mono for Powerline Nerd Font Complete.otf" https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/DroidSansMono/complete/Droid%20Sans%20Mono%20Nerd%20Font%20Complete.otf
  ```

コマンドをそのままコピペして実行すればFontのインストールが完了する。

## TerminalのFont設定

Fontをインストールしたら、使っているterminalにも適用しなければならない。
文字化けになる。

### macOSのterminal

iTerm2の場合は、FontとNon-ASCII Fontの２種類で設定ができるが、macOSデフォルトのterminalはフォントの設定が一か所しかない。
Options 6の方法でFontをインストールした場合は、Droid Sans Nerd Font CompleteというFontが使える。
そのFontで指定して設定しよう。

<img width="802" alt="スクリーンショット 2019-07-21 18.11.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93752/dcd6b748-fa1f-6553-a197-fb54739892cf.png">

### iTerm2

iTerm2ではFontとNon-ASCII Fontを分けて設定ができる。
Fontでは文字の可読性が優れるRicty for Powerlineを設定して、Non-ASCII FontではDroid Sans Nerd Font Completeを設定する。

<img width="1030" alt="スクリーンショット 2019-07-21 18.14.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93752/48c5e3b2-2dda-70ff-09ec-2994a3d7878b.png">

Ricty for Powerlineについてはこの[記事](https://qiita.com/park-jh/items/3c5b9b4aa5619a3631b3)を参照しよう。

## vim-deviconsのインストール

* vimrcにplugin追加

  ```vim
  Plug 'ryanoasis/vim-devicons'
  ```

* 追加したpluginをインストール

  ```vim
  :so ~/.vimrc
  :PlugInstall
  ```

* vimrcのおすすめ設定

  ```vim
  " guifontを設定しないと文字化けになる。terminalで行ったフォントの設定と同様
  " 公式サイトではLinuxとmacOSの設定が若干異なるが、Linuxの設定でもmacOSで問題なし
  set guifont=Droid\ Sans\ Mono\ for\ Powerline\ Nerd\ Font\ Complete\ 12
  set encoding=utf-8

  " フォルダアイコンを表示
  let g:WebDevIconsNerdTreeBeforeGlyphPadding = ""
  let g:WebDevIconsUnicodeDecorateFolderNodes = v:true
  " after a re-source, fix syntax matching issues (concealing brackets):
  if exists('g:loaded_webdevicons')
    call webdevicons#refresh()
  endif
  ```
laravel 5.7 フォルダの中身を取得

laravel で フォルダの中身を取得したい。

```

        $files = \File::allFiles(public_path("img/icons"));

        foreach ($files as $v) {

//            /var/www/html/uranaibako.com/public/img/icons/123164647.jpg
            $res = $v->getRealPath();

            //123164647.jpg
            $res = $v->getFilename();

        }

```

こんな感じ。

img/icons の中身を取得。
そして、パスを取得する場合は getRealPath とかを使う必要がある。
トリガと実行の順序

#1.トリガと実行の順序
- 01.古いレコードをデータベースからロード（または、upsert 用レコード初期化）
- 02.新しいレコードの値で古い値を上書き
- 03.システムの入力規則
- 04.すべての before トリガ
- 05.システムの入力規則 ＋ カスタム入力規則
- 06.重複ルール
- 07.レコード保存（コミットされていない）
- 08.レコード再ロード
- 09.すべての after トリガ
- 10.割り当てルール
- 11.自動応答ルール
- 12.ワークフロールール
- 13.ワークフロー項目自動更新が存在する場合、レコードが再度更新されます。
- 14.ワークフロー項目自動更新でレコードが更新された場合、標準の入力規則に加えて、before update トリガおよび after update トリガがもう一度 (さらに 1 回のみ) 実行されます。カスタム入力規則、重複ルール、およびエスカレーションルールは再実行されません。
- 15.プロセス
- 16.エスカレーションルール
- 17.積み上げ集計数式の値の更新
- 18.条件に基づく共有の評価
- 19.データベースのコミット
- 20.コミット後のロジック（メールの送信）

#2.DML ステートメント
- insert
- update
- upsert
- delete
- undelete
- merge

#3.DML merge のトリガー実行順
**1.削除対象レコード**

- ⅰ.before delete トリガ実行
- ⅱ.内部処理実行
 - 無効となるレコード削除
 - 新しい親レコードが子レコードに割り当て
 - 削除されたレコードの MasterRecordId 項目設定

- ⅲ.after delete トリガ実行
 
**2.更新対象レコード**

- before / after update トリガ実行。

#Resource

- [トリガと実行の順序](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm)
- [トリガと Merge ステートメント](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_triggers_merge_statements.htm)
- [SFDC：自動化ルールやApex トリガーなどの実行順序](https://tyoshikawa1106.hatenablog.com/entry/2016/03/26/205912)
- [Apex DML 操作](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_dml_section.htm#apex_dml)
- [DML を使用したレコードの操作](https://trailhead.salesforce.com/ja/content/learn/modules/apex_database/apex_database_dml)
SwiftUIでElm architectureを実現するフレームワークSelm

SwiftUIにおいてElm architectureを実現するフレームワーク「Selm」を作っています。

Elm architectureと言っても実は私はElmを扱ったことがなくXamarin+F#でのElm architecture実装のFabulousを使った経験から、FabulousのSwift実装のような形で作っています。

Elm architectureはModel-View-Updateというパターンで処理を行います。ビューの状態であるModelをもとにViewを作成し、Updateによりモデルの状態遷移を行います。

Elm architectureはReduxに影響を与えたそうですが、ReSwiftなどのRedux実装と比べてSelmは以下のような特徴を持っています。

- ディスパッチがタイプセーフで、ReSwiftでいうところのActionをEnumで定義できる。
- モデル-サブモデル（ビュー-サブビュー）間の関係がモデルとメッセージで記述されるので、ビュー-サブビュー間のやり取りが記述しやすい。


## 現状

現在[WIP Pull Request](https://github.com/rizumita/Selm/pull/2)を作成しています。

- [Selmの使い方](https://github.com/rizumita/Selm/blob/c4d31630de9e53de9fb0bce54fc7bb04ed7e4777/Docs/HowToUse.ja.md)
- [サンプルアプリでの実際の実装](https://github.com/rizumita/Selm/blob/c4d31630de9e53de9fb0bce54fc7bb04ed7e4777/SelmSample/ContentView.swift)

を見てもらえると、雰囲気をつかんでもらえると思います。

## 実装例

使い方文書から、カウントアップ・ダウンの最小の実装例を抜粋すると以下のようになります。

```swift
struct MyView: View {
    struct Model {
        var count: Int = 0
    }
    
    enum Msg {
        case up
        case down
    }
    
    static func initialize() -> (Model, Cmd<Msg>) {
        (Model(), Cmd<Msg>.none)
    }
    
    static func update(_ msg: Msg, _ model: Model) -> (Model, Cmd<Msg>) {
        switch msg {
        case .up:
            return (model |> set(\.count, model.count + 1), .none)
            
        case .down:
            return (model |> set(\.count, model.count - 1), .none)
        }
    }
    
    @ObjectBinding var driver: Driver<MyView.Msg, MyView.Model>

    var body: some View {
        Stepper(onIncrement: {
            self.driver.dispatch(.up)
        }, onDecrement: {
            self.driver.dispatch(.down)
        }) {
            Text(String(self.driver.model.count))
        }
    }
}
```

## 今後について

まだSwiftUIが未成熟なのでSelmの仕様も固まっていません。SwiftUIの更新に合わせてSelmの実装を修正していきます。プロダクトで利用できるように成熟させていければと思っています。

質問があればコメントやGitHub Issueでお願いします。
また、興味を持っていただけて開発に参加していただけるとうれしいです。
CSSフレームワーク「Bulma」の Tips集

# はじめに
業務で[Bulma](https://bulma.io/)を一通り使ってみて、Tipsが溜まってきたので吐き出しておきます。
今後、何かあれば随時更新したいと思っています。

# レスポンシブ無効にしてwidthを固定化したい
PCオンリーのサイト作成にBulmaを使っていてwidthを固定したい時があったので紹介します。
Nuxt.js+Bulmaなのでapp.scssでBulmaの変数を以下のように変更しています。

```scss:assets/css/app.scss
$navbar-breakpoint: 0px;
$tablet: 0px;
$desktop: 1024px;
$widescreen-enabled: false;
$fullhd-enabled: false;

#main {
    width: $desktop;
    margin: 0 auto;
}
```

簡単に説明すると各種breakpointを0pxに設定して無効化。
desktopを起点にするのでお好みのwidthを設定。
widescreenとfullhdはenabledで無効化できるのでfalseを指定。
あとはcssでwidth固定してセンタリングすることで対応しました。

# formのplaceholderの色を変更したい
Bulmaのドキュメントになかったので掲載しておきます。

```scss:assets/css/app.scss
$input-placeholder-color: #お好みの色
```

# Columsのマージンを無くしたい
`colums`はマージンがdefaultでついており、
マージンを消したいシーンがよくあるのでメモ。
is-marginlessを`colums`と一緒に付けるだけ。

```html
<footer class="footer columns is-marginless">
.
</footer>
```

# Columsの間隔(gap)を変更したい
`is-variable`をつけて`is-(n)`でgapを変更することが出来る。

```html
<div class="columns is-variable is-3">
.
</div>
```

# 横方向(水平方向)centerにしたい

```html
<div class="has-text-centered">
縦方向センター
</div>
```
# 縦方向(垂直方向)centerにしたい
columnsにはis-vcenteredが使える。

```html
<div class="columns is-vcentered">
縦方向センター
</div>
```
それ以外の要素で縦方向centerを使いたい時には普通にclassを定義。

```css
.is-vertical-center {
  display: flex;
  align-items: center;
}
```

# 動的に要素が変更されるdropdown-menuでwidthを自動調節したい

検索の候補などをdropdown-menuで表現したい時に、普通にdropdown-menuを使うとwidthが表示内容に関わらず$dropdown-menu-min-width(12rem)が適応されてしまう。
これを解消するために以下のようにclassを定義することで解消。

```css
.dropdown-menu {
  white-space: nowrap;
}
```

# ulのデザインが反映されない

普通にulタグで組むとリストマーカーもインデントも反映されません。
以下のようにcontentクラスで<ul>ブロックを囲ってやるとデザインが反映されます。

```html
<div class="content">
  <ul>
    <li>いぬ</li>
    <li>ねこ</li>
  </ul>
</div>
```


# まとめ

Bulmaはドキュメントも充実しているので、自分書くCSSの量を大幅に抑えて（ほぼ書かなくていいと言ってもいいくらい）ページコーディングが出来るのでとても便利です。

たまにこれどうすんの？って疑問に思うこともありますが、Bulmaのコードを読めばよしなにカスタマイズも可能です。

今後Bulmaを使って詰まったことなどあれば随時、追記していこうと思います。
Swiftアンラップ備忘録

## if let 

#### 例文1

``` swift

if let userCode = userRow.code {
       print("正常処理")
    }else{
        print("nilのときの処理")
    }
```
#### 例文2（複数チェック）

``` swift
if let userCode = userRow.code,
       userName = userRow.name {
       print("全てnilではないときの処理")
    }else{
        print("どれかがnilのときの処理")
    }
```
## guard let

guardの場合、else時にreturn処理がないとコンパイルエラーになる。

#### 例文1

``` swift
guard let userCode = userRow.code
    else {
        print("nilの処理")
        return
    }
```
#### 例文2（複数チェック）

``` swift
//  複数ver
guard
    let userCode = userRow.code,
    let userName = userRow.name
    else {
        print("nilの処理")
        return
    }
```
## あとがき
大体の場合、nilで処理終了するし
guard let のほうがミスも防ぎやすく使いやすい感じがした(小並感)。
UINavigationControllerの戻るボタン 陥りやすいミス編も・・・

## UINavigationController の戻るボタンを消したい、非表示にする方法

#### 陥りやすいミス

~~~ Objective-C
self.navigationItem.backBarButtonItem.hidden = YES;
~~~

~~~ Swift
self.navigationItem.backBarButtonItem.hidden = true
~~~

あれれ？表示されるし、タップもできちゃう。となる場合があります。
そんな時はこれを試してみてください。

~~~ Objective-C
self.navigationItem.hidesBackButton = YES;
~~~

~~~ Swift
self.navigationItem.hidesBackButton = true
~~~

ちなみに

## UINavigationController の戻るボタンの文字だけを消す方法

~~~ Objective-C
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
~~~

~~~ Swift
    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
~~~


## 関連記事

【About】(http://qiita.com/sunstripe) - サンストライプ

---

## 制作チーム：サンストライプ

[![sunstripe_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/322f2d60-f19d-af9e-2b6f-7290ca546848.png)](http://sunstripe.main.jp/)
http://sunstripe.main.jp/

(月１WEBコンテンツをリリースして便利な世の中を作っていくぞ！！ボランティアプログラマー/デザイナー/イラストレーター/その他クリエイター声優募集中！!)

### 地域情報 THEメディア
THE メディア 地域活性化をテーマに様々なリリース情報も含め、記事をお届けしてます！！
https://the.themedia.jp/

### ゼロからはじめる演劇ワークショップ
多様化の時代に向けて他者理解を鍛える

https://workshop.themedia.jp/

### プログラミングワークショップ・ウェブ塾の開講！！！
様々なテーマでプログラミングに囚われずに取り組んでいきます。
詳しくはこちら　↓　↓　↓　↓　↓　↓　↓　↓
[プログラミングサロン 月１だけのプログラミング学習塾](https://workshop.themedia.jp/posts/7057553?fbclid=IwAR32CfRQ7RvDOhvuogoSwqxDLMOU7Jvuzljlnx-TMc27qBPX1BnWsfLcBR8
)

### 協力応援 / 支援者の集い
## チーム：サンストライプ
#### プログラミングラボ
https://twitter.com/sunstripe2011

一緒にポートフォリオを作りませんか？現場の体験やそれぞれの立場から年齢関係なく作品を作りたい方々と一緒にチームを作って、作品を作っています。現場に行きたい人には、職場紹介や職場の体験や悩み相談なども受けております。
様々な職種からプログラミングの知識を得たい、デザインの知識を得たい、データーベースの知識を得たいという人が集まっております。
週１のミーティングにそれぞれの近況と作業報告して、たまにリモート飲み会などをしております！！

興味がある方は、DMに話しかけてみてください。

## トラストヒューマン
http://trusthuman.co.jp/
私たちは何よりも信頼､人と考えてます｡

｢コンサルティング｣と｢クリエイティブ｣の両角度から｢人材戦略パートナー｣としてトータル的にサポートします！！

キャリア教育事業
広域学習支援プラットフォーム『のびのび日和』
https://slc-lab.amebaownd.com/

#スポンサー募集
セキュリティグループの作成単位について

AWSのセキュリティグループを設定する機会があったのですが、その際にどういう単位でグループ分けを行うかで社内で2つに意見が分かれたので、備忘録として記載いたします。


結論は今のところ出ていないのですが、もし皆さんにコメントを頂くことができましたら、後ほどまとめさせて頂こうかと思っております。

## はじめに

説明を分りやすくするため、下記のようなシステムにセキュリティグループを設定する場合を想定して話を進めます。
<img width="400" alt="Sample.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235378/cb5aba5c-4822-4f23-619c-aa4d834a35bd.png">

2台のWEBサーバのフロントにELBを、バックにMySQLを置いた構成となります。
Bastionサーバはインターネット側からのSSH接続をシステム内で唯一許可するサーバとなり、
他サーバへのSSH接続は、当サーバを経由してのみ可能とします。

## ミドルウェア単位

ミドルウェアで単位にセキュリティグループを作成する考え方です。
上記システム例では、

| セキュリティグループ名 | タイプ | ポート範囲 |ソース         |
|:----------------------|:-------:|:----------:|:-------------|
| ssh_private            | SSH    | 22         | 10.1.0.0/16   |
| ssh_public             | SSH    | 22         | (接続元IP)/32 |
| http_group             | HTTP   | 80         | ELB_group     |
| ELB_group              | HTTPS  | 443        |  0.0.0.0/0    |
| MySQL_goup             | MySQL  | 3306       | 10.1.0.0/16   |

※(接続元IP) は、リモート接続する端末に設定されているIPとなります。

といったようにセキュリティグループを作成し、
各インスタンスには、

| 役割        | 適用グループ             |
|:------------|:-------------------------|
| WebServer01 | ssh_private / http_group |
| WebServer02 | ssh_private / http_group |
| 踏み台サーバ | ssh_public               |
| DBサーバ    | ssh_private / MySQL_group|
| ELB         | ELB_group      |

といった具体で設定します。

個人的には、アウトバウンドの設定はどうなるんだろう？ という疑問と、
1インスタンスにつき最大5(※)まで というセキュリティグループの制限が気になるところです。

ちなみにネットで検索すると、このようミドルウェア単位での設定で紹介されているサイトが多々あります。
社内でも、こちらが主流派(といっても 3 vs 1 ですが...) でした。


## 役割単位での設定例

各サービスの役割によってセキュリティグループを作成する考え方です。

| セキュリティグループ名 | タイプ | ポート範囲 |ソース         |
|:----------------------|:-------:|:----------:|:------------|
| web                    | SSH    | 22         | bastion       |
|                        | HTTP   | 80         | elb           |
| bastion                | SSH    | 22         | (接続元IP)/32 |
| mysql                  | SSH    | 22         | bastion       |
|                        | MYSQL  | 3306       | WEB / batsion |
| elb                    | HTTPS  | 443        |  0.0.0.0/0    |


※(接続元IP) は、リモート接続する端末に設定されているIPとなります。

そして、各インスタンスに適用する場合は、

| 役割        | 適用グループ |
|:------------|:-------------|
| WEBサーバ01 | web          |
| WEBサーバ02 | web          |
| 踏み台サーバ| batsion      |
| DBサーバ    | mysql        |
| ELB         | elb          |

という形とします。

こちらはポート番号とあわせて、「どこからの通信か」という所も明確に設定することとなるため、
サービス単位よりもセキュリティ的に厳しくなっています。アウトバウンドも役割毎で
設定ができることが多そうなので、サービスに適用するグループ数を抑えることができるメリットがありそうです。

## まとめると

上記だけでは、「役割単位だよ」派の方が良さそうに思えますが、たぶん私が理解できていないメリット/デメリットがあるのでしょうか感覚的には、「役割単位」での設定をベースとして、それに当てはまらない物は個別に作成するハイブリッド運用になるのだろうなぁ とは思いますが、具体的にイメージができておりません。

もし、うちのプロジェクトはこうやっているよ や、こういう考え方もあるよ、 こういうメリットがあるよ などご意見を頂ければ思います。
新入社員なので「わかばちゃんと学ぶWebサイト制作の基本」を読んだ


前回の記事 -> [新入社員なので「わかばちゃんと学ぶGit使い方入門」を読んだ](https://qiita.com/yano0717/items/d3a23f2cb7062b0bd278)

# 3行で概要
* わかばちゃんと学ぶWebサイト制作の基本を読んだ。
* コーディングのみにフォーカスしていないところが良かった。
* 運用に関しては、新入社員を卒業してからも使えそうな知識になりそう

# 何が良かったか

- 1ステップずつ丁寧な説明&漫画で理解がしやすく、**一冊やりきるのが苦にならない。**(重要)
 - 特にCSSの説明がわかりやすい(paddingとmarginがらみ)

- 最終的に自分のサイトをWebに公開できる実力がつく。
 - サーバーへのアップロードは意外とやらないので練習になった。

- コーディングのみにフォーカスした技術書が多い中で、以下の話を掘り下げている。
 - Webサイト制作の**一連の**流れ(企画から運用まで)
 - Google Analytics
 - SEO


# 今後
今後Webサイトの作成・運用をするとき、非常にお世話になりそうな本です。
繰り返し読んで技術をモノにしていきたいと思いました。
[Docker]ローカル開発用MySQL

## 概要

ローカル開発で使用してMySQLサーバを立てたい場合に、Dockerで簡単にMySQLサーバを起動する方法です。
また、今回のサンプルはデータをローカルのストレージに永続化します。
[サンプル](https://github.com/tchnkmr/docker-development-mysql.git)

## 手順

### MySQLの使用するDockerイメージの取得

以下のコマンドにて使用するMySQLのDockerイメージを取得します。\<version\>は使用するMySQLのバージョンです。[MySQLバージョン](https://hub.docker.com/_/mysql)

`docker pull mysql:<version>`

### docker-compose.yml作成

docker-composeファイルを作成します。必要に応じて各項目を変更してください。

```yaml
version: '3'
services:
  mysql:
    container_name: dev-mysql
    image: mysql:<version>
    ports:
      - 3306:3306
    volumes:
      - <local_storage>:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=<passwrod>
      - MYSQL_DATABASE=<database>
```

| 項目 | 内容 |
|:-----|:----|
|version|取得したMySQLのバージョン|
|local_storage|データを保存するローカルパス|
|passwrod|ルートパスワード|
|database|データベース名|

### 起動

`docker-compose up -d`

### 停止

`docker-compose stop`
今更ながら、mockito入門の個人的メモ

最近android(java）のテストを書きたいと思って、モックライブラリのmockitoを勉強したのでメモ

と言っても以下の記事をざっくりまとめただけw
https://www.vogella.com/tutorials/Mockito/article.html#using-gradle-for-an-android-project

## セットアップ

```
// build.gradeに以下を記述。
dependencies {
    // ... more entries
    testCompile 'junit:junit:4.12'

    // required if you want to use Mockito for unit tests
    testCompile 'org.mockito:mockito-core:2.7.22'
    // required if you want to use Mockito for Android tests
    androidTestCompile 'org.mockito:mockito-android:2.7.22'
}
```

上に青字でsyncボタンが出てくるのでタップすると、セットアップ完了。

MainActivity.javaを開き、クラスをクリックして、goto testを選択。
Android testか、unit testのフォルダを選択する必要があるので、
Unit testのフォルダを選択。

// 以下が自動生成された。
```
package com.example.mockitosandbox;

import static org.junit.Assert.*;

public class MainActivityTest {

}
```

まず、テスト対象のクラスをMainActivityと同じフォルダに作る。

```
public class Foo {
    public String foo() {
        return "foo";
    }
}
```
上記コードのFooを右クリックし、unit testをjunit4で作成する。

Footestを以下のように書き換える。
一般的なjunit4のテストだ。

```
import static org.mockito.Mockito.*;

public class FooTest {
    @Test
    public void testClassTest() {
        // モックを作成
        Foo foo = mock(Foo.class);

        // 返り値をモックする。
        when(foo.foo()).thenReturn("kaba");

        // testを作成。
        assertEquals(foo.foo(), "kaba");
    }
```
テストが成功したら、モック成功だ！

### static importとは？
org.mockito.Mockito.*;をstaticにimportすることで、meck()のような、メソッドを、直接テストに使うことが出来る。static importは、staticメンバを使うことを可能にする。例えば、クラス内メソッドや、フィールドをクラスを指定せずに記述できる。
stitic importは、可読性を大きく向上させるので、おすすめです。

## Mockの返り値を設定する。
一般的なモックライブラリのように、モックに任意の還り値を与えることが出来る。
以下のコードでは、モックオブジェクトに帰り値を設定している。

```
package com.example.mockitosandbox;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;

import java.util.Iterator;

import static org.mockito.Mockito.*;

import static org.junit.Assert.*;

public class MainActivityTest {

    @Test
    public void testMoreThanOneReturnValue() {
        Iterator<String> i= mock(Iterator.class);
        when(i.next()).thenReturn("Mockito").thenReturn("rocks");
        String result= i.next()+" "+i.next();
        //assert
        assertEquals("Mockito rocks", result);
    }
}
```

一番やりたいクラス内で宣言される、androidモジュールのモックのやり方が書いていない。
見つかり次第記述する。

これぐらいできたら、基本的なモックは作れそう。

個人的メモ完
【無料】AWS認定試験で役に立ったけど誰も知らないリソース 一覧

# 概要
- Practionerだけだと格好悪いので、Developer Associateの資格を取った
- 基本は[11冠を取った人の記事] (https://qiita.com/nakazax/items/20458e146d3d9f2aa615) を読めばなんとかなるが、**個人的に役に立ったけどあまり知られていない無料リソースを紹介してみる** (Udemy, セールやってなかったので。。ry


# まとめ
[Blackbelt資料集] (https://aws.amazon.com/jp/aws-jp-introduction/)、[Whitepaper] (https://aws.amazon.com/jp/whitepapers/) あたりはよく知られているので説明は割愛します。
Practice Examは有料だが、比較のために載せておきました。なお完全に主観です。

| カテゴリ | リソース  |  費用 | おすすめ度  |  
|---|---| ---|---|---|
| AWS | Exam Readiness Course  | 無料  |  ★★★★★  | 
| AWSJ | Blackbelt  | 無料  |     ★★★★★  | 
| AWS | サービスFAQ  | 無料  |   ★★★★★  |   
| AWS | Sample Questions | 無料 | ★★★★☆ | 
| AWS | Practice Exam | USD$20 (voucherあれば無料* 下に説明) |   ★★★★☆  |
| Third-party | Whizlabs | 無料(課金オプションあり) | ★★★☆☆ | 
| AWS | Whitepaper  | 無料  |  ★★☆☆☆  | 


# AWS公式

## 最初に見ておくとよいExam Readiness Course
<img width="1425" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343755/c77107dd-8bf0-6dcd-649e-fe99b5ec74f2.png">
https://www.aws.training/LearningLibrary?&search=exam%20readiness&tab=view_all

めっちゃ優良な公式試験対策リソースなのに、どの受験対策エントリーにも書いてなくてびっくり。。！ AWS trainingのlearning library、もしくは資格紹介ページの下の方の推奨コースから飛べる。
資格によるみたいですが、Associateレベルなら2-3時間のe-learning教材。**最新の試験バージョンに合わせて試験範囲の説明、練習問題、ポイントとなるサービスをやさしく解説してくれる。** English only. 
(AWSトレーニングサイト専用のビデオ再生プレイヤーなので、1.5倍速にできないのが唯一残念だった。)


## 理解度チェックのためのSample Questions
これは公式サイトからなかなか飛べなくて、「(AWS 資格名) sample questions」とグーグルで検索した方が速いかも。

e.g. "aws developer associate sample questions" を検索してグーグルで見つかったもの
https://d1.awsstatic.com/training-and-certification/docs-dev-associate/AWS_certified_developer_associate_examsample.pdf

10問しかないが、解説付きなので理解度チェックに役立つ。10分で解けるので良い。

## エンタメ感覚で楽しめるThe AWS Certification Quiz Show (CQ)
https://www.aws.training/LearningLibrary?&search=quiz%20show&tab=view_all

AWSオーストラリアがやっているクイズショーです。Aussieアクセントが好きな方には特におすすめ。

<img width="975" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343755/e5bedcfc-f6fe-1cb8-7cb9-772fca9ecfa6.png">
(Source: AWS Training. 背景も毎回オーストラリアのどこかの名所になっている。)

毎回呼ぶAWSトレーナーのゲストが違うので当たり外れあったりするが、**30分の中で6~8問取り上げ、ゲストが考え方やexam tipsを教えてくれる。**問題も、間違いやすいものを含む本番に近い難易度です。Episode 02のトレーナーほんと良かったです。





# サードパーティ
## 過去問をひたすらやるなら Whizlabs
https://www.whizlabs.com/aws-certifications/
<img width="1424" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343755/ea0697c3-6384-f28a-935b-fb319f2a3cfc.png">

- Free Test(10数問)だけ受けたが、USD$20 (セール価格)払えばPractice Testsの700+問題受けられる模様。
- Free Testの問題はAWS公式のPractice Examと酷似している🙂 解説付きなのはすごく助かった。(AWS公式のPractice Examは結果のみでなぜ/どこで間違ったか教えてくれないので、ここで解いて確認すればよいと思う)

例)
こんな感じで問題の下にExplanationが出てくる。書き方雑だったりするが間違ったことは多分言っていない。公式documentationへのリンクもついていたりするので親切。
<img width="1073" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343755/970e8e0b-221d-1a87-4f3b-e63e652731c3.png">
(Source: Whizlabs)


# おまけ
合格したっぽいので、結果を見るのに My Certification -> Benefitsに行ったが、
なんと `Free Practice Exam Voucher` や `50% Discount on your next Exam` があった。。次回も受けろということかな😂
<img width="830" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343755/6fdfccda-c8a1-bf05-c906-54b6a113a2cb.png">
docker-composeで超簡単ローカルwordpress環境作り

# 概要

- ローカルにdocker以外なにも入れずにwordpressの環境をつくる
- dbもdocker-composeに含まれています

# 環境

- docker, docker-composeが使えればOK

# 手順

1. 以下のdocker-compose.ymlを作成

    ```[yaml:docker-compose.yml]
    version: '3.3'

    services:
       db:
         image: mysql:5.7
         volumes:
           - db_data:/var/lib/mysql
         restart: always
         environment:
           MYSQL_ROOT_PASSWORD: somewordpress
           MYSQL_DATABASE: wordpress
           MYSQL_USER: wordpress
           MYSQL_PASSWORD: wordpress

       wordpress:
         depends_on:
           - db
         image: wordpress:latest
         ports:
           - "8000:80"
         restart: always
         environment:
           WORDPRESS_DB_HOST: db:3306
           WORDPRESS_DB_USER: wordpress
           WORDPRESS_DB_PASSWORD: wordpress
           WORDPRESS_DB_NAME: wordpress
    volumes:
        db_data: {}
    ```
1. ``` docker-compose -d up ```
1. ``` http:localhost:8000 ```にアクセス
1. 各種wordpressの設定をして完了 

# 昔と比べて簡単すぎません？

mysql入れたり、xamppやら入れたりしていた頃と大違い…
Laravel日本語ドキュメント（readouble.com）にページ内メニューを常に表示する

## 2019/9/20 追記
GitHubにコードを上げたのでサクッと使いたい方はこちらをご確認ください
https://github.com/tomoeine/readouble-menu

## 経緯（またの名を茶番）
Laravelの日本語ドキュメントは読みやすい~~のだけど、ページ内リンクのメニューがないのが辛いな〜と常々感じていたので~~、メニュー表示するブックマークレットを作った。

**Laravel日本語ドキュメントでキーボードの「A」を押すかヘッダーの⚓️をクリックするとページ内リンクのメニューが出ます**
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/760b9c84-ad3e-2b6d-9cc9-ed00ba171636.png"/>
いやーいこれは便利。

え、もちろん以前から知ってましたよ？うん、マジマジ。
「メニューなくて不便だな〜」と思いながらスクロールしまくったり、英語のドキュメントと行ったり来たりなんて、してるわけないじゃないですか、やだな〜もう。

## ここからが本題
というわけでブックマークレットを作りました。
本家とは違いなんと！！！！ドキュメントを読みながら**メニューを常に表示**しておくことができます😉
なんて便利！！！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/10f8440d-293b-4abd-8a50-17a7fb9678bb.png)
べっ、別に本家のメニューを知らなかったから作ったわけじゃないんだからねっ・・・！

## 使い方
さておき、これはこれでニーズあるかもしれないので公開しておきます。

以下のコードをブックマークバーに登録します。

```js
javascript:var b=document.getElementById("laravelDocumentSideMenu");if(null!=b)b.parentElement.removeChild(b);else{var e=document.getElementById("content").querySelectorAll("h2, h3"),a=document.createElement("div");a.style.position="fixed";a.style.top="30px";a.style.left="0";a.style.backgroundColor="rgba(255,255,255,0.8)";a.setAttribute("id","laravelDocumentSideMenu");b=document.createElement("ul");a.appendChild(b);Array.prototype.forEach.call(e,function(a){var c=a.innerHTML;if("\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u7ae0\u5225\u30da\u30fc\u30b8"== c)return!0;a.setAttribute("id",c);var d=document.createElement("li");"H3"==a.tagName&&(d.style.marginLeft="20px");d.innerHTML='<a href="#'+c+'">'+c+"</a>";b.appendChild(d)});document.body.appendChild(a)};
```

適当なブックマークをブックマークバーに登録して、URL部分を↑で書き換えればOK。
[ブックマークレットの登録方法](https://qiita.com/aqril_1132/items/b5f9040ccb8cbc705d04)

ブックマークバーで登録したブックマークを押すと、左側のメニューが開いたり閉じたりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/80bd72d4-a48b-e7cb-1313-4489e85ad152.png)

## 常に出しっぱなしにしたいなら
自動でJavaScriptを実行してくれる、便利なChrome拡張機能をコメント欄で教えていただきました！
上記のコード（から`javascript:`を除いたもの）を、hostname `readouble.com` に対して設定しておくと、ドキュメントにアクセスしただけで**はじめからページ内メニューが表示された状態**になります😆
[ScriptAutoRunner](https://chrome.google.com/webstore/detail/scriptautorunner/gpgjofmpmjjopcogjgdldidobhmjmdbm)

（これができるなら、閉じるボタンもつけよう・・・）

## その他
ブックマークレットの処理でh2、h3タグにidを振ってアンカーリンクできるようにしてますが、アンカーリンクを他の人に送っても該当箇所には飛べないので気をつけてください。
（これを押してもドキュメントのトップを表示するだけ）
https://readouble.com/laravel/5.8/ja/queries.html#WHERE句


~~個人的には、何も押さなくても常にメニュー出しておいてくれると嬉しいのでChrome拡張も考えようかしら。。~~
→「常に出しっぱなしにしたいなら」を追記
CircleCIでcheckoutすると日本語ファイルがpullできない問題を解決する

## 問題

CircleCIで、アプリケーションのソースコードをcloneするには `checkout` というコマンドを使う。

``` .circleci/config.yml
version: 2.0
jobs:
  build:
    docker:
      - image: circleci/node:lts
    steps:
      - checkout # << これ
      - run:
          name: The First Step
          command: |
            echo 'Hello World!'
            echo 'This is the delivery pipeline'
```

その際、ファイル名に日本語などマルチバイト文字が含まれていると、 `No such file or directory` と怒られて失敗してしまう。

```

====>> Checkout code
  #!/bin/bash -eo pipefail
mkdir -p /home/circleci/project && cd /tmp/_circleci_local_build_repo && git ls-files | tar -T - -c | tar -x -C /home/circleci/project && cp -a /tmp/_circleci_local_build_repo/.git /home/circleci/project
tar: "features/scenarios/お知らせ.js": Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
Error: Exited with code 2
Step failed
```

## 原因

`checkout` の中で `git ls-files` をしているが、その際ファイル名がエスケープされてるのが原因っぽかった。

```bash

$ git ls-files

# （中略）
"features/scenarios/\343\202\244\343\203\263\343\202\275\343\203\274\343\202\267\343\203\263\343\202\260.js"
# （後略）
```

## 解決法

`checkout` の前に `'git config --global core.quotepath false'` を実行して解決。

```.circleci/config.yml

version: 2.0
jobs:
  build:
    docker:
      - image: circleci/node:lts
    steps:
      - run: 
          command: 'git config --global core.quotepath false'
      - checkout
      - run:
          name: The First Step
          command: |
            echo 'Hello World!'
            echo 'This is the delivery pipeline'
```


## 備考

絶対なんか別の方法あるやろと思いつつあんま調べてないのでなんかご存知の方はこっそり教えて下さい
ランキング機能の追加

ランキング機能を追加する際に、製品毎にレビューが多い順に並べる場合、下記内容でデータを取り出すことができる。

```ruby:ranking.rb
product_ids = Review.group(:product_id).order('count_product_id DESC').limit(5).count(:product_id).keys
    @ranking =  product_ids.map {|id| Product.find(id)}
```
reviewsカラム

| id          |review        | product_id   |
|:-----------:|:------------:|:------------:|
| 1        | text         | ３         |
| 2      | test       | 1       |
| 3        | text         | 1         |
| 4          | text           | 3           |
| 5        | text        | 3       |
| 6     | text      | 2      |

product_id:  3>1>2の順にレビューが多い

productsカラム

| id          |name|
|:-----------:|:------------------------:|
| 1        | pen         |
| 2      | glue     |
| 3        | drill         |

①モデル名.group(:カラム名)
groupはモデルメソッドとして元からあるため、:product_idなどでグルーピングする。

②limit(表示したい要素数)
①のままだと最終的にproduct_idの種類全てを取得してしまうため、ランキングに載せたい数を制限する

③order('count_カラム名 DESC')
count_カラム名またはcount(カラム名)でカラムの種類ごとにカウントして
descで多い順に並べる。（少ない順ならasc)

```ruby:ranking.rb
 pry(main)> id = Review.group(:product_id).order('count_product_id DESC').limit(5).count(:product_id).keys
=> [3, 1, 2]

pry(main)> id = Review.group(:product_id).limit(5).count(:product_id).keys
=> [1, 2, 3]
#order('count_product_id DESC')をつけないと、product_idの1から順に取り出すだけになってしまう
```

④count
product_id毎のデータ数を配列形式で並べたハッシュを返すことができる。
{2=>10, 1=>4, 3=>1}
見方としては{product_idが2個=>データ数10個,,,という表示方法になる。

⑤keys
順にハッシュのキーを配列として取り出す。

⑤@ranking = map{|i| Product.find_by(product_id: i)}
map関数で配列の中を１つづつ取り出す。今product_idsの中にreviewが多い順にproduct_idが並んでいるため、find_byで各product_idのインスタンスを@rankingに代入する。
Rails6 のちょい足しな新機能を試す57（Arel is_distinct_from編）

# はじめに

Rails 6 に追加されそうな新機能を試す第57段。 今回は、 `Arel is_distinct_from` 編です。
Rails 6 では、 `Arel` を使った `is_distinct_from` と `is_not_distinct_from` が追加されました。

Ruby 2.6.3, Rails 6.0.0.rc1, PostgreSQL 10.7 で確認しました。Rails 6.0.0.rc1 は `gem install rails --prerelease` でインストールできます。

```shell
$ rails --version
Rails 6.0.0.rc1
```

# User モデルを作る

User モデルを作ります

```shell
$ bin/rails g model User name
```

# User モデルを修正する

`scope` を使って、 `is_distinct_from` と `is_not_distinct_from` を定義します。

```ruby:app/models/user.rb
class User < ApplicationRecord
  scope :is_distinct_from, ->(name) {
    users = Arel::Table.new(:users)
    where(users[:name].is_distinct_from(name))
  }

  scope :is_not_distinct_from, ->(name) {
    users = Arel::Table.new(:users)
    where(users[:name].is_not_distinct_from(name))
  }
end
```

# seed データを作る

```ruby:db/seeds.rb
User.create(name: nil)
User.create(name: 'Taro')
```

# マイグレーションを実行し、seedデータを登録する

マイグレーションを実行します。seedデータも登録します。

```shell
$ bin/rails db:create db:migrate db:seed
```

# rails console で確認する

`rails console` を実行して確認します。

`is_not_distinct_from` を実行してみます。

```irb
irb(main):001:0> User.is_not_distinct_from('Taro').to_a
  User Load (1.1ms)  SELECT "users".* FROM "users" WHERE "users"."name" IS NOT DISTINCT FROM 'Taro'
=> [#<User id: 2, name: "Taro", created_at: "2019-07-14 02:31:10", updated_at: "2019-07-14 02:31:10">]
```

`is_distinct_from` を実行してみます。

```irb
irb(main):002:0> User.is_distinct_from('Taro').to_a
  User Load (1.0ms)  SELECT "users".* FROM "users" WHERE "users"."name" IS DISTINCT FROM 'Taro'
=> [#<User id: 1, name: nil, created_at: "2019-07-14 02:31:10", updated_at: "2019-07-14 02:31:10">]
```

`where.not` を使って実行してみます。 `is_distinct_from` と違って、 検索結果が `[]` になることに注意してください。

```irb
irb(main):003:0> User.where.not(name: 'Taro').to_a
  User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."name" != $1  [["name", "Taro"]]
=> []
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try057_arel_null_safe_comparison


# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [Arel: Implemented DB-aware NULL-safe comparison](https://github.com/rails/rails/pull/34451)