Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
仕事でWeb API開発するときに考えているこ と 技育CAMP 2023 CARTA HOLDINGS Inc.
Slide 2
Slide 2 text
● yanyan ● 新卒3年目 ● 株式会社fluct アドプラットフォーム事業本部 ○ データエンジニアリングや API開発してます 自己紹介 CARTA HOLDINGS Inc.
Slide 3
Slide 3 text
今日のサンプルコードは Githubにおいてあります https://github.com/shinya-ml/geeksai-backend-study サンプルプログラム CARTA HOLDINGS Inc.
Slide 4
Slide 4 text
ざっくりしたWebアプリケーションの構成 CARTA HOLDINGS Inc.
Slide 5
Slide 5 text
ざっくりしたWebアプリケーションの構成 CARTA HOLDINGS Inc. この部分を作るときに考えていることを話します
Slide 6
Slide 6 text
認知負荷の話 01 アプリケーションのアーキテクチャの 話 02 APIの設計について 03 テストの話 04 CARTA HOLDINGS Inc. 思想を言語化する 04
Slide 7
Slide 7 text
認知負荷の話
Slide 8
Slide 8 text
人が学習する際にかかる記憶領域に対する負荷 ● 開発には様々な認知負荷がかかる ○ コードの意図を読み取る、アーキテクチャの理解 etc… ● A Philosophy of Software Design では、ソフトウェアの複雑性が増大している兆候の一つとしてあ げられている ● 自分は普段の開発で認知負荷が高くなりすぎていないか?を気にしている 認知負荷とは CARTA HOLDINGS Inc.
Slide 9
Slide 9 text
● 認知負荷が高いものは理解するのが難しい ● 理解が不十分なままコードの修正や書き足しをすると、 より複雑度が高まってしまう ○ 認知負荷の高いコードは、さらなる認知負荷の上昇をもたらす ● 規模が大きくなるにつれて複雑性の増加は避けられない ○ 工夫して複雑になりすぎないようにすることはできる なぜ認知負荷を気にしているのか CARTA HOLDINGS Inc.
Slide 10
Slide 10 text
アーキテクチャの話
Slide 11
Slide 11 text
実際はインフラの構成とかもスコープだが今回はアプリケーションコードの構造の話 ● アプリケーションの実装をレイヤーごとに分けて整理する ● レイヤーに分けると何が嬉しい? ○ 関心事の分離 ○ 依存関係の整理 1からコードを書いていくときに、どうやってレイヤー構造を考えていくか ここでいうアーキテクチャとは CARTA HOLDINGS Inc.
Slide 12
Slide 12 text
● レイヤードアーキテクチャ ● ヘキサゴナルアーキテクチャ ● オニオンアーキテクチャ ● クリーンアーキテクチャ ● etc… よく目にするアーキテクチャたち CARTA HOLDINGS Inc. [画像の出典] Ready for changes with Hexagonal Architecture, Clean Architecture
Slide 13
Slide 13 text
いかなるアプリケーションに対しても最適なアーキテクチャなどない 彼らは銀の弾丸ではない CARTA HOLDINGS Inc.
Slide 14
Slide 14 text
● そのアプリケーションにとって妥当なアーキテクチャは 開発が進むにつれて変化していく ● 小規模な段階から壮大なアーキテクチャにすると大体辛い ○ ほとんど何もしてないレイヤーが生まれる ○ 意味のない抽象化 (具体的な実装が一つしか無い ) ○ なぜそのレイヤーが存在しているのかわからない = 認知負荷が高い 必要なときに必要な変更をする CARTA HOLDINGS Inc.
Slide 15
Slide 15 text
● handler: HTTP リクエストを受けてレスポンス返す ● repository: DBとやりとりする ● entity: アプリケーションで扱うオブジェクトを定義する 例えば CARTA HOLDINGS Inc. handler repository entity DB 依存の流れ 単にCRUDするだけならこれくらい素朴な構成でもよい
Slide 16
Slide 16 text
● ビジネスロジックを書く層がほしい! ○ 必要になったら足せば良い 扱う関心事が増えた CARTA HOLDINGS Inc. handler repository entity DB usecase
Slide 17
Slide 17 text
● repositoryに依存する層のユニットテストをしたい ○ repositoryの部分はフェイクに差し替えたい ● インターフェースに依存する形にする 抽象化したい CARTA HOLDINGS Inc. handler repository interface repository implementation repository mock entity DB
Slide 18
Slide 18 text
1. 関心事の分離 2. 依存の流れを1方向にする これらを守りながら、 その時々でベストな設計を模索する 何が大事かは関わる人とかサービスの特性によって変わってくる 依存関係を整理するときに大事なこと CARTA HOLDINGS Inc.
Slide 19
Slide 19 text
● 関心事とは ○ 自分が主に取り扱おうとしているトピック、対象 ○ e.g.) DBとのやりとり、HTTP req/resについて etc… 関心事の分離 CARTA HOLDINGS Inc.
Slide 20
Slide 20 text
● まずはどんな関心事が存在するのか言語化することが大事 ● 1レイヤーが複数の関心事を扱わないようにする ○ e.g.) ファットコントローラー 関心事の分離 CARTA HOLDINGS Inc.
Slide 21
Slide 21 text
● 認知負荷が低い ○ 触りたい実装がどこにあるか把握しやすい ○ e.g.) DB周りはrepository層をみればいい ● 変更しやすい ○ どこを修正すればいいか明確 ● 壊れたときに直しやすい ○ どこで壊れたか特定しやすい 各層が1つの関心事だけを扱っていると何が嬉しい? CARTA HOLDINGS Inc.
Slide 22
Slide 22 text
● レイヤー構造を成すので、レイヤー間に 依存関係が生まれる ● 依存とは ○ 依存される側の知識が依存する側に漏れ出ている状態 ○ メソッドの呼び出しに必要な引数とか ● 依存される側に変更が入ると、する側も影響を受ける ○ あるモジュールが依存したりされまくったりしている(密結合)と辛い 依存関係 CARTA HOLDINGS Inc.
Slide 23
Slide 23 text
● 依存の向きを交通整理する ● 具体的な関心事を扱うレイヤー → 抽象的な関心事を扱うレイヤーという依存の流れを作る ○ 具体的な関心事: 特定の技術に関すること (DBとかGraphQLとか...) ○ 抽象的な関心事: アプリケーションが扱うドメインコアなこと (ビジネスロジックとか ...) 依存の流れを1方向にする CARTA HOLDINGS Inc.
Slide 24
Slide 24 text
● サービスのコアとなる部分が特定の技術に依存しない ○ 変更しやすい ● ある技術を差し替えてもサービスのコアには影響しない 具象 → 抽象の向きで依存させる CARTA HOLDINGS Inc.
Slide 25
Slide 25 text
つまり、具体的な知識がビジネスロジックに漏れ出る ● e.g.) MySQLの知識がusecase層で必要になる 具体的な関心事が漏洩すると ... ● 円の外側に対する変更で内側も影響を受ける ● 技術の差し替えが難しくなる 抽象 → 具象という依存があるとどうなる? CARTA HOLDINGS Inc.
Slide 26
Slide 26 text
● アプリケーションにレイヤー構造を設けることで依存関係が整理される ● 関心事を適切に分けよう ● 何を守りたいか?を考えながら、必要に応じてアーキテクチャは変化させよう まとめ CARTA HOLDINGS Inc.
Slide 27
Slide 27 text
API設計の話
Slide 28
Slide 28 text
APIをどういう形式で提供するかは、いくつか選択肢がある ● REST ○ リソースベースのURI ○ JSON形式でデータをやり取りする ○ 長いこと使われてる ● gRPC ○ Protobuf形式でやり取りする ○ マイクロサービス間の通信とかで使われてる ● GraphQL ○ クエリ言語 + クエリに対するサーバーサイド実装 ○ クエリする側が柔軟に欲しいデータを持ってこれる APIのスタイル CARTA HOLDINGS Inc.
Slide 29
Slide 29 text
● ユースケースに応じて使い分けよう ○ 銀の弾丸などない ● GraphQLはRESTの上位互換とか、そんなことはない ○ RESTのほうがいい場合もある 大前提 CARTA HOLDINGS Inc.
Slide 30
Slide 30 text
● APIの利用者 ○ 誰が使うんだっけ ○ どのくらい使われるんだっけ ● ユースケースの数 ○ 利用者が多様でユースケースも様々なんだよねーとか ● サービス的になにを重要視するか ○ APIとしての柔軟性? ○ パフォーマンス? etc… どういう軸で考えるのか CARTA HOLDINGS Inc.
Slide 31
Slide 31 text
● REST ○ リソースベースでエンドポイントを生やすので、 1つのAPIで色々なユースケースに対応しよう とすると辛くなりがち ○ 1APIのユースケースが単純ならわかりやすい ● GraphQL ○ クエリによって利用者側が柔軟に欲しいデータを記述できるのでユースケースが多様な場合 に対応しやすい ○ エラーハンドリングが難しい ● gRPC ○ パフォーマンス重視ならこれかな ○ 内部向けのAPIかくなら、型もかっちり書けるしよさげ ざっくりとした私の所感 CARTA HOLDINGS Inc.
Slide 32
Slide 32 text
正しい使い方をするのが簡単で、間違った使い方をするのが難しい ● APIを使う側のことを考えて設計する ● 適切にドキュメンテーションする ● 命名の一貫性 ● レスポンスの設計 良いAPIとは? CARTA HOLDINGS Inc.
Slide 33
Slide 33 text
APIの形式によって気をつけたいことも変わってくる RESTなら... ● エンドポイントのURIはわかりやすいか ● クエリパラメータやリクエストボディの設計 GraphQLなら... ● スキーマ設計 ○ 命名の一貫性 ○ nullの使い分け ● Production Ready GraphQL という本がおすすめ 例えば CARTA HOLDINGS Inc.
Slide 34
Slide 34 text
テストの話
Slide 35
Slide 35 text
● ユニットテスト ○ あるモジュール単体の振る舞いに対するテスト ● インテグレーションテスト ○ 複数のモジュールを跨いだテスト ○ DBのような、アプリケーションの外側とのテストも含む APIサービスに対するテストは色々ある CARTA HOLDINGS Inc.
Slide 36
Slide 36 text
Q. どのテストを書けばいい? CARTA HOLDINGS Inc.
Slide 37
Slide 37 text
A. 全部書けばいいやん Q. どのテストを書けばいい? CARTA HOLDINGS Inc.
Slide 38
Slide 38 text
A. 全部書けばいいやん Q. どのテストを書けばいい? CARTA HOLDINGS Inc.
Slide 39
Slide 39 text
● リリース前にバグに気づく ● 変更することに対する安全性、容易性 ● テスト対象のコードの理解を助ける ● etc… つまり、開発における様々な不安を取り除く なぜテストを書きたいのか CARTA HOLDINGS Inc.
Slide 40
Slide 40 text
テストを書くことで、不安を取り除きたい箇所 ● リリース後に壊れると致命的な箇所 ○ お金が絡んだりしてあとから直すのが辛いとか ● サービス的に大事なロジックが書かれている ○ ECサイトなら決済とか、注文のキャンセルとか ○ いわゆるビジネスロジック どこにテストを書きたい? CARTA HOLDINGS Inc.
Slide 41
Slide 41 text
特段不安がないとか、テストのコスパが悪そうな箇所にはテストは書かない ● テストコードにもメンテコストはかかる ● テストの実行に時間がかかると人々はテストしなくなる → テストしたいところだけテストする テストを書かないという選択 CARTA HOLDINGS Inc.
Slide 42
Slide 42 text
● 公開された振る舞い ○ 依存しているモジュールから呼び出されるようなメソッド ● 実装詳細 ○ モジュール内で完結しているメソッド ○ 外部から利用されることはない 公開された振る舞いと実装詳細 CARTA HOLDINGS Inc.
Slide 43
Slide 43 text
基本的に公開された振る舞いしかテストしない ● 外部から見える振る舞いが担保されてればよい ● 詳細がテストされていると、リファクタリングしにくい ○ 振る舞いは変わらないがその中身が変わるときに、テストも直す必要が出てくる 実装の詳細はテストしない CARTA HOLDINGS Inc.
Slide 44
Slide 44 text
右図のような構造で、以下のことを考えてみる ● 何のテストを書きたいか ● 何のテストを書かないか 各レイヤーの関心事 ● handler: HTTP req/res ● usecase: ビジネスロジック ● repository: DBとのやりとり ● entiry: ビジネスオブジェクトとその振る舞い 例 CARTA HOLDINGS Inc.
Slide 45
Slide 45 text
あくまで例、サービスの特徴によって変わる 単純な構造なので、書きたいテストはそんな多くない ● usecase層のユニットテスト ● (ロジックがあれば)entity層のユニットテスト ● handler ~ repositoryまで一気通貫のインテグレーションテスト 何のテストを書きたいか CARTA HOLDINGS Inc.
Slide 46
Slide 46 text
あくまで例(ry ● handlerのユニットテスト ● repositoryのユニットテスト ● repository - DB間のインテグレーションテスト 何のテストを書かないか CARTA HOLDINGS Inc.
Slide 47
Slide 47 text
handlerのユニットテスト ● HTTP req/resが関心事 ○ それ以外の殆どの処理は他の層に移譲している ○ つまり、テストしたいロジックがほとんどない ● この層にテストしたいロジックがあったら、関心事の分離がうまくできていないかも? なんで書かない?の一例 CARTA HOLDINGS Inc.
Slide 48
Slide 48 text
● なぜテストを書き、何をテストしたいのか ● 意図がわからないテストは後々辛い ○ プロダクションコードの変更でテストがコケたとき直しづらい ○ そのテストの存在理由がわからないとメンテもされない 本当にテストしたいところにテストを書こう テストは意図が大事 CARTA HOLDINGS Inc.
Slide 49
Slide 49 text
思想を言語化しよう
Slide 50
Slide 50 text
● なぜこのアーキテクチャにした? ● なぜこの言語を選んだ? ● なぜGraphQLを採用した? こうしたWhyに対する答えは、意図的に言語化しないと残らない Whyはコードを読んでもわからない CARTA HOLDINGS Inc.
Slide 51
Slide 51 text
● 理解の助けになる ● あとから反省する材料になる ● アーキテクチャやテストに手を入れる際、既存のものの意図を知ることは大事 ○ 今あるものがなぜこうなっているかを知った上で、どう変えると良いかを考える Whyの言語化はなぜ大事なのか CARTA HOLDINGS Inc.
Slide 52
Slide 52 text
システムを作り始める前に書く地図のようなもの ● これから作るシステムが目指すゴール ● どういう設計で作るのか ● システムがスコープとしないこと、やらないこと などを書く ● システムを作るにあたって必要な意思決定が言語化される ● 意思決定に至ったWhyも書く Design Docを見ればシステムのゴール、意思決定の Whyが分かる状態にする Design Doc CARTA HOLDINGS Inc.
Slide 53
Slide 53 text
特定の意思決定に関することを記述する ● 背景 ● なぜこの意思決定をしたのか ● 他にどんな選択肢があったのか 作り始めてから行われる変化の意思決定は ADRで言語化するとわかりやすい Architecture Decision Record (ADR) CARTA HOLDINGS Inc.
Slide 54
Slide 54 text
● 認知負荷を意識して開発する ● アーキテクチャもテストも必要だと思ったことをやればよい ○ 必要に応じてあとから変化させれば良い ● なぜやる(やらない)のかが大事 ● コードでは伝わらないことは積極的に言語化していこう おわりに CARTA HOLDINGS Inc.
Slide 55
Slide 55 text
CARTA HOLDINGSのテックブログを読んでみてね ● https://techblog.cartaholdings.co.jp/entry/2022/10/20/100730 今日の内容を実践した話 CARTA HOLDINGS Inc.
Slide 56
Slide 56 text
もの創り実践プログラム 「Treasure」 ● 内容 「Go言語を使って学ぶ、 価値のあるもの創りとチーム開発」 ● 日時 8/7~8/25(10:00~18:30) ● 形式 オンライン+オフィス開催(渋谷) ● 定員:30名程度 ● 学年:2025年4月以降に入社可能な方 ※文理不問、条件に合えば学年不問
Slide 57
Slide 57 text
大規模サービス構築プログラム 「Sunrise」 ● 内容 Goの広告アプリケーションサーバを AWSに構築し、改修 大規模リクエストを捌くために必要な 設計・構築について学べます ● 日時 9/11~9/15(10:00~18:30) ● 形式 オフライン開催(渋谷オフィス) ● 定員:16名程度 ● 学年:2025年4月以降に入社可能な方 ※文理不問、条件に合えば学年不問