https://fukuokaex.connpass.com/event/150079/
最近のElixir開発で得た知見を語る2019/10/30 fukuoka.ex#32:秋のElixir LT大会
View Slide
自己紹介● 古賀 祥造(こが しょうぞう)● 株式会社ベガコーポレーション● fukuoka.exビルダー / もくもく会リーダー● Elixir/PhoenixでAPIを日々書いています● twitter: @koga1020_
今日お話しすること● 最近お仕事でElixir・Phoenixを触っています○ 今年の3月ぐらいから、やっと半年ちょい● その中で得た知見をつらつらと語ります
何やってる?● 社内基幹システムの構築● 事業拡大に向けたシステム刷新のプロジェクト● REST APIの構築○ データの整備、商品ページ公開の自動化などなど○ Elixir・Phoenixを採用し、せっせと開発中○ リリース前なので、Elixir(v1.9.x) / Phoenix(v1.4.x)に追従
Elixir・Phoenix実際どうよ?
思うところ● メリット○ ロジック書きやすい最高 ☺○ テストがサクサク書ける ☺○ デプロイも一度mix release用のDockerfileを組んでしまえば楽☺● デメリット○ エラーメッセージ分からない○ Ectoクセが強い○ ex_awsでCloudFront操作できない
エラーメッセージ分からない● エラーメッセージだけで分からないこともしばしば● 特にPlug。よくハマる。● 自作Plugを組んでいる場合は要注意。よくよくデバッグすると「あーこのエラーPlugが原因だったのねー」となることもしばしば
GitHubのissueにとりあえずつっこもう
depsにinspectを仕込むことも可能
根気よくdebugする力が必要
Ectoクセが強い● Ecto: DB Wrapper○ RailsでいうActive Record○ LaravelでいうEloquent● オブジェクトでないので、ORMではない● これがなかなかクセがすごい
クエリっぽく書くこともpipeで書くことも出来る
弊チームではpipeでの書き方を採用
慣れれば怖くない!● Ecto.Multi● cast_assoc, put_assoc○ 「Ectoのassoc関数を整理してみる」という記事書いてます○ https://www.koga1020.com/posts/ecto-assoc-functions● dynamic queryこの辺りを理解してからは基本的な処理は書けるようになったこの辺りのキーワードをまずは拾ってみる
ex_awsでCloudFront操作できない● AWSの操作APIを提供するex_awsというライブラリ● 要件でCloudFrontを操作する必要があったが、該当するモジュールがない● こんな具合に、「他言語ならあるのに!」問題にぶつかることも→ 結局、PHPのSDKを参考に自作した。多少リソースに余裕がないと厳しい?
ロジック書きやすい最高☺● 関数パターンマッチが至高● チーム内ではif文を書かない方針○ ifを書くと、分岐が増えたときに対応できない● 関数パターンマッチ or withに寄せる○ この辺りはチームでの決めの問題かも○ 世のライブラリの実装を参考に見るのが吉
構造体をマッチさせる際は常に明示的に書く
Enumを使いこなす● fukuoka.exでもよく言われているが、これはガチ● map, reduce, filter, reject, group_by あたりは鉄板○ そのあとは組み合わせたflat_mapやmap_joinなど● Enumerable protocolが実装されたdata typeなら動作するので、MapもOK
credoで秩序を保つ● https://github.com/rrrene/credo● Elixirの静的コード解析ツール● 以下の観点でコードの改善点を指摘してくれる○ consistency / design / readability / refactor / warning● pre-commitでcredoでエラーが出たらcommitできないようにしている○ ついでに mix format も自動実行にしている
警告を出したいものだけ設定することも可能● credo gen.config で設定ファイルを書き出し、カスタマイズ可能● .credo.exsが生成される● projectのrootかconfig/.credo.exs としておけば設定値が採用される
テストがサクサク書ける● mix testで即テストが実行可能● optionが豊富。以下のオプションでテストを回すと良い感じ● --stale: 前回のテストから変更のあったモジュールに関するテストだけ実行● --max-failures: 許容する失敗回数。1だと1つテストケースがこけた瞬間に終了
便利なライブラリ達● mix_test_watch○ ファイルの変更を検出してテストコードを実行○ https://github.com/lpil/mix-test.watch● mock○ モックライブラリ○ https://github.com/jjh42/mock
便利なライブラリ達● Power Assert○ テスト結果をみやすくしてくれるライブラリ○ https://github.com/ma2gedev/power_assert_ex● ExMachina○ rubyでいうfactory_bot(おそらく) / LaravelでいうFactory○ https://github.com/thoughtbot/ex_machina
● mix release を利用● Dockerfileのマルチステージビルド○ mix releaseの成果物をalpineのベースイメージにCOPY● GitHub → Travis CI → ECR → ECS のデプロイパイプラインデプロイAmazon ECR Amazon ECSGitHub Travis CI
エラー監視● Sentryを採用● ElixirのSDKもあり、導入は楽チン✨● https://github.com/getsentry/sentry-elixir● Plugでエラーを拾うことができる
その他諸々
OpenAPIのドキュメンテーション元々PhoenixSwaggerを利用してswagger.jsonを生成していた|> 開発が進むにつれて、メンテが辛くなってきていた|> さらにElixirがv1.9に上がった直後は依存ライブラリの関係で使えない状態に、、|> このタイミングで、API定義はymlを直接編集するようにした
Elixirの中で書きたい人は● Open API Spexなるライブラリがある● https://github.com/open-api-spex/open_api_spex● Elixirコード内でAPI定義を記述できる
デプロイ(個人開発)● Gigalixir × Github Actions● 特定のブランチにmergeされたら、git push gigalixir master を実行する● ブログにも書いたので、よければ是非○ https://www.koga1020.com/posts/gigalixir-deploy-from-github-action
Thank you!