いがにんのぼやき

WEBエンジニアのブログ。IT、WEB、バンド、アニメ。

ORMの使う使わないについて

  • とあるコミュニティでORMを使う使わない、使い方の議論があった
  • 自分の考えを整理するためにも今自分がこうしたほうがいいなって運用方法を書き出してみる
  • 個人の好みによるものが大きいので一意見として
  • ここではサーバーアプリケーションでの文脈

ORMってそもそも何

前提知識としてORMとは

  • インピーダンスミスマッチを解消するもの
  • インピーダンスミスマッチとは
    • 概念モデルと論理モデルの違いを埋める
    • アプリケーションの要件にそった概念モデル(Entity)は、論理モデル(テーブル)と1対1になるとは限らない
    • こういったDB側の都合をアプリケーションで意識しないで済むようになるもの

ORMを使うか使わないか

でもDB側の都合を意識しないで済むって言うけど結局パフォーマンスとか考えたら意識しなくちゃいけないよね?
で、ORM使ってWhereとか書き始めたらそれSQL書いているだけだよね?ORMいらなくない?
っていうのが今回のORM使う使わない問題の根幹としてあると思う

サーバーアプリケーションからDBの値を引く

サーバーアプリケーションからプログラムを書いて、DBから値を読み込み、アプリケーションで使用する、その方法は大体こんな感じだと思う

  • SQLを直接書いてORMを用いずマッピング
  • ORMを使用するパターン
    • ORMの機能(クエリビルダーなど)を使用する
    • ORMとSQLを組み合わせる

個人的意見

個人の好みによる ORMでクエリビルダーを有効活用するのが自分の最適解

SQLを直接書いてORMを用いずマッピング

ここからは各方法を実際のコード(C#)で良いところ、悪いところを挙げていく
ORMを使用しないマッピングの場合、

  • SQL書く
  • 何かで実行、結果は配列みたいなものに入る
  • 自分で毎回マッピング
 var sql = $@"
 SELECT
  USER.NAME
  ARTICLE.TITLE
 FROM
  USER
 INNER JOIN
  ARTICLE ON ARTICLE.ID = USER.ID
 WHERE
  ID = @id
 ";
 
 return Connection.Query(sql, new { id });
 
 // 上の呼び出し元
 foreach(result in results)
 {
    var name = user["Name"]
    var title = user["Title"]
    
    // 何かの処理
 }

良いところ

  • クエリを直接かけるのでハイパフォーマンス
  • 特別構文解釈の負荷もかかりにくい

悪いところ

  • 取り回しが悪い

そのままSQLからしっかりデータベースのことを考えてチューニングできるのでいい
でもビジネス要件に耐えられるものではないかなあと思ってしまう
上記は単純なSQLだが複雑度が増し、その複雑度の増したSQLが画面やAPIによって若干の条件が変わるごとに同じSQLを書くことになったりして辛くなるのでは
サーバーアプリケーションにおいてはこれを用いることによって行えるパフォーマンス向上も一般的なサーバーアプリケーションでは早すぎる最適化なのではと思う

ORMとSQL書くパターン

前の直SQLだけの場合と比べるとマッピングが追加されただけ

 var sql = $@"
 SELECT
  USER.NAME
  ARTICLE.TITLE
 FROM
  USER
 INNER JOIN
  ARTICLE ON ARTICLE.ID = USER.ID
 WHERE
  ID = @id
 ";
 
 // Userクラスにマッピングされる
 return Connection.Query<User>(sql, new { id });

良いところ

  • クエリを直接かけるのでハイパフォーマンス

悪いところ

  • 取り回しが悪い

これも前述の取り回しの問題が解決できない

ORMでクエリビルダーで書くパターン

C#だとメソッドで書くパターンとクエリ式というもので書くパターンがある

  // メソッド形式
 var result1 = _context.Users
                .Join(
                _context.Articles,
                user => user.ID,
                article => article.UserId,
                (user, article) => new { user, article })
                .Where(m => m.user.ID == id)
                .Select(m => new { m.user.Name, m.article.Title }).ToArray();
 
 // クエリ式
 var result2 = (from user in _context.Users
                join article in _context.Articles
                on user.ID equals article.UserId
                where user.ID == 1
                select new { user.Name, article.Title }).ToArray();
  

良いところ

  • (静的解析であれば)補完が効く
  • 通化、拡張がしやすい

悪いところ

  • 独自構文、メソッドを覚えなくてはいけない
  • 発行されるSQLを把握しとく必要がある

これのいいところは取得するカラムの絞り込みを後から行いやすかったり、Whereの共通化、追加を行いやすい
JoinやWhereの部分を拡張メソッドとして切り出してあげることも可能

  public static IQueryable<User> HasArticle(this IQueryable<User> query)
 {
     return query.Where(user => user.Articles.Any());
 }
 
 var result = _context.Users
                .HasArtice()
                .ToArray();

みたいな
ここらへんはORMによりけり
C#のクエリ式はSQLそのままに近く、かつプログラミング言語の機能を生かせるのでかなりいいと思っている
リッチなORMであれば上記のようなクエリビルダーを使うこともないかもしれない
ここらへんは後でもう少し深堀したいところ

Vue.js スタイルガイドのすヽめ

概要

この記事は Vue.js #3 Advent Calendar 2018 の 10 日目の記事です。

この記事ではVue.jsのスタイルガイドを今一度皆さんにすすめたいと思います。

jp.vuejs.org

Vue.jsのスタイルガイドって?

Vue.jsでコードを書くときに命名や記述順序など細かい設計で議論を呼ばないように公式で公開されているスタイルガイドです。
HTML、JavaScriptのスタイルの言及ではなくVue.jsのスタイルの言及のみを行っています。
例えば、これから紹介するコンポーネントのファイル名だったりプライベートなプロパティ名の命名規則なんかが明記されています。

現実的なことが書いてある

このスタイルガイドは細かいことは議論をスキップできるという意味でいいのものです。
加えて特にいいポイントが、公式が現実的な解を示しているというところです。
この現実的な解というのは例えば昨今のエディタを意識していたりといったことです。

例えば 密結合コンポーネントの名前 の詳細な説明をみて欲しいです。

このスタイルは親コンポーネントと密結合した子コンポーネントは、親コンポーネントの名前をプレフィックスとして含めるというものです。
その中で以下のような記述があります。(一部省略)

この問題を、子コンポーネントを親コンポーネントの名前を元に命名したディレクトリの中に入れることで解決したいと思うかもしれません。
例えば:

components/
|- TodoList/
   |- Item/
      |- index.vue
      |- Button.vue
   |- index.vue

これは推奨されません。以下のような結果を生むからです:
同じような名前のファイルがたくさんできてしまい、コードエディタ上で素早くファイルを切り替えるのが難しくなります。
ネストしたサブディレクトリがたくさんできてしまい、エディタのサイドバーでコンポーネントを参照するのに時間がかかるようになります。

これの正しい例としては下記のようになります。

components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue

このスタイルガイドではこのように、現代のエディタに合わせて開発をしやすいように現実的な解答をしていたりします。

また、コンポーネント名における単語の順番 にあるようにコンポーネント名はそのコンポーネントとして重要な単語を最初にするということも書いてあります。

例えば検索関連のコンポーネントでは、以下のような自然言語のようなコンポーネント名ではなく

components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue

以下のように何に関するコンポーネントなのかを最初に明記するということを推奨しています。

components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputExcludeGlob.vue
|- SearchInputQuery.vue
|- SettingsCheckboxLaunchOnStartup.vue
|- SettingsCheckboxTerms.vue

一般的にエディタではファイルはアルファベット順に並ぶので、コンポーネント間のあらゆる重要な関連性はひと目ではっきりと分かります。

こういった現実的な解を定義しています。

他に

といったことが定義されています。
一部はeslintのプラグインを入れることで自動化が可能なので導入をおすすめします。

github.com

これで快適なVue.jsライフを!

Vue CLIのvue serveが便利

Vue CLIを触っていたらこんなものがあることを知らなかった。
単体でVueのコンポーネントを試したりできるらしい。

cli.vuejs.org

手順としては簡単。

  • npm install -g @vue/cli
  • npm install -g @vue/cli-service-global
  • vue serve [実行したい.vueファイル]

Vue CLIの基本的な設定(webpackやbabel,eslintなど)が適用されてビルドされている。
地味に -o オプションでいちいちコピペしなくてもブラウザが自動で開くか選択できるとか気が聞いている。

だからVueの構文試したいなとかなったらすぐに作ってすぐに試してが出来て便利。
こんな風にコンポーネントを作って。

App.vue

<template>
  <div>
    <h1>Hello!</h1>
    <ul>
      <list-item v-for="item in list" :value="item"/>
    </ul>
  </div>
</template>
<script>
import ListItem from './ListItem.vue';

export default {
  components: { ListItem },
  data() {
    return {
      list: [1,2,3]
    };
  },
};
</script>

ListItem.vue

<template>
  <li>{{ value }}</li>
</template>
<script>
export default {
  props: {
    value: {
      required: true,
      type: Number,
    },
  },
};
</script>

そのまま vue serve -o とするとApp.vueが実行されたブラウザが開かれる。

$ vue serve -o
 INFO  Starting development server...
 98% after emitting                                                           t
 DONE  Compiled successfully in 1146ms                                  11:38:35


  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.2.108:8080/

  Note that the development build is not optimized.
  To create a production build, run npm run build.

JSも実行できるのでVue RouterとかVuexも使えそうかな?
用途としてはコンポーネント単体を試すくらいがちょうどいいかも。

.Net Core MVCでTag Helperを自作する

docs.microsoft.com

.Net Core MVCのRazorではHTML Helperとは別にTag Helperというものが使えるようになっている。
そのTag Helperを自作したときのメモ。

作り方

public class PriceTagHelper : TagHelper
{
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "span";
    }
}

実質これだけ。
これでView側のcshtmlに@addTagHelper *,[アセンブリ名]と記述するだけで使用できる。
ちゃんと公式に書いてあるんだけど勝手にここを名前空間を指定するものと思ってハマった。

こんな感じ。

@addTagHelper *,SampleCoreWeb
<price>10000</price>

出力結果

<span>10000</span>

カスタマイズ

上記はただタグを差し替えているだけなのでこれだけじゃ使う意味はない。
なのでカスタマイズしていく。

例えばお金を扱うことにしよう。
よくある要件でお金の値を3桁ごとのカンマ区切りにして末尾に円を付けるとする。
実際どうするかって言うとこうなる。

public class PriceTagHelper : TagHelper
{
    public decimal Value { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "span";
        output.TagMode = TagMode.StartTagAndEndTag;
        
        var yen = Value.ToString("C").Substring(1);
        output.Content.SetContent($"{yen}円");
    }
}
<price value="10000" />

出力結果

<span>10,000円</span>

output.TagMode = TagMode.StartTagAndEndTagというのは<hoge />のような開始終了タグが一つになっているときに、HTMLでは開始終了タグを別にそれぞれ出力するために指定している。
TagHelperを継承したクラスにプロパティを宣言するとそのプロパティ名のケバブケースを属性として扱うことができる。
なのでここではvalue属性を使ってdecimalの値を入れることが出来る。

開始終了を単一のタグにするか分けるのか

今回のような値を入れて終わりという要件であれば開始終了が単一のタグの形式でいいのかなと思う。
開始終了のタグが別である場合というのは、中に文章など落とし込みたい時などで使えるのかな。
一応さらっと今回のケース(カンマ区切りはしてないけど)も載せておく。

public class PriceTagHelper : TagHelper
{
    public decimal Value { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "span";
        var content = await output.GetChildContentAsync();
        output.Content.SetContent($"{content.GetContent()}円");
    }
}
<price>10000</price>

カンマ区切り以外は同じ結果が出力される。

<span>10,000円</span>

単一のタグに属性を付与する利点

  • 値を複数付与できる
  • モデルを入れたりも可能
  • 補完が効く

大体属性をうまく使ったほうが利点が大きい。
そもそも組み合わせることも可能なのでうまく使い分けたり組み合わせていきたいところ。

属性の補完が効くのはとてもいい。

f:id:igatea:20180531002111p:plain

Vue.js Tokyo v-meetup #7 に参加してきた

Vue.js Tokyo v-meetup #7 に参加してきました。
vuejs-meetup.connpass.com

募集開始が平日の12時で10分で一般参加枠もLT枠も埋まったのを見てVue.jsは人気なんだなと思いました。
しかも参加率99%と昨今のITイベントだと信じられないくらいの参加率・・・。

そんなイベントのレポートを自分なりにまとめたいと思います。

「結局Nuxt.jsってなにがいいの?」に対する回答

「結局Nuxt.jsって何がいいの?」に対する回答 by potato4d

@potato4d フリーランス

あまりはっきりとした回答がネット上に転がっていないのでそこらへんの話をすると

Nuxtとは

ReactでNext.jsがでて、それにインスパイアされてVue.jsでもできないかと開発が始まった
SSRフレームワークを目指して始まった
すでにSSRツールではなく統合開発ツールの面を持つようになっている
WebpackやBabelなどが準備されている

使うべき理由

開発の足回りを楽にすることができる

今からVue.jsの開発を始めるときになんでもできる
BabelやWebpackといったツールの設定、SSR環境などが揃っている

概念的な話

規約をフロントエンドに持ち込んだ

Nuxt.jsに限らない話・・・
「ここにこう配置したらうまくいくよ」ってもの
開発者はアプリケーションの本質だけに目を向けられるように
日本人的には仕組み化と言える
いわゆる ベストプラクティス勝手にやってくれるマン

規約の利点

オレオレアーキテクチャの排除ができる

こう言ったみんな似たようなことをやってるけど煩雑なものが人の手を離れる

コード品質の最低ラインを担保する

便利だからと作ったutilディレクトリとかcomponentのディレクトリの複雑さとか
plugins / middlewareなどを正しく使うことで使う人自身が楽できる設計に
layouts / pages / composnentsで分かれていたりしている

誰かの主観によって作られたルールはいつか壊れるので規約によって秩序を保つ

規約の良さとは、開発において避けられない開発者のレベル差を吸収すること

全くの初心者だけで書けるわけではない
うまくやってくれるから知らなくてもいいわけではない

規約は単なる頻出のベストプラクティス集
あくまで頻出設計を楽にしてくれるもの

React、Vue、Angularとそれぞれの特徴、規模感によっていい悪いと言われることについて

なぜVue.jsは中小規模向けか
フロントエンドにおける「ちゃんとしてないPHP」みたい
自由度が高すぎる

対してAngularは大規模向けか
Angular Wayに乗れば楽ができる
敷居は高いが人員をスケールさせやすい

これはだいたい「強い」規約

Vue.jsに統一規格を入れることによってレベル差を吸収する
= 人員をスケールさせやすい
= ルールに乗るとラクできる
= Vueの手軽さに堅牢性

Nuxt.jsは機能的なところばかり注目されるが、規約が存在する
規約の概念は大きなメリットと小さなデメリットをもたらす
ちゃんとVue.jsに詳しい人も必要
規約はAngularが近い概念だがこれまでなかった
ルール順守の世界観の影響力が強くなる

LT

最初の講演のあとはLTでした。

Vue.js + D3.jsでグラフを描く

Vue.js + D3.jsでグラフを描く // Speaker Deck

@hogesuke_1 さくらインターネット

コンポーネント分割 X軸、Y軸、パスに分けた

パス
SVGの要素をテンプレートに書く(path要素)
computedでD3のライン関数を用いて描画

X/Y軸
同じくテンプレートに書く(g要素) axisBottomやaxisLeftで同じように描画

アニメーション
CSS transitionを使ったがChromeでしか動かなかった
代わりにTweenLiteを使った
pathのd属性に用いることでアニメーション可能

VUE DESIGNER でコンポーネントGUI で開発する

Vue Designer でコンポーネントを GUI で開発する by katashin

@ktsn

XcodeとかでアプリはGUIで作るけどWebにはないのでそれを作ってみた

VSCodeコンポーネントで描画されるようなものを作った

github.com

拡大縮小したり文字を書き換えてもリアルタイムに反映されていく
プロパティの値を変えたりすることもできるもの
コンポーネントドラッグアンドドロップで入れられるようにもした
Chromeのdevツールで色をコピーしていたようなことも簡単にできるようにした

ロードマップ
1.0でエンジニアが使えるように
2.0でデザイナーが使えるように

(とても面白そうなプロジェクトでした!)

VUEX PLUGIN 101

Vueのプラグインを使うがVuexのプラグインを使ってる人は少ないイメージ
Vuexのプラグインは簡単に作れる
actionではミューテーションの更新が3秒待つといった簡単なものを作った
awesome VueのでもVuexのプラグインが紹介されている

SVG makes your components to testable

SVG makes your components to testable // Speaker Deck

@haribote_nobody

テストしているか HTMLを使ったグラフィカルなものは難しい 期待値はなんなのか

SVGはコードであり文字列、つまり期待値を定めやすい

Jestを使ってテストしていく

初回のこれが期待値となる 期待値が満たせるように裏のロジックを実装していく

Nuxt.js ファーストインプレッション

Nuxt.js ファーストインプレッション / Nuxt.js First Impression // Speaker Deck

@y_temp4 ALIS

フロントはReactかVue、おそらくVueになると思うと入社前に言われた
React経験があったのでVueに対して色々不安があった
触って見た結果Nuxt.js(Vue.js)がいいものだと気付いた

starter-templateの質が高い
vue-cliからNuxtの雛形を生成 そのまますぐに開発を始められる

.vueファイルが管理しやすい
HTML/CSS/JSが1つのファイルで触れる 圧倒的に楽

日本語ドキュメントの充実
全部日本語のドキュメントが揃っていて学習コストが低い

結論
Vueを使った新規プロジェクトでNuxtを使わない手はない 想像以上にVue.jsの敷居は低い

最後に
ALISのソースコードをオープンにしている

github.com

Vue.jsにありがとう

Vuejs meetup

@carotene4035

双方向データバインディングやリアクティブシステム
最近詐欺にあいかけてVue.jsも信用できなくなってきた
それの中身を読んで見た

dataオブジェクトはgetterとsetterとdep.notifyで算出プロパティに通知

Vueのコンポーネント実装パターン

Vue コンポーネント実装パターン // Speaker Deck

@sekikazu01 BizReach

Controlled Component
v-modelと:value="value", @input=this.\$emit('input', $event.target.value)と同じ

transparent Wrappers
公式にもラッパーコンポーネントを作れると書いてある

Building Real-time Vue App

Building Real-time Vue App // Speaker Deck

@joe_re ClassDo CTO

Socket.IO
双方向通信をサポートするイベント通信
Rooms and Namespaces
名前空間を機能ごとに実装

SocketIO with Vuex
SocketIOとVuexを組み合わせるプラグインを自作

github.com

最後に

どの発表もとても面白かったです。
懇親会でも話していてVue.jsを実際に使っている方以外にあまり使っていない方も参加していて、Vue.jsは注目されているなと感じました。
また参加したいと思います!

Azure Virtual MachinesでWindows RDPを試す

検討

もくもく会とか外部での発表で手軽にWindows 10にRDP出来るような環境が欲しい。
自前でWindowsのノートを用意してもいいんだけど気に入るものが中々なく、気に入ったものは高いしMacbookも欲しいしで簡単に立ち上げられて安価で使えるWindows環境と考えた時に、意外とクラウドが選択肢に入るんじゃないかと思った次第。
AWSかAzureでいけるかなーと思って試してみる。

クラスメソッドでAWSWindowsを使うという記事があった。

dev.classmethod.jp

この記事を参考にするとAWSではEC2とWorkSpacesでWindowsを使うことができるらしい。
ただし以下の点からAWSは検討から外した。

  • WorkSpaceは月額料金のみか月額料金+時間料金
  • WorkSpaceで使えるWindows 10はWindows Serverのデスクトップエクスペリエンス
  • EC2はWindows Server系OSのみ

料金に関しては時々しか立ち上げないので月額だと高くなってしまうんじゃないかと。
Windows Serverに関してはピュアなWindows環境にしたいのでなるべくそのままのWindowsを使いたかった。

なので本家MicrosoftのAzureのWindows Virtual Machinesがそこら辺を叶えてくれて、かつ簡単そうなのでこちらで試してみる。

azure.microsoft.com

作成

Azure Portalにアクセスし、左のメニューからVirtual Machinesを選択。
追加を押して、Windows 10と検索。
Windows 10 Proを選択すると下記のような画面になるので作成をクリック。

f:id:igatea:20180502225920p:plain

スペックの選択もここで行う。

f:id:igatea:20180502230025p:plain

サイズの選択で出てくるディスクはメインディスク+αの容量っぽい?
ここら辺の情報が欲しい。
今回は32GBのものを選択したら下記の画像のようになった。

f:id:igatea:20180502224811p:plain

ポチポチ押していくと最後にスペックの確認が表示されて作成ボタンを押すと作成が開始される。
基本的にはそのまま変更せず作成した。

ということで作成が完了したら作成したリソースを選択して接続をクリック。
そうするとRDPのファイルがダウンロードされるのでそれを起動し、事前に設定したログイン情報を入力するとWindowsに接続することができる。

ということで動いた。

f:id:igatea:20180502222706p:plain

使ってみて

低速回線(1Mbps)だとコード書くくらいなら少し遅延があるが使えるレベル。
けど色の変化が激しいものとかだと描画に大きなラグが見られる。(例えばChromeYouTubeのトップページをスクロールするとか)
ある程度の回線であれば結構使えそうかも?

あとこれは単純にMacからWindowsにRDPするときの問題なのでMacとコマンドが違くて戸惑った。

  • Command → Windows
  • Control → Ctrl
  • option(alt) → alt

最終的な料金だけど、計算したものの自身がないので再度請求が来てからしっかり確かめるものとする。

ただそのホストのトップページに飛ぶというChrome拡張を作った

github.com

Chrome ウェブストアに公開しているわけではないが、作った。
Ctrl + Shift + H で開いているページのホスト直下に飛ぶだけ。
いつもそのサイトのアイコンをクリックするとか面倒だったので。

Chrome拡張開発に関しては、Background ScriptsとかContent Scriptsだとか、Background PagesとかEvent Pagesとかよく分かっていない。
公式を読んでいるんだけど英語力が足らず全く頭に入ってこない。

何か本当に作りこみたいものが出来た時に再度調べなおしたい。