比べて簡単に、また殆どの処理を型安全に書くことができるようになりました。利用して管理し、もしスキーマが変更されコードを書き直す必要が生じた場合は再生成後静的解析により警告が表示されるようになります。この移行は結構手間がかかりましたが、やって良かったです。DIを行なっていたために他のレイヤーのコードには一切手をつけることなく移行が完了したので、コードを丁寧に書いててよかったと思いました。するごとに呼び出し元の関数の情報を追加していったり独自のエラーコードを用いて発生したエラーによる条件分岐を可能にしたりしています。共にエラーとしてクライアント側に返却されます。独自エラー型はIsメソッドを持っておりerrors.Isの際にエラーコードが同じかどうかで比較をしています。エラーコード型はエラーコードの文字列を返すメソッドとステータスコードを返すメソッドを持っており、必ず403を返すerr403とエラーコードの文字列の組み合わせなどで表されています。呼び出し関数の取得はruntime.Callerから得られた文字列を/や.で区切っていじることで取得しており、もう少しきれいなやり方はないかと思いつつ動いてるのでまあいいかとそのままにしてあります。kin-openapi)oapi-codegenを利用しており、定義したAPIを自動でサーブするためのインターフェースを用意しパラメータを自動でパースしてくれたり返却する際JSONにMarshallするための構造体も自動で生成してくれるので大変助かりました。テストはkin-openapiのレスポンス検証を使っており、もし定義と異なるレスポンスが帰ってきた場合はテストが通らないので定義通りに実装されているかが確認できます。認証GoogleとAppleでのソーシャルログインに対応しています。外部の認証サーバーからトークンを受け取ってこっちのサーバー側で検証したらそのサービス固有のIDと一緒にユーザー登録してJWTを発行しています。このときJWTに所持している本の情報も入れているため以後アクセストークンが有効であればユーザーDBアクセスなしで検索可能*3となります。アクセストークンの有効期限は15分ほどで切れた場合はリフレッシュトークンを用いてリフレッシュすることが必要です。この際に外部サーバーのトークンが有効かどうか確認することでアプリの利用を停止されてないか確かめています。採用することにしました。実際に使ってみるとプラットフォーム間の差異を殆ど気にすることなく開発を行うことができ、ツールも充実しているためかなり満足度が高いです。エミュレータと同じものが動くことに大変驚きました。経験は1週間程でしたが、随分その経験が活きたように思います。書いて過ごしていたのですが、大学が始まってから全く触っていないので本当にこのレポジトリにあるものが全てです。Generationを用いています。中身はNotifierProviderとAsyncNotifierProviderで、特にAsyncNotifierが非同期処理を扱う際にはとても便利です。殆どのWidgetをStatelessにしてViewModelで一括でステートを保持しています。2.0に統一したいです。最初はMVVMっぽくだいたい全ての画面に対応するViewModelを用意していましたが、最近は無駄が多い気もしています。ルーティング用のProviderを用意したらVMは取っ払っちゃって今その一個下にあるレイヤーを画面から直接呼んじゃうのもありかなという気がしています。なるとGoでやってる階層構造とあんまり変わりませんね。(GetX)一番下のレイヤー、RepositoryのDIとルーティングにGetXを用いていますが、全てRiverpodに統一できるはずなので置き換えようかな〜と思いつつも特に困ったことがないためそのままになっています。見てるとちょっと評判悪いみたいです。置き換えて比べてみようと思います。dio)openapi-codegenでdioのコードを自動生成しており、通信部分は全く自力で書いていません。楽で定義を更新して再生成すると静的解析により対応が必要な部分がわかるのも大変良いです。情報が見つからなかったのが難点といえば難点でしょうか。Storageに保管しています。Flutter側でもトークンの情報を活用することは考えましたが、トークンの形式を変更するかもしれないことを考えてFlutter側では完全にノータッチで、仮にJWT以外に置き換えたとしてもフロント側のアプデは一切必要ないようにしています。トークン有効期限切れで403エラーが返ってきた際に時にdioのinterceptorで上の階層から見えないようにトークンをリフレッシュしてリトライする処理がちょっと難しかったです。リポジトリのディスカッションなどを参考に実装しました。(PostgreSQL)特に文句ありません。現在は基本的な機能しか使っていないので当然といえば当然ですが、これからpg_bigmを用いた類似度検索などを実装しようと思っているので、そこで高機能さにお世話になるかもしれません。DB設計なんてもちろん初めてだったので達人DBを読みました。日雇いのバイトに持ってって休憩中に読んでたら社員の人に褒められて、後でジュースとお菓子おごってもらいました。達人DBはめっちゃわかりやすくてかつ読みやすいので超オススメです。読んだことなかったら騙されたと思って買ってみてほしいです。(render.com)日本ではあまり知名度がないみたいですが、使いやすいPaaSです。友達が使ってたので使ってみたら本当に便利で離れられなくなりました。無料枠もあるので気軽に試せますし、GitHubのレポジトリを選択するだけでデプロイができます。previewというプルリクエスト毎にプレビュー版をデプロイしてくれる機能もあり、コミットがあれば自動でビルド・デプロイしてくれます。難点といえば日本サーバーがなくシンガポールサーバーを使わざるを得ない点ですが、そこまでレスポンスは悪くないので問題ないかなと思います。DBもこのサービス上にデプロイしていて、24時間毎の自動バックアップには助けられました。(GitHub)コードは基本GitHubで管理していました。途中まではバックエンドとフロントエンドで分けていましたが途中からリポジトリを合体させモノレポにしました。これは開発中に出てたハッカソンで友達が同じようにモノレポで収めていたのを参考にしてやったはずです。Issueを立ててバグの原因特定してそれがバックエンドでもフロントエンドでもブランチ切って同じリポジトリで対応できたり、ある時点でのフロントとバックのコードが簡単に取得できたりとメリットが多かったです。ブランチはリリース前は初期状態のmain、developと都度のfeatureブランチのみで、リリース時にreleaseブランチを切って調節した後にmainにマージしてmainブランチをrender.comでデプロイしました。flowのとおりに基本的にはやっていて、リリースバージョンごとのタグもつけいます。バグや機能追加毎にIssueを立ててブランチを作り、マイルストーン*4によって次に出すバージョンに含める機能を管理しています。依存性を分離することで複数のファイルを編集することをあまりせずに共同作業ができたので、フロントの見た目だけをいじる相方と裏のロジックをいじる自分でコンフリクトを多少避けることができたのも良い点でした。結局見た目のコードもかなり手を入れたので、コンフリクトしてたことも多々ありめんどくさかったです。今後やりたいことまずフロントのエラーハンドリングが適当なので改善したいです。valueを扱ってた結果例外をthrowするDartに慣れないままとりあえず動く状態にしてリリースになんとか間に合わせたという状況なので、全然エラーをうまくハンドルすることができていません。実際エラーが出ないことでストアのレビューに低評価が出てしまったので早急に対応したいところです。あとユーザーに関係ない部分になってしまいますが、管理画面を作ろうと思っています。サービスリリースして初日にユーザー数を確認しようとSQL叩いたら、ミスってDBのユーザーテーブルを全部飛ばしてしまったのでなるべく生で触りたくないです。機能の追加も随時やっていきます。今はリリースに必要な最低限の機能だけでリリースしているので、所持している本を確認したりより詳細な検索条件を設定したり、シラバスを参照できるようにしたり、記事を配信できるようにしたりとやりたいことはたくさんあります。あと忘れちゃいけないのが広告で、例えば早稲田通りでティッシュ配ってる企業なんかはこういう早稲田生しか使わないようなアプリに広告出したいんじゃないかな〜と思うのでうまく広告を取り入れて費用を回収していきたいですね*5。最後にアプリを使ってくれている人々、どうもありがとうございます。科目登録期間に旅行に行くことになってしまったが、アプリのおかげで旅行先に本を持っていかなくて良くなったという声や、弟・先輩の友達が実際に使っていたなどの話も聞けて大変嬉しく思っています。アプリ開発でしたが、無事にリリースできてまずは一安心です。設計からリリースまで全部やったのはとても良い経験になりましたし、めちゃくちゃ大変でしたがその分大きな自信に繋がりました。これからもアプリに限らず色々作って、色々やっていくので、応援よろしくお願いします。3はてなブログをはじめよう!takabayapさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。