#299 一機能を作り上げるまで 〜啓蒙活動〜

2024/11/10 ·

  • この番組は駆け出しエンジニアの順平と先輩エンジニアの海一 乗りが送る駆け出しエンジニアを中級エンジニアにキャリアアップさせるラジオです本日ですが イカリ いや違うな啓蒙活動です 本日啓蒙活動なんですがエンジニアの仕事でコーディングがあると思うんですけどことコーディングに関して



  • めっちゃ偏見を言うんですけど半分以上のエンジニアは作ってるものの構造を理解せずに元のものを参考にしてそれっぽく作ってるのではないかすいません半分以上すいません



  • 声明の半分以上なんか謝罪の声が聞こえるんですけど あれですねその世の中のエンジニアの声かもしれないですねそうなんだはい なので今日はバックエンド api をイメージしながら一つの機能 今日はじゃあ ec サイトの商品更新 api



  • 商品を更新するAPI商品情報を更新しますか商品情報を更新するストア側ってことですかねAmazonとかに出展してるお店側の気持ちになる感じですかねそうですねユーザーはユーザーはをイメージしつつどういう風にコードを書いていくかっていうのをポッドキャストでに載せるとなるほどねどういう話をしたいかっていうと多分実際にコーディングするときって



  • フレームワークにはもちろんよるかもしれないですけどAPIってだいたいコントローラーが最初に受け取るんですよルート通るって言ってもるんですけどルート通ってコントローラーに命令が言ってコントローラーが呼び出されてコントローラーで全部処理返すわけじゃないじゃないですかコントローラーで全部書くわけじゃないじゃないですかできなくはないけどやんないですよねじゃあ



  • どういう処理をどういうフォルダのどんなファイルにおいてとかクラスどう分けて実装していくと保守性の高いソフトウェアが書けるかなという話をちょっとしていきたいですクリーンコードってことですねクリーンコードってその辺の話ありますかねちょっと前すぎて記憶にないんですけど



  • あったような気がしますよあったような気がしますか結構なんかオブジェクトごとに分けて責務分けるみたいな話いっぱいあった気がするそうか確かに単一責務みたいなことかはいちょっとその辺の話をはいしてまあ多分のりさんも僕もじゅんぺいも言うほど違うと思うんでお互いの学びになればなってなるほどいう感じですではいどこから切り込んでいこうかなっていうのはすごい



  • 前どころなんですけどじゃあじゅんぺいをオペレーターじゃねえやパイロットとして我々がオペレーターでモブプロしていくイメージですかそうですねやんやんやんや言っててきぎのりさんと僕でやんやんしつつじゃあ一歩目も想像すかねあんまりまず何するのか僕も言ったんですけどね最初に確かにちなみにじゅんぺい使ってるフレームワークは普段何ですか普段使ってるのは直近だとアクシオス



  • それはフロントエンドのクライアントのライブラリーですねそれによって叩かれる側がAPIとなりますなるほどそうですよねクライアントですよねHPT直近そうするとマジで1年以上前からじゃあフロントエンドエンジニアじゃん本当だとなると順平に振るのも難しくなってきますね確かにとはいえじゃあ順平難しいな確かにそうすると順平



  • パイロットにするのむずいな一回やってみるよ確かにイマジンでいけますよねいける気がするまずどうする雑な投げ方するんですけどまずは関数を作ろうと思って作ろうと思っていたら怖いなこれ怖いよねすごい怖いなこれどうやったらじゅんぺいの学びになる感じで進められますかね



  • 僕とのりさんでポンポン進めていくとたぶんじゅんぺいが置いてけぼり食らうじゃないですかたしかにじゅんぺいアキシオスから叩くときはどんな情報が必要ですかこういう情報を渡したいみたいな情報を書いてそれを渡す関数を作るパラメータってことですかはい大事なのが3つあると思うんですよねパラメータ



  • エンドポイントエンドポイントで言えば1個にまとまってるここに投げるよっていうURLではないですよねURLって言い方で合ってます?URLとそのパラメーターとゲットとかポストとかI say yesYou say yes



  • I say yesその3つが必要ですねとじゃあそこからバックエンド時代覚えてるかなんですけどそういうのを作るには何に何を書きますかそういうのを作るのはそこに送れるようにするためには何を書く必要がありますかねじゃあじゅんぺいがわからなかったら質問してくださいおそらくコントローラーにメソッドだから今回でいうとECサイトの



  • 更新なんで違うわ詳細の更新パッチ?パッチにしておきます?パッチなので僕が普段使ってるファストAPIとかだとデコレーターつってアットマークパッチなんとかみたいな感じでこのメソッドの時にこの関数呼ばれるよみたいなのをコントローラーに書きますねコントローラーに書くのかなコントローラー



  • だよないやごめん俺ねファストAPIはそんな詳しくないんであれなんですけどちなみにコントローラーと呼ばれるものはないですエンドポイント一番上にいるんでコントローラーと思ってましたルーターからコントローラー呼ばれますよねだってファストAPI僕が今触ってるディレクトリ構造だとないんでそれがエンドポイントのコントローラーあれがルーター



  • 通常大体のMVCフレームワークってルーティングするファイルとコントローラーがあってルーティングするところにこのメソッドでこのパスのリクエストが飛んできたらこのコントローラーのこのメソッドを呼び出すよみたいな指定してコントローラーに処理を移情してると思うんですけどFastAPIはそれが一体になってるなってますね一旦そこは本質じゃないので置いといて第一階層ですねだから処理第一階層



  • まずは空っぽだけどとりあえずエンドポイントを作ると第一階層がコントローラー的なとこそうですねコントローラーで何をしていくかですよねコントローラーってもう処理受け取って下に丸投げして返すとこじゃないですかエラーはハンドリングするだいたい5行とかなイメージですよね



  • そうですね今回の場合だとこういう風な情報に変更したいよっていうのが送られてくるんでまずは入力値のバリデーションしますかねそうですね確かにバリデーションは本当にフレームワークによるんでしょうけど多分バリデーションのメソッド呼ばなきゃいけないやつもいるしなんならそのフレームワークが勝手にやってくれるパターンもありますね多分あの型指定でリクエストのパラメーターを型指定で指定しとけば多分その



  • メソッドが呼ばれたときに勝手にバリデーションチェックしてバリデーションエラー返してくれるやつもいそうですねそうね確かにバリデーションチェックして下に投げるここまでですよね下に投げるときコントローラーから呼び出されるのは



  • 何ですかっていうのはサービス層なんですかねプロジェクトにもよると思うんですけどそういう今の僕のプロジェクトならそうしますねそうですよね一般的にもだいたいそんな感じですよね多分コントローラーからサービス層が呼ばれますサービス層はそうですねサービスだからコントローラーの名前はだいたいメソッドとエンティティじゃなくてエンティティ名っていうんですかだからパッチ



  • 商品アイテムズ違う商品ってなんだアイテムズアイテムズ1個なんでパッチアイテムですねパッチアイテムメソッドが呼ばれてそっからサービス層のパッチアイテムサービスに受け取ったパラメーター丸投げしますどうしようこれこの辺の設計こういうのあるけどどうなのみたいなやつ差し込んでいっていいですかコントローラーでえーと



  • 結構流派あるかなと思っててありそうコントローラー書くじゃないですか例えばアイテムコントローラー今回だったらアイテムに関するやつなんでその中に例えばアイテムって別に更新以外の処理もあるじゃないですか削除とか追加とかあとは取得もあるかだいたいクラットがあると思うんですけど



  • 1個のアイテムっていうコントローラーの中でクラットを作るのか一方シングルアクションコントローラーみたいな感じでそのコントローラーにワンメソッド書くのかみたいなあるじゃないですか僕あれシングルアクションコントローラーのメリット分かんないんですよね分かります分かります僕は携わってるプロジェクトはシングルアクションコントローラーじゃないんですけど



  • なんかあるとしたらコンフリクトしないとかなんじゃないですか一つのコントローラーファイルを同時にだからゲットとプット同時に作るとかあるのかなゲットとポスト同時に作った時にコンフリクトもねガッチャンコするだけなんですけどコンフリクトしないとかそんぐらいじゃないあと今ちょっと思ったのはサービス層をめちゃくちゃちゃんと分けてれば分ける意味あるのかなぜえーと



  • これ全体設計の話になるんですけどサービス層が結構テーブルに引っ張られてるアプリケーションよく見るんですよねと言いますとほぼデータベースのテーブルの数と同じだけサービスがあるみたいなそれに関連する処理が中に書かれててだいたいモデルと同じじゃんみたいな状況になるみたいなっていうのが結構あるあるあるかなと思っててその状態だとコントローラーをシングルアクションにしてもどうせ全部の



  • 別々に作ったコントローラーの中で同じインスタンス作らなきゃいけないから同じようなコードが増えてめんどくさいのかなと思ったんですけど一方サービスがちゃんと適切な単位に分かれてサービスも細かく分かれていればより小さいオブジェクトだけで全部完結していくのかなってのはちょっとなるほどなるほどなるほどなまあそうですねとはいえどっちでもいいっちゃうどっちでもいいというかどっちでもいいなあ



  • インスタンスの大きさでパフォーマンスに影響を出ることってそんなないじゃないですかよっぽどじゃないですかよっぽど好みですね多分でも厳格にやるんだったらシングルの方がいいかもしれないですねパフォーマンスめっちゃ求められるとかなるほどなっていうのがコントローラーの話ですいませんいきなりミクロの話からマクロの話になるんですけど全体としてどういう構造になるかですね



  • 全体としてまず層の話層とは別なんですけどバックエンドAPIのフレームワークだいたいルートがいてルートは受け取ったやつどこに振り分けるか決めるやつその後ろにコントローラーくんがいてコントローラーくんは受け取ったやつを返すやつ受け取って下に投げてPMみたいなやつ



  • その下がサービス層これはビジネスロジックいわゆる例えば金利とか商品でいうと商品の料金を設定しましたただその料金ってECサイトの手数料入ってないんでECサイトの手数料を乗っけた料金にしてくれますみたいなビジネスロジックとかを持つの



  • もうサービス層ですかじゃないかなあと例えばECサイトだと商品いろんなの扱ってるんでこのタイプの商品にはこういうルールが適用されるみたいなのありそうな気がするじゃあお酒だったら20歳未満のユーザーに見せないみたいなそうそうそうそうそうそういうフラグを判定してデータベースに入れるみたいなねそうそうそうそうありそうありそうっていうのがサービス層あとはデータベースと直接やり取りしないんですよサービス層って



  • データベースをやり取りするときはデータベースをやり取りするクライアントを使ってやり取りするんですけどそのクライアントの中身例えばセッション作ったりとかログイン情報を持たせて直接やり取りしてとかあと処理途中で失敗したときに切り戻しさせるみたいな細かいロジックはサービス層が持たなくてそれを持たせる



  • データリンクっていうのインフラ層とか呼ばれるかなインフラ層データベースもだし他のシステムのAPIタタッククライアントとかも含まれるんですかね例えば商品の画像ファイルS3に上げてますとかだったらねS3のクライアントを持つのはインフラ層そんなもんかなですよね今言った



  • ルーター君とコントローラー層コントローラーとサービス層イングラ層っていうイメージでお話ししますはい今コントローラーがサービス層にぶん投げるって話までいきましたサービス層どうしますかですよ今すんごい多いですよやること多分そうですねアップデート



  • 要はやることはデータを更新したいんですよねあとは設定足しちゃったけどフラグ追加追加はしないか商品変わんないからね料金変えた時の送料の計算とかしないか送料は出店側が設定するだけだからロジック何かしら手数料かやっぱ手数料の計算とか入れますか手数料は



  • 商品に保存するっていうよりは商品の状態によって決まるってことですか出品者が設定した値段にECサイトのマージンを乗っけてユーザーに表示する設定にしましょうそうしたらビジネスロジックが必要になってくるんで伝わってる?あれでもそれ更新の時に何か関係あるのかお金が100円値上げしたらその値上げしたお金から



  • 手数料じゃないなマージン計算してユーザーに出す金額変える必要がありますね表示する料金も保存されるんだはいそのイメージですね確かにでもそうすると手数料のパーセンテージが変わったタイミングでDB一気に更新しなきゃいけなくなってくそ設計ですね確かに変なこだわり捨てようかななんかないですかなんか保存するときのやつ欲しいよね欲しい



  • 一旦なかったことにしましょうか将来そういうのが追加されることを想定して考えましょう例えばですけど値段を変更するときにすでにお気に入りリストに登録しているユーザーがいたら通知を送るみたいな値段変わったよみたいな欲しいものリストみたいなね天才ですね思いついちゃった今それを入れるとしてサービス層君何しなきゃいけないかで言うとえー



  • DBクライアント作ってあとは順番とか関係なしにあとはDBクライアントでデータ更新します更新したらその通知をするただ値段が変更したかどうかをチェックしなきゃいけないんで最初に更新する前に取得して今回の送られてきた値と比較して値段に差分があるかをチェックしなきゃいけないですねいいですねいいですねいいですね



  • じゃあ今の話だと値段チェック更新通知の大きく3ステップがあるんですねここからが僕面白いポイントだと思っててサービス総組で呼び出されたメソッドでその処理を書くわけなんですけどある程度抽象化しなきゃいけないじゃないですかどの部分を例えば値段じゃないな



  • 値段の変更を判定する実際のコードってサービス層のそのメソッドには書かないじゃないですかサービス層のメソッドって今言った処理全部書くわけじゃなくて



  • インフラ層に書くコードもあるかもしれないしっていう意味で確かに抽象化して書く必要があるんですよね思った時にどこまでを今呼び出しているサービスメソッドにサービスメソッド君に書きますかっていうそういうことねそれで言うと今設計判断いくつかあるかなと思ってて例えば値段



  • なんでもないわなんでもないですねでもただ書き用というか結構これ現場ではやってる可能性あるんじゃないかなっていうのでまず一個あるのは例えばコントローラーで一回その取得メソッドを呼びますで一件取ってきますその中でチェックして通知みたいなメソッドを次サービス呼び出しますはい



  • そのワンセットの中にアップデートっていうメソッドも呼び出してるみたいなケースもあればそもそも更新するのとこの通知を送るのはセットでやらないと意味ないからってことでアップデートみたいなサービスに作ったメソッドの中でさらにプライベートメソッドとして呼び出すのかみたいなめっちゃいい話してるそういう切り分けあるじゃないですかありますねじゅんぺんくんならどっちにする?



  • 早口だな僕は聞いた感じ後者の方するかもしれないなるほどねいい話しますねのりさんよだれじゅるじゅるですよよだじゅるよだじゅるよだじゅるよなこれ僕前者派なんですよねそうなんだ割とそういう風に層を分けてるじゃないですかでえーっと



  • 一足飛びに呼び出したくない気持ちになってるんですよねさっきの通知みたいなやつって他の機能でも使われると思ってて値段変わった時に通知することもあるかもしれないし消費なくなった時にも通知するかもしれないしみたいな他の呼び出し元ってきっとコントローラーっていうよりはサービスになる気がしてて



  • 例えばデリートのサービス層君が呼び出す層だから階層的にはサービス層のクラスのプライベートメソッドないし僕はもっと言うとそういうのはヘルパーとかユーティルみたいなよぼ山ツールフォルダみたいなとこに入れちゃうかもしれないですねなるほどね実際にその通知を送るための例えばAWSだったらSNSの



  • AWSクライアント多分作って送るのかなと思うんですけどクライアントはインフラ層になるかもしれないですけどクライアントを使ってメッセージ送るメソッドみたいなのはそういうよもやまフォルダに入っちゃうなるほどでも逆にコントローラーに入れ込む意図とか知りたいです俺もあちなみにじゅんぺどういう意図で言ってたりしてましたじゅんぺ校舎って言ってたからサービスにまとめる



  • サービスの中で呼び出す方ですね じゃあごめん同じことを詳しく聞いただけなんですねすいません 多分コントローラーに入れる人の気持ちはちょっとわかっててまずサービス呼び出すだけなのが気持ち悪いと思ってるはずなんですよこれ何これ右から左に受け流してるだけじゃんみたいなだったらそのコントローラーを見て何の情報も得られないよりはちょっとやってることがわかる



  • だからさっきのりさんが言ったバリデーションかけて一見取ってきてそれの値段の差分見て更新して通知送るってやってた方が何やってるか分かるみたいなっていう言い分は全然そういう意図なんだろうなって思いますうん



  • けどそういうのじゃないとは思っているそうねあとなんかどっちでもできちゃうからなんか最初にパッと思いついた方でそのままやっちゃうだけみたいなのも全然あると思いますねちなみになんで分けた方がいいんでしょうねそれで言うとね個人的には使い回すあーてか



  • それぞれのレイヤーの役割みたいなところで僕なんとなくあるのはコントローラーはまず入力値の受け取りとそれに基づいて各種処理の呼び出しとあとは何を返すかこの3つを決めてるみたいなじゃあ本当にエンドポイントって



  • 入り口入り口を司る確かに何を受け取るかとか何を返すかっていう情報だけでもまあまああるじゃないですか情報量としてそこだけ見たい人に向けて存在している人確かに確かに



  • だから例えばエラーエラーはでも他のメソッドと使えますから抽象化しているかもしれないけどエラーも返すよっていうのが書いてたりするんですよねそうそうそうそうなんか起きたらエラー返すよみたいなサービスは純粋なビジネスロジックいわゆる最初に言った何やって何やってみたいなそうそうそうで



  • インフラ層はデータの保存とかじゃないですかロジックって2パターンあると思っててアプリケーション都合のロジックとビジネス都合のロジックがあると思うんですよコントローラーとインフラ層はアプリケーションの都合を書いてビジネス層はアプリケーションの都合に関係ない方がいいなと思ってるんですねちなみに今言ってるアプリケーション都合とビジネス都合って具体的に何と同じみたいなイメージですか例えばさっきのなんだっけ



  • 商品の値段が変わったら通知するみたいなやつってリアルのビジネスであってもいいじゃないですか



  • 例えばこのお客さんこれ欲しがってたなみたいな情報があったらネットのない時代とかだったらもしかしたらお手紙出してたかもしれないじゃないですかっていうのが要はビジネスロジックだと思うんですねなるほど企画の人がこうやってほしいんだよねっていうことがビジネス都合アプリケーションのロジックは例えばさっきのインフラ層だったらデータベースに保存するみたいなデータベースって言ってる時点でアプリケーションっていう



  • あとあれですね企画の人は保存して取り出せるようにしてねって言ってるけどそのためには多分データベースのIDとパスワードを持ってなきゃいけなくてそれを使ってデータベースと通信するためのロジックを書かなきゃいけないみたいな企画の人がやりたいって言ってることをやるために必要な手続きみたいなイメージなんですかねだと思います



  • ビジネス都合がサービス層でアプリケーション都合がインフラ層とコントローラー分かったそうね結構この辺ありがちかつ判断むずいなって気もするんですけど例えばログインしてるかどうかのチェック



  • 今回だったら商品情報変更じゃないですかその商品出してるお店以外がやれたらおしまいじゃないですかってなった時にその本人なのみたいなチェックはどこでするのかとかそういうのって今その話していいですか多分大元じゃない最初最初の最初ですよね



  • であの恥ずかしながらここ数年コグニート使ってるしかないんで自前の認証認可なんてやってないんですけどマジででもそのイメージだとなんかどうやってやっちゃったっけなメソッド呼び出される前に自動でなんかやってくれてたりするんですかいやーメソッドというかコントローラー呼び出される前段階ぐらいであーはいはいえーっとあーでも何と何称号してんだろうな



  • バリデーションチェックみたいなぐらいのスピード感段階でそういうセッションというか本人だよねみたいなのって認証認可かいわゆるやるもんなんですよねでそのロジックどこで書くかそのロジックはやっぱおそらくセッションストレージにアクセスしに行くんでそれはインフラ層に書いててでそれをその前の



  • 確認かでも確認するのは多分サービス層にいるんじゃないですかね汎用的なクラスみたいなのが今の話だと確かに本人確認はビジネス都合な気がするそうだよねでもよく考えたら僕これ結構コントローラーとかあと普通にララベル使ってるとミドルウェアっていうコントローラーよりちょっと前にやるんですけどはいちょっと前に処理するやつはいはい



  • だからそれを今話しててあれこれもしかしてビジネス都合かって思い始めて混乱してたそんな綺麗に分け分けできないのはありそうですよねでも一応やるとしても例えば今回だったらうーんと



  • 必要なのって本人かどうかじゃないですかでも実際ID必要なときあるじゃないですかそれは人のIDですか商品IDですか例えばユーザーの情報を変更するんだったらユーザーのID今回も必要か本人かは必要ですね



  • 管理者かアイテムの所有者かララベルとかだとオースっていうライブラリというかフレームワーク組み込みの機能があってどっからでも呼べちゃうんですよどっからでも呼べるんですねなのでたまに見かけるのがサービスで呼んでるみたいな処理する直前ですねデータベースの処理入る直前のサービス層で呼んでるってことですねでも



  • それってセッション関係あるからあんまサービスで呼ぶっていうよりはコントローラでも入力地としてIDを取り出して引数で渡してほしいなってめっちゃ思うんですよねサービス層に引数で渡してほしいそうですそうですアップデートみたいなメソッド呼ぶときに引数でIDみたいな形で渡してほしいうんうん



  • そのIDの取得をサービス層の中で直接オースからやらないでほしいっていうのをめっちゃ思っててなんでそうしないといけないかっていうところでセッションってめっちゃHTTP都合じゃないですか都合来ましたまたアプリケーション都合ビジネス都合に続くHTTP都合セッションってHTTPの文脈じゃないと存在しないじゃないですか



  • はいはいはいってことはもしかしたら商品情報をHTTP経由API経由じゃなくてなんかバッチ処理で変える可能性もあるじゃないですかと言いますとまあなんか分かんないですけどえーと



  • この店舗は会員ランクアップしてるんで情報を変えますみたいなのがあったときに夜間のバッチョリとかでやるとするじゃないですかそのときってターミナルから呼ばれるんでセッションないじゃないですかってなると更新のロジック本当は使えるはずなのに



  • あのセッションにアクセスしちゃってるせいでそのサービスがせっかくのビジネスロジックなのに使い回せないってことが起きるんですね素晴らしい話してます素晴らしい話してますかなのでそういうのを書かないでほしいっていうのをすごい思ってるんですけどでもやっぱコード見るといっぱいそういうのやってるんですよねララベルあるあるだと思うんですけどちなみに逆張りするんですけどそういうバッチ処理をするときって



  • バックエンドAPI使うんですかねスクリプトとしてそういうことかDBを叩くバッジのスクリプト書いたりする可能性もあるじゃないですかそっちの方がイメージ多そうな気もするんですけどなるほどララベルの場合フレームワークでコマンド生成しやすいようになってるんでそうなんだあんまり運用であんまり僕がそういうバッジ処理をする経験がなかったんでシンプルに無知で



  • 言ってるんですけどなるほどなそういうの想定してるんだなインフラ的な都合でバッチリ回してるとき負荷上がっちゃうから別のインスタンス立ててるみたいなのは分けてますけどリポジトリ自体は同じで結構使うんじゃないかなララベルのプロジェクトだとなるほど独自でコマンド作れる



  • 話は戻りに戻ってオースはコントローラーでやれよっていうねなぜならセッションにアクセスしてるしセッションにアクセスしてるロジックをサービス層に持ってくとhttpと関係ないロジックで使い回したいときに使い回せないからわかるっていうめっちゃわかるこれがアプリケーションとビジネスロジックをちゃんと分けましょうねっていうメリットだと思うんですよね本当にビジネスロジックアプリケーションビジネスロジックっていうワードいっぱい出てきますけど



  • なんて言うんでしょう世の中のビジネスロジックと違う意味で使われてるじゃないですかそうあとビジネスロジックっていう言葉1年目の時から聞いてたけど



  • どこ?みたいなどれがビジネスロジックでどれがアプリケーションのロジックなの?みたいなのがめっちゃ分かんなかった最初分かんない分かりづらいだからそれがちょっと理解が深まる話ができてよかったですアプリケーション都合でもう一個いいですかインフラ層も混ぜるなって思うんですけど例えばさっき言った商品情報商品情報はDBに保存するじゃないですか画像はS3にアップするじゃないですか



  • っていう時にそれを意識どこに保存するかをサービス層で意識してほしくないんですよ例えばアップロードto S3みたいなメソッド名になっちゃってるみたいな出ました警察来ますよそれはガサ入れ入った時にこれはなんでダメかっていうとS3はアプリケーション都合だからです



  • どういうことですか会社の都合でアップロードする場所をS3ちょっとS3めっちゃいいサービスなんですけどAWS喧嘩したんでダメですとAWSできになりましたGCPに移行しなきゃいけないみたいなGCPの何に変わるのか分からないんですけどちょっと別の画像ストレージ使わなきゃみたいなってなった時に



  • じゃあそのメソッド名って変えるの?みたいなめっちゃめんどくないですか?めっちゃめんどいですねしかも今一機能だと思ってるでしょ?違いますよアプリケーション全部ですよありとあらゆるところにありますよセーブトゥエススリーがあるんですよなるほどそんな人間がいる仕事じゃないそうそうこれきついみたいなってなるじゃないですかなのでまず名前で漏洩させてはいけない



  • それはデータベースも同じで商品情報を保存するのをセーブトゥDBとか書く人いないと思うんですけどもしそうやってしまうとRDBかRDBってやってたけどでも商品情報って商品によって結構絡む違って塗るの値がめっちゃ出たりとかRDBじゃ効率よくないからドキュメント型に変えましょうかみたいな感じで文言を使いますってなった時に



  • じゃあまたそれをメソッド名変えるんかいみたいなそういう問題が出てくるんでなるべくそこに匂わせを入れちゃいけないなんか見た気がするすごい見た記憶がある匂わせちゃいけないと思うんですよそこそれはもうインフラ層に保存するよっていう名前のメソッドだけ作って投げて今回だったら更新か更新するよっていう名前のメソッドだけつけてあげて



  • どこに保存するとかそういう匂わせは一切名前から見せないっていうふうに分けたいなって啓蒙したかったですありがとうございますナイス啓蒙じゃあちょっと戻っていいですか戻るとサービス層で処理としては



  • 既存の値段取ってきて値段の変化があるか確認してDBに入れて通知するっていう流れになると思うんですけど既存のものを取ってくるこれはサービス層の最初のメソッドにどこまで書きますかどうなるんですか取ってくる一件取ってくるみたいな



  • 呼び出し方になるんですかねかなぁまあそうですよまあそれをインフラ層に投げちゃいますかねそうですよねインフラ層に投げるでレスポンスとしてその一件取った情報がまるっと入ったオブジェクトがなんかが返ってくるとでそのオブジェクトを次値段変わったメソッドに投げるとそうねはいでその値段変わったメソッドどこに置きますかじゅんぺいくんはどこに置きますか



  • サービスクラス今のサービスクラス同じですね僕実は値段変わった僕が今引っかかってるのは他のクラスで使えますことあるのかなってちょっと思ってユーティルとかに入れるかもって話ですかそうそうそうそう例えばですよ商品とは違ってふるさと納税商品テーブルがあるかもしれないじゃないですかはい



  • それでも使い回せるのかな使い回せるとかわかんないですけどそういうケースがある場合はサービス層のクラスには入れないで



  • 便利メソッドフォルダに入れちゃうかもしれない便利メソッド系もまたあれなんですよねそれちょっと厄介なんですよね僕の中でも厄介今臭いものに蓋をしている状態僕相当なことないとコモンとかユーティルは作らないですねそうなんですね今回だったら値段比較じゃないですかプライスコンペアラーみたいなの作っちゃうかもしれないですねサービス層に



  • もし使いますってなったらなるほどサービス層に入れるんですねなるほどなでもそこまでやるかないややんないなクラスは作んないかもでも今回は作んないけどそういうのもやるケースがあるってことですねちなみにそうなるとフォルダの構成として多分サービスレイヤーフォルダ名は分かんないけどそういうフォルダの中に今は多分



  • エンティティごとにファイル並ぶと思うんですけどそういうプライスコンペアラー今回作らないと言ってましたけどそういうのができる場合はエンティティ名だけ並んでるファイル名プラスそういう都度呼ぶファイルみたいなのがサービスのフォルダの中に並ぶみたいなイメージですかもう一回いいですかサービス層のクラスが入っているファイルってサービスのフォルダの中に



  • 入りがポンポンポンって入るイメージをしてますでそのサービスフォルダの中にはコントローラーから呼ばれるサービス君とサービスから呼ばれるサービス君がどっちも入ったフォルダになるみたいなイメージなんですかねなっちゃうねそこそこってどうなんですかね僕今やってるプロジェクトだと分けててで今はそうなってるから感性でそれがいいなと思ってるだけかもしれないんですけどどうあるべきなんですかね聞いてる感じいい



  • どっちが分けるの分けた方が良さそうですよね分かりやすいって僕思っててそれゆえコンペアラそうだなヘルパーというかユーティリになっちゃうんですけどなるほどねサービス層から呼び出されるサービス層に使い回されるやつはそういうとこに行っちゃうなるほどちなみにちょっとこれありかどうかあれなんですけどもしかすると



  • 商品を表現するオブジェクトにメソッドを生やすのももしかしたらありかもと思うそれはありかもしれないですねどうなんですかね要はモデルモデルの中に引数だけ渡して



  • 新しい値段を渡すようにしますとモデルってだいたい過去の1件持ってきた場合は値段持ってるじゃないですか自身のモデルと比較して変更があったかどうかだけを通知するメソッドをモデルみたいなやつに生やすのもありかもっていう今回のユースケースだとそれで良さそうですよね結局だって1件取ってきた時に返ってくるオブジェクトって商品クラスじゃないですかで



  • 多分値段更新メソッドで値段更新メソッドなのかな更新メソッドで更新した時のなんていうんだろうな結局だからモデルのクラスに対する処理なんでそこに持たせるのは今回はありですねそうじゃない時どうしようくらいですかねでも実は商品クラスかサービスのクラスのどっちかに当てはまる例が9割5分だよねちゃんと考えればかもしれないですけどね僕は今



  • 追い出してますけどなるほどなるほどでも追い出したくない気持ちはずっと持ってますよあと



  • あとこういうのを考えるときにさじゃあどこまで重複許容するか問題というかありますね例えばさっきの商品とふるさと納税で分けるかもしれないじゃんっていうのはあってそうなった場合2個書く必要あるんですけどでもそんなにめっちゃ変更される可能性もないなっていうロジックじゃないですか値段比較ってそうですね値段の概念が世の中から変わったら変わるんですけどなんなら数字の概念が変わったらぐらいかもしれないですねそうそうそうそう



  • っていうのはあるんですがおそらく変更はあんまり見込まれないし大したロジックでもないから別に重複して存在してても問題にならないのではっていうのであえて2個書いてもいいかも確かに普通に両方のサービスにそれはそうかもいいですねそれはいい確かにな2個ないし3個とか4個になるかもしれないけど例えばお店のランクごとにいやないか



  • 他のユースケース思いつかないですけどなるほどなでもその辺を適宜判断しながら置き場所を考えるとかなでもじゃあサービス層に戻ってサービス層では最初データ一件取ってこーいってインフラ層に投げるやつで取ってきたやつに対して値段比較してくれって投げるやつ次データベースの更新ですねこれも多分通知が飛んでるかな更新してから通知じゃないですかあーそっか



  • ですよねだって更新失敗するかもしれないですよねなるほどね確かに更新します更新も更新してくれって投げるやつ通知してくれって投げるやつって流れになるんですけど一旦更新に戻って最初の一件取ってくるとこ飛ばしちゃったんでデータベースに更新投げるとこってインフラ層どうなりますか引数としてどんな値を渡す感じになりますかねっていうので



  • シンプルにID投げるかなあと更新なんで更新内容入れなきゃいけないですね取得のとこじゃなくて更新で一回取得とこしちゃったんで取得は一緒多分サービス層でインフラ層だからデータベースクライアントをインスタンス作るじゃないですかインスタンスサービスクラス作るときに



  • インストラクター?コンストラクターコンストラクターにDBのクライアントを持たせるんですかねインフラ層のインスタンスは持たせるかなインフラ層のインスタンス持たせるんですよねサービス層からインフラ層のインスタンスDBクライアントのアップデートアップデートか



  • 多分MySQLとかRDSだとアップデートですねアップデートメソッドに対して更新後のアイテムインスタンスをぶん投げる呼び出し方ですねインフラ層のコード行くと多分そのデータベースクライアントはコンストラクター



  • コンストラクターじゃなくてイニットのメソッドっていうんですかインスタンス作られた時に呼び出されるやつコンストラクターコンストラクターの中でIDとかパスワードを読み込んで通信できる状態のクライアントを準備しておいてっていう処理が書かれてあとは各ゲットなのかフェッチなのかアップデートなのかデリートなのか各メソッドでDBに対して



  • この命令するもらったやつでっていう書類を書いていくみたいなイメージですよね書いていきますねこれはもう全部DBクライアントのクラスの中で完結してるしてるもう他のとこの何か読んだりも多分しないはいでサービスを戻ってはいでDBのアップデート終わりましたはい次通知そうだね通知も同じくインフラ層のコードでやるいや通知はね怪しいところがあるよねなるほど



  • 通知って何にするんだろうな 多分何かしらのクライアントがあってそのクライアントにメッセージ分投げてそれを送ってくれるんですよねきっとただここで難しいのは通知用のサービスを作った方がいいかなと思っててそれは確かにそういうのもどこに置くんだ問題あるんですよね



  • なるほど何点でしょうさっきのレイヤー分けで言うとサービス層なんですけどフォルダ分けとしてさっき言ったようにサービスフォルダに入れてるとコントローラーから呼ばれるやつと別のサービスから呼ばれるやつにごっちゃになっちゃうんで確かにだからサービス層といえどもコントローラーから呼ばれるやつと他のサービスに使い回されるやつは



  • 分けたい分けたいはユーティリズでもないそれはもうてかそっかそれがないからカオスになるのかはいって思っててなるほどねでもここからはあのローカルルールなんですけどコアとかうんうんうんインターナルインターナルとかそういうのがいますはいはいはいサービスから呼ばれるやつうん



  • そこから通知クライアントを呼び出して送るみたいな作りにするのが僕個人としては今いいと思っているそうですねいいわそれ分けるのいいサービスをでもそうなりますよね多分ねそうね多分通知の中で今回の場合だったらどこに通知するかみたいなロジックは必要かなと思ってて確かに商品



  • 情報変更の場合だったら例えばアプリのプッシュ通知とメールの2パターンで通知するみたいなのでその判断だけはサービス層でやって実際に送るのがインフラ層でやるみたいな感じになるかなその判断をするのも多分だからさっき言ったサービス層だけどサービスフォルダじゃないところに入ったロジックでやるんでしょうねインターナルと言いますかインターナルにとりあえず一旦



  • しかもそのロジック面倒くさいですね多分ねユーザー全部引っ張っていくのかなまあその条件かこの商品をレコメンドしているユーザーボンリスト引っ張ってきてそうだねなおかつなんか通知希望してるかみたいなそうだね通知希望してるかもあるしあとはそのユーザーによってアプリないこととかあると思うからその辺の出し分けとかメッセージ作るところも結構複雑になると思うんですよね



  • メールとプッシュ通知って絶対同じ内容じゃないじゃないですか共通はあるとしてメールだったらメールのボディ必要だし本当にそうですねコンテンツとしては別かもしれないですねインフラ層でやってそうですけどね本当に本文だけ



  • 本文とタイトルはSNSはないかもしれないけどもしかしたら設定値みたいな感じであらかじめ固定のメッセージ持っておいてそこに対してサービス層からキーだけ渡す感じになる商品名と値段だけ引数で渡して文章を組み立てていいそんな感じですよね多分ね



  • で戻りましてサービスを僕は通知して終わりじゃないと思ってて最後にレスポンスを作る必要があると思うんですよ今回で言うと更新後のコンテンツ回数ですね多分ねなぜなら編集画面で編集ポチッとしたら編集後のやつが表示されるはずだからはい確かにもしくは編集後のページが一覧とかに飛ぶんだったらリダイレクトになるからその場合だったらまあ



  • 作られたデータを見て成功したか失敗したかみたいなのが分かった方がいいのかそういうのなんか綺麗にコネコネまとめてくれるこれはサービス層のクラスの中でどっちで寝れとりいいのかなうわめめむずいですねコンバートそこでリダイレクトレスポンス作るはしないかコントローラーで戻ってからやるかそれってどうしますちなみにレスポンス作るのってどこでやりますか



  • コントローラーでやりますねコントローラーの中に入れます?僕割とサービス層でやってるかもサービス層はサービス層でやるとこれはさっきの入り口と同じ問題が起きる気がするわかりますあれちょっと待ってくださいねやってないわごめんなさいコントローラーからロジック作るくん呼んでるな別の場所に置いてるのかなすいませんコントローラーってクラスじゃないですよね



  • ララベルの場合クラスですねじゃあコントローラーにひも付いたプライベートメソッドみたいなやつ切れるんですね切れる切れる多分ファストAPIないんで関数なんで別のとこに置いてるんですけどレッスンスクルークンまあでもなるほどねまあでもそうですね確かにコントローラーでやりますわはい



  • っていうような形で層とファイルとか 関数を分け分けすると使い回したい時に使い回せるし データベースじゃなくてデータベースのライブラリ変わった時とかも変更が最小になるような いいソフトを書けるんじゃないっていうまとめた方がいいかもな これ長すぎて



  • まとめも長いですよまとめても長いね振り返りおさえしましょうかルート君がいてルート君からコントローラーに来ますコントローラー何するかセッションのチェックとバリデーションチェックそしてサービス層よろしくじゃあ下いきますサービス層は実は2個ありましてコントローラーから呼ばれるサービス層とサービス層から呼ばれるサービス層通称インターナルがあります以下インターナル



  • サービスにはビジネスロジックを置きます今回だったら商品を取得して値段の変更があるかとかをチェックしてデータを更新して値段の変更があった場合は通知を送るっていうこの組み合わせですね本当にその詳細部分はサービスに書かずに例えば



  • 値段の変更をチェックするための最初に取ってくる一件取ってくる処理はインフラ層のDBのクライアントのところに書いてるし値段のチェックこれはサービス層から呼ばれるサービス層に書いてるインターナルに書いてると



  • で更新も同じくインフラ層に書いてて通知部分もインフラ層違うな通知をするのはインターナルインターナルのサービスでどこに通知するかとか誰に通知するかとかどういうメッセージを送るかっていうのはサービス層のインターナルでやって実際に送るのは送ってるメッセージ作るのインフラ層でやるとはいでそっからサービス層君はえっと



  • 更新した値これだよ通知できたよってコントローラーに送ります返しますでコントローラーはよっしゃできたんだじゃあ返すもん作って返そうっていうレスポンス作るのをコントローラーでやって無事ユーザーに200が返るとはいこんな感じでねやっていくとごしゃっとならないしあとなんでしょうねプロジェクト行った時になんでこんなわけわけしてんのって思うことあると思うんですけど僕は思ってましたけどうんうんうん



  • 意図が分かるようになるんじゃないかなと



  • ですねこれはあの啓蒙活動なんではいこれはの続けてってなんぼだと思いますし 確かにはい今の話を順平ができるようになるっていうのがなんかいいのかもしれないですねそうでちなみにまあ今のが絶対の正解ではないってのは絶対にあの意識してほしい いや絶対の正解ではないですね絶対そうそんなものこのようにないですからね結局どういうのが一番今回のプロジェクトに合うかみたいなメリット デメリットトレードオフがあり



  • その結果取捨選択をしていかなきゃいけないんですけど一般的にはこうするといいよねって言われてるやつを言ったつもり半年後1年後僕とのりさんこれを聞いて顔を覆ってるかもしれませんがそうですねイヤホンすぐ取って音止めるかもしれないですねエピソード消えたらご察しください差し替えられてるかもしれっとじゃあ終わりますかだいぶロングコースでしたか



  • 1時間2分やっちゃったではハッシュタグひまじんプログラマーでSNSでフィードバック募集してますのでまさかりないしプロポーザルこちらもお待ちしてますこういうAPI設計するならどうしますかとか送ってほしいかもねあー面白いサーボぜひくださいめっちゃ募集してます



  • あとは各種ポッドキャスト説明欄からグーグルフォームでお便り要望感想質問何でもお待ちしてますお願いしますあとは各種ポッドキャストプラットフォームでフォロー高評価お待ちしてますぜひお願いしますちょっとこれね長すぎたんですけど次はなんかもうちょっとねフォーカスしてやりましょうかそうですねではまた次回バイバイ日本のエンジニアは使うアプリが多すぎる



  • 事実!ヒマプロの使用アプリ平均数38.6個!レイキャストならアプリの即起動!過去のコピー履歴を引き出せる!ウィンドウのリサイズなどこれ一つで作業効率アップ!しかも料金無料!今すぐレイキャストで検索!

0:00 57:46

#299 一機能を作り上げるまで 〜啓蒙活動〜