ここ数日の開発と実況
最近の配信
最近はゲームと開発の両立を目指して私生活のほとんどが垂れ流されています。
これはこれで精神とプライベートが脆弱になってしまいそうです。
ほどほどに楽しみながら引き続き学習を続けていきたいところです。
開発の進捗と残タスク
認証機能はやはり複雑度が高く、今になっていろいろな作りの考慮できていない点が浮き彫りになってきました。
最近の状況は以下の通りです。
あ、そういえば本開発のタスク管理としてGithub Projectsを使い始めました。
個人でメモとして利用する分には非常に便利です。
進捗
- 認証を2パターン実装完了
- ツイートCRUDを認証が通った場合にのみ利用できるように修正
- ログアウトボタンのOn, Offを共通ヘッダで自動判断できるように実装
残タスク
- ログアウトボタン配置などのデザイン調整
- 全体の圧倒的リファクタリング
- ログアウトボタン表示・非表示制御方法の検討
- エラーハンドラーから表示する404ページのlangsを適切に実装
- Auth系のimplicit executionContextを良い感じにする
- ドキュメントの作成
動きとしてはそれっぽい状態にまで持っていけているのですが、細かいところで違和感のある実装になってしまっています。
MessagesApiやExecutionContextの管理ができておらず、いろいろな場所に点在している感じになっています。
またログアウトボタンの制御を行うに当たって最適な方法が何か悩んでいます。
今はimplict parameterで渡されているrequestをisInstanceOfでUserRequestかどうかを判定しています。
ただこれはかなり実装に依存しているので、できればもう少しスマートに実装したいです。
request.session.get(key)
がisDefinedであれば表示する、というように制御してもいいのですが。。。
実はシンプルで一番いいのでしょうか。ただそうするにしてもtwirlから利用するヘルパーを実装して多少隠蔽してあげた方が良いのかなとおもいます。
定数にしているkeyをわざわざ画面から呼び出すのが、いまいちな感じがしていたり...
まとめ
システムの実装者がビジネスロジックに集中できるように共通処理を隠蔽するのって難しいですよね...
実装者は普通のPlayを利用しているのと同じ感覚で使えるように上手いこと作りきりたいです。
まだまだScala力もPlayへの理解も足りなさそうです(´-ω-`)
Playの認証処理をいくつか作る part2
本日の配信
今日は肌色しかないモデル、トライセプトくんで配信をしてみました。
トライセプトくんは純粋におっさんなので、準備が楽でいいですね〜(´・_・`)
というわけで、昨日から引き続きログイン認証機能を作成してみました。
進捗と残タスク
今日は思ったよりも順調に実装が進みました。
2日前の昨日の段階で、2パターンの実装それぞれがイメージできていたことが大きかったみたいですね。
個人的には今日実装したパターンの方が何かと使いやすいのかなと思ったりしています。
ただ認証処理でslickからデータを取得しているのでFutureがうまく処理できなくてAwaitで強制的に取り出しているんですよね...
ここもうちょっとうまく処理したいですね。
あとEitherとか使ってカッコよく書きたい感じがあるのですが、なくても動いてるんでそれならなくてもいいのかなって悩んだり...
進捗
- パターン2の認証処理実装完了
残タスク
- リファクタリング
- ドキュメント作成
いったん実装ができたので、これを利用した具体的な実装に落とし込むところと、それに合わせたドキュメント作成が残っていますね。
ここからが本当の地獄だっ...!!
まとめ
PlayではActionBuilderが提供されているので、良くも悪くもこの2パターンの実装に近いものに集約されていく気がします。
いろんな人のログイン処理実装とかを見てみたいですね〜
カッコいい実装ってどんな感じなんだろう??
JWTに格納しているIDとかを可逆に暗号化したりするところまで気をつけた方がいいものなんでしょうか??
悩ましいですね。結局URLにidなどのprimary keyって入ってくるので、そこまでする必要ってあるのかなぁ...って思います。
でもyoutubeとかってurlに入ってるID的なものが素直なprimary keyのままな感じがしないんですよね。
ということは、そもそもURLにスの状態のID入れるの自体が本当は好ましくなかったりするのでしょうか??
考えだすと悩みがつきませんよね...(´-ω-`)
Playの認証処理をいくつか作る part 1
本日の配信
久しぶりに平日夜間配信をしてみました。
いやぁ、音声の設定を間違えてますね。
ほんのりと後ろで私の地声が入ってますね。 LadioCastの設定をミスしている様子です。
仕方ないですね。ほとんど聞こえないくらいなので、スルーで(´-ω-`)
あと溜息とか着くと、純度70%おっさんになってるようです。
これはびっくりします
進捗と残タスク
今日はシンプルな認証機能を作成しました。
本当はUserRequestみたいなものを作って、認証が通った段階でUser情報を取得できるようにしたかったのですが、DBIOをどこにおくのかなどに悩んだの今回は別のアプローチ。
PlayのSessionはJWTになっているので、データ改竄を行うとsessionからデータが取得できなくなるようになっています。
なので、セッションのIDが正しく取れてくれば正規に発行されたセッションとして認証OKにしちゃう形で実装しました。
これはこれでいいんじゃないかなぁって思うのですが、どうでしょうかね?(´-ω-`)
細かいことを考えると、JWTをこちら側から廃止するような手段やJWTの鍵を定期的にupdateするような仕組みを実装した方がいいのでしょうけれど、そこまで対応していられないです...
※ するスキルがないとも言う
とはいえ、次回は認証時にUser情報をDBから持ってこれるようなパターンを実装してみようと思っています。
実装方針とイメージはあるので、数日でできると思います。
進捗
- ControllerDIを利用した認証ActionBuilderの実装
- 認証処理の動作検証とサンプル
残タスク
- 別パターンの認証実装
まとめ
理想型というのがどういう形なのかイメージがつかないので、いくつかパターンを実装してみて、様子見ですね。
認証系は実装が難しいというか、こだわることができるポイントが多いので、なかなか辛いところです。
個人で検証している分にはいろいろなやり方があって楽しいんですけどね。
あとはAtCoderの問題をちょっと解いたら、また明日ですね
6月のまとめ
最近の活動
6月も終わりました〜
早いもので、今年度の1/4が終わってしまいました
今年立てた目標に対して、みなさんいかがですか?
私は...
最近は非常にチョコチョコとAtCoderの練習をしていました。
平日に時間を取りづらくなってきている印象があるのですが、気のせいだと思います。
モチベーションが少し落ちてきているだけですね。
最近再びやる気が戻ってきたので、ここからです。
昔と大きく違うのはやる気がない時でも少しは学習をするようになってることでしょうか。
その結果、なかなか草が生えるようになりました。
ちょっとチート感はありますが、癖付をすることは一定の価値があるかなと思います。
配信
本日試しに配信を行ってみました!
BGMにさえ気をつければ、問題なく配信ができそうでした。
BGMはフリーサイトのものを利用しても、規約違反で落とされてしまったので、何か良い物を見つけるまでは苦しみそうです...
久しぶりのクリスティーナちゃんボイスですね。
むちゃくちゃ機械音ですね...
また、エアコンの風がマイクを直撃するためノイズキャンセラーを強めにかけている影響で、もそもそ喋ってる時の声が全然聞き取れなぁい!!
あとinput textで私の本名をサジェストするの勘弁していただきたい...
学習
ほとんどがAtCoderの過去問を解くことになっています。
最初はA, Bを高速で解く練習をしていましたが、最近はC, D問題をコツコツと解いています。
この2つを安定して回答できるようになると緑が見えてきそうですね。
全然見えてこないですね
読書が相変わらず苦手で全然すすみません。
読書嫌いです。
でも頑張ります。
まとめ
7月からはまた忙しくなりそうなのですが、技術力が大切になっていきそうなので、真剣に技術に向き合うことができたら嬉しいなぁと思っています。
Slick3.3系でMySQLの日付型をマッピングする実装 - 3パターン実装してみたよ -
本日の配信
Slick3.3とMySQLの日付型の戦い part2 - 兎にも角にも実装するよの巻 -
今日は昨日に引き続きslickとMySQLの日付型のマッピングを実装していました。
昨日候補に上げていた
1. def *
を自分で実装するパターン
2. MappedColumnTypeを利用するパターン
3. Profileを拡張するパターン
一応それぞれを実装して比較をすることまではできました〜
進捗と残タスク
進捗
- 各3種の実装比較
1-2の実装: Commit Log
3の実装: Commit Log
残タスク
- 実装サンプルの整理
- コンテンツへのインクルード
- 実際に今回採用する実装方法決め
結局のところどれがいいのか
通常の独自クラスについてはMappedColumTypeを利用するのが良いのでしょうが、今回の日付型に限ってはProfileを拡張する方法が一番良いと感じました。
今後ちゃんと記事にまとめようと思いますが、それぞれのメリット・デメリットを簡単に記載します。
ただし、あくまで私の実装した範囲においてなので、もっとよい実装方法があった場合にはこの限りではありません。
def *で対応するパターン
誰でも理解しやすくてシンプルな実装になります。
複雑なことをしていないので、何をしているのか一番理解しやすいと思います。
デメリットは今後追加される全てのテーブルの全ての日付型に対して律儀に対応しなければならないことです。
MappedColumnTypeのパターン
今回のケースでは一番旨味が少ない実装パターンになったと思います。
本来であればmapping処理を記載すると、特に自分で処理することなくデフォルトの型のように取り扱えるはずなのです。
はずなのですが、今回はこれを利用しても結局 def *
の実装や、各マッピング系処理での自前実装が必要になり、無駄にコード量が増え複雑度があがりました。
自分の使い方が間違っているんですかね...
なんか他の実装だと base[LocalDateTime, java.sql.timestamp]
みたいな実装も見かけるので、そのような形にするともう少しうまいこと実現できるのでしょうか??
でもLocalDateTimeはTEXT処理されてしまうので、結局汚くなってしまうのではという気がしています。
また、さらにしんどいのが def *
パターンと同じように結局マッピング周りに手を入れる必要が出てくるので全テーブルにコツコツ処理を書かないといけないです。
ここは今になって自信がなくなってきたので、いいやり方知ってる人がいたら教えて欲しいです。
Profile拡張
そもそも、これが公式で推奨されている実装方法です。
https://scala-slick.org/doc/3.3.1/upgrade.html#support-for-java.time-columns
The types are: Instant, LocalDate, LocalTime, LocalDateTime, OffsetTime, OffsetDateTime, and ZonedDateTime. If you need to customise these formats, you can by extending a Profile and overriding the appropriate methods
って、書いてあります。
今回必要なLocalDateTimeの部分だけ拡張してslickのprofileとして引き渡してあげれば、ちゃんと自分で実装したparse処理に従って日付処理をしてくれます。
なので、一回作れば他のモデルではprofileにこれを指定するだけで済みます。
初学者に対して「Profile作れ」っていうのは、結構ハードルが高いので初心者向けとは言いづらいのですが、Profile全体の説明をする必要もないので案外プログラミング経験者なら理解できるのではないでしょうか。
未経験だと、うん、しんどいとおもうけど。
というわけで、日付型に関してはこの実装方法が最適な気がしています。
ただ繰り返しになりますが、slick側でデフォルトで対応している型であり、一般的に利用される型だから、これが向いてるだけで自分で作ったクラスなどをいい感じに使う場合には通常MappedColumnTypeが良いと思われます。
まとめ
英語だからと面倒くさがってちゃんとドキュメントを読まないとこういうことになるのですね...
公式サイトにちゃんと書いてあるやないですか...
とはいえ、いや、万人にprofileを拡張しろって真顔でいうのは結構しんどい気がするんですよねぇ...
DBIOやデータアクセス周りはプロジェクトの技術強いマンがラッパー作ったり隠蔽することが多いとはいえ、slickというもの自体が相変わらず初心者にあまり優しくないなぁという思う今日のこの頃なのでした。
Slick3.3系でMySQLのLocalDateTimeをいい感じにしたかったけど、できなかった
本日の配信
Play-SlickでLocalDateTimeを何とかする part1 - どうにもならなかった -
本日は久しぶりに作業配信です。
slickの調整に入ったはいいが、相変わらずこの辺りは苦労しますね...
slick3.3からMySQLの日付関係の型がString受け取りになって、parse処理が雑なせいでそのままではエラーになってしまうという状態です。
このあたり、一体どういう利用され方を想定しているんですかね??
バグというと言い過ぎだかもしれませんが、バグと言っても差し支えないレベルなのでは...
進捗と残タスク
ある程度進捗は出たのですが、結局悩んだり検証したりで時間が浪費され...
slickってやっぱりしんどいのでは??
実装までのマッピングや準備もそうですが、どうやってファイルやクラス分けたらいいのか非常に悩んでしまいます
db.runもできれば隠蔽したいけど、いざとなれば自分で領域が切れるようにもしたい
隠蔽したりラップしたい箇所が多いんですよね、slickって
DBアクセスのレイヤーはそういうものという気もしますけどね
ほんとむずかしい
進捗
- slickを利用したサンプルのベース作成
- 次回以降のコンテンツ作成方針決定
残タスク
- LocalDateTimeとslick column typeのマッピング
- slick modelのいい感じのファイル分け
基本的には以下の3パターンを考えています。
- Stringで受け取ってmodelとのマッピングで処理
- implicitのSlick Column Mappingを作成する
- MySQLProfileを拡張して独自profileを作成する
最後のやつはやってみたのですが、なんかうまく動かなかったんですよね
何か悪いはずなんですが、何が悪かったんだろう??
まとめ
改めてSlick側の実装に入ったわけですが、安定のよくわからなさです
一番シンプルで簡単だけど、あまり見た感じ汚くないものといういいとこ取りができるのでしょうか
作れるだけの能力が私にあるのだろうか...
PlayFrameworkハンズオン作成 - lesson1をlesson2に繋げつつdocker化するよ。slickもくるよ -
本日の配信
土日は長々と作業していたので配信なし、日曜日はStorybookの検証をしていたので久しぶりの定期配信です。
休日はDBを使わないLesson1は一通り完成しコンテンツの整理と分割をしていました。
今日は全体的なディレクトリ構成の変更とlesson1で作成したコンテンツをlesson2で使えるようにセットアップをしていました。
思ったよりも大きな変更なくlesson2へ繋げられそうで、ホッとしましたよ〜
lesson2でDB接続までを行う予定なので、そこまで出来ればもうひと段落というところでしょう
とはいえ、Slickは手強い...
ここのところの進捗と残タスク
進捗
- lesson1のコンテンツ整理
- ディレクトリ構成の変更
- lesson2のseed作成
残タスク
- lesson2のseedを参考プロジェクトディレクトリへ移動
- ミリ秒以下の日時設定を秒までに修正
- ミリ秒以下の設定方法をおまけに移動
テーブル設計でミリ秒以下への対応をしたせいでSlickのmappingが大変になってしまっているので、それをおまけ側へ移動しようとおもいます。
秒までであれば、複雑なことをしなくても日付側に変換が効くのでまずはそこから始めようと思います。
まとめ
lesson1のリファクタリングという名のコンテンツ再確認と動作検証がしんどすぎてモチベーションが下がりそうだったので、続きを作成することにしましたが思ったよりも順調に進みそうなので無事にやる気が出てきました
とはいえ、lesson1をしっかりとしたコンテンツにする必要があるので、どこかで自分で通してみないといけませんね
いや、ほんとこういう資料作る人すごいと思います
絶対粗めっちゃありますもん私の...