Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
サーバサイドDartを試してみた
Search
ANDPAD inc
February 25, 2021
Programming
3
4.6k
サーバサイドDartを試してみた
2021/02/24 ANDPAD TechLive #2 Flutterって実際どうなの?設計からテストまで
ANDPAD inc
February 25, 2021
Tweet
Share
More Decks by ANDPAD inc
See All by ANDPAD inc
Go コードベースの構成と AI コンテキスト定義
andpad
0
150
「もっと正確に、もっと効率的に」ANDPADの写真書き込み機能における、 現場の声を形にしたエンハンス
andpad
0
570
複数チーム並行開発下でのコード移行アプローチ ~手動 Codemod から「生成AI 活用」への進化
andpad
0
230
Building the Real World with Ruby
andpad
0
51
Catch Up: Go Style Guide Update
andpad
0
310
OSS開発者という働き方
andpad
5
1.8k
Vue・React マルチプロダクト開発を支える Vite
andpad
0
180
プロダクト開発を支えるデータ利活用:中央集権から「民主化」までの軌跡
andpad
0
240
アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介
andpad
0
450
Other Decks in Programming
See All in Programming
Pythonではじめるオープンデータ分析〜書籍の紹介と書籍で紹介しきれなかった事例の紹介〜
welliving
3
750
從冷知識到漏洞,你不懂的 Web,駭客懂 - Huli @ WebConf Taiwan 2025
aszx87410
2
3.3k
2年のAppleウォレットパス開発の振り返り
muno92
PRO
0
180
クラウドに依存しないS3を使った開発術
simesaba80
0
210
Kotlin Multiplatform Meetup - Compose Multiplatform 외부 의존성 아키텍처 설계부터 운영까지
wisemuji
0
150
AI 駆動開発ライフサイクル(AI-DLC):ソフトウェアエンジニアリングの再構築 / AI-DLC Introduction
kanamasa
11
4.9k
TestingOsaka6_Ozono
o3
0
260
Vibe codingでおすすめの言語と開発手法
uyuki234
0
160
TerraformとStrands AgentsでAmazon Bedrock AgentCoreのSSO認証付きエージェントを量産しよう!
neruneruo
4
2.3k
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか
syumai
7
2.4k
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
200
AtCoder Conference 2025
shindannin
0
880
Featured
See All Featured
Visualization
eitanlees
150
16k
A Modern Web Designer's Workflow
chriscoyier
698
190k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
210
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
0
990
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
530
Abbi's Birthday
coloredviolet
0
4.2k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
1
100
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
35
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.1k
The Language of Interfaces
destraynor
162
26k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
0
220
Transcript
サーバサイドDartを試してみた バベルの塔以前の世界へ ANDPAD Tech Live #2
1. 動機 2. なぜDartでサーバを実装するのか 3. サンプルの構成 4. サンプルのポイント解説 5. 感想
6. 実戦投入のはじめの一歩 目次 ※ FlutterやgRPCの基礎知識があることを前提にしている。本資料では、これらの詳細には触れない。
• サーバ、Webフロント、モバイルアプリで言語がばら ばらのせいか、相乗効果がない ◦ バベルの塔の建設現場っぽい • サーバのコードを読まないと、Web APIの仕様が分か らないことがある ◦
モバイルアプリエンジニアからすると、サーバの言語とツー ルに馴染みがないのでつらい 1. 動機(問題意識) 主は、人の子らが作ろうとしていた街と塔とを見ようとしてお下りになり、そして仰せられた、「なるほど、彼らは一つの民で、同じ言葉を話して いる。この業は彼らの行いの始まりだが、おそらくこのこともやり遂げられないこともあるまい。それなら、我々は下って、彼らの言葉を乱して やろう。彼らが互いに相手の言葉を理解できなくなるように」。 — 「創世記」11章1-9節
• サーバ、Webフロント、モバイルアプリで言語を統一 する ◦ ノウハウの共有ができる ◦ 担当外のコードも読みやすい ◦ フルスタック開発もできる 1.
動機(解決案)
• フルスタック開発ができる言語は2つ ◦ Javascript(Typescript込み) ◦ Dart • モバイルアプリ開発では、Javascript(ReactNative)よ りも、Dart(Flutter)の方が勢いがある 2.
なぜDartでサーバを実装するのか ※厳密にいえばGoなどでも全部開発できるが、この 2つの言語以外はロマンだと思う。
• サーバをDartで実装してみました ◦ サンプルコード ▪ https://github.com/KamikazeZirou/dart-ser ver-sample ◦ おなじみのTodoアプリ ▪
バックエンドのAPIのみ 3.サンプルの構成(概要)
3.サンプルの構成(アーキテクチャ) Repository MySQL Domain Model Service gRPC Handler API Client
Handler:APIのエントリポイント。データ形式の変換をして、 gRPCを隠蔽する。 Service:ビジネスロジックを担当。ロジックが単純すぎるので Repositoryのメソッド呼ぶだけ。 DomainModel:データとビジネスロジックを持つ。サンプルは単純すぎるので単なる構造体。 Repository:データのCRUD機能などを提供。データの保存方法を隠蔽する。 円の外から内の依存関係は良いが、逆は NG。 Dart Server
ライブラリ バージョン 備考 Flutter 1.26.0.17.6.pre beta channel, Dart 2.12。 grpc
3.0.0 このバージョンではDart 2.12以上が必要。 protoファイルからのコード生成は割愛。 公式の説明をお勧めします。 https://grpc.io/docs/languages/dart/ mysql1 0.17.1 MySQLドライバ。 riverpod 0.13.0-nullsafety.3 DIに使う。 3.サンプルの構成(利用ライブラリ) mysql1以外は、モバイルアプリ開発でも珍しくはない
3.サンプルの構成(開発環境) ツール 説明 Docker MySQLサーバとDartサーバを動かす用。 Dockerを使わなくてもサーバは起動できるが、実務ではコンテナとしてデプロイ することが多いので Dockerを使う。 protoc gRPCのAPIを定義するprotoファイルから各言語のコードを生成するツール。
protoc_plugin protoファイルからDartのクライントコードとサーバコードを生成するツール。 Dart のプラグイン。 Android Studio コードエディタ。サーバ独自の設定は不要。 もちろん、InteliJやVSCodeでもOK。
3.サンプルの構成(開発環境) service TodoService { rpc CreateTodo (CreateTodoRequest) returns (CreateTodoResponse) {}
} message Todo { int32 id = 1; string title = 2; string description = 3; } message CreateTodoRequest { // 作成するTodo Todo todo = 1; } message CreateTodoResponse { // 作成したTodo Todo todo = 1; } 補足:gRPCのコード生成 protoファイル Dart コード Go コード JS コード protocで 生成
4.サンプルのポイント解説(main) void main(List<String> arguments) async { final container = ProviderContainer();
var listener = container.listen(todoServiceHandlerProvider); // 1. serviceHandler の作成 final serviceHandler = await listener.read(); // 2. serviceHandler をgRPCのServerに登録 final server = Server( [serviceHandler], const <Interceptor>[], CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]), ); // 3. サーバ起動 await server.serve(port: 5001); ... }
4.サンプルのポイント解説(Handler) // 1. Handlerにはprotocが生成したAPIサーバ用の基底クラスを継承させる class TodoServiceHandler extends TodoServiceBase { //
2. APIに対応するメソッドがあるのでoverrideする @override Future<grpc.CreateTodoResponse> createTodo(ServiceCall call, grpc.CreateTodoRequest request) async { // 3. データをgRPC -> domain形式に変換 // 4. Serviceのメソッドを呼ぶ final newTodo = await _todoService.create(domain.Todo( title: request.todo.title, description: request.todo.description, )); // 5. Serviceの処理結果をgRPC形式に変換して返す return CreateTodoResponse( todo: grpc.Todo( id: newTodo.id, title: newTodo.title, description: newTodo.description, )); } } 形式変換をするのは、 Service がgRPCに依存しないようにす るため。
• Service ◦ サンプルではRepositoryのAPI呼ぶだけ • Repository ◦ モバイルアプリの時と同じように実装すればOK 4.サンプルのポイント解説(Service/Repository)
riverpodを使用。 Handler、Service、 Repositoryのオブジェクト のProviderを実装。 // MySQLConnection のプロバイダ final dbConnectionProvider =
Provider.autoDispose((ref) async { ... final connection = await MySqlConnection.connect(settings); ... return connection; }); // Repository のプロバイダ。 // ref.watch で依存オブジェクトを取得する。 // ここでは、MySQLConnection を取得している。 final todoRepositoryProvider = Provider.autoDispose((ref) => ref.watch(dbConnectionProvider).then((conn) => MySQLTodoRepository(conn))); final todoServiceProvider = Provider.autoDispose((ref) => ref .watch(todoRepositoryProvider) .then((repository) => TodoServiceImpl(repository))); final todoServiceHandlerProvider = Provider.autoDispose((ref) => ref .watch(todoServiceProvider) .then((service) => TodoServiceHandler(service))); 4.サンプルのポイント解説(DI)
マルチステージビルドを使う。 ビルド用と実行用でイメージを分け ることで、実行イメージのサイズを 抑える手法。 ビルドに使うDockerイメージのサイ ズは約250MBある。Dart SDKなど が含まれるため。 実行用のDockerイメージは、開発 用のツールが一切入っていないの
でサイズは約2.2MB。 (ビルドしたバイナリファイルのサイ ズは約8.7MB) 4.サンプルのポイント解説(Docker) # ランタイムなしで実行可能なサーバのバイナリファイルをビルドするイメージ FROM google/dart:2.12-beta as builder WORKDIR /app ADD pubspec.* /app/ RUN pub get ADD . /app RUN pub get --offline RUN dart compile exe bin/server.dart -o bin/server # ビルドしたバイナリを実行するイメージ FROM subfuzion/dart:slim WORKDIR /app COPY --from=builder /app/bin/server . CMD [] ENTRYPOINT ["./server"]
4.サンプルのポイント解説(docker-compose) • Docker単独よりもサーバの実行が簡単にできる ◦ サーバの起動時のコマンドがDockerコマンドよりも簡潔に なる ◦ コンテナ間の依存関係を設定できる ▪ DBのコンテナをDartサーバのコンテナより先に実行できる
4.サンプルのポイント解説(client) Future<void> main(List<String> args) async { // 1. gRPC接続チャンネルを作る final
channel = ClientChannel( 'localhost', port: 50051, options: ChannelOptions( credentials: ChannelCredentials.insecure(), codecRegistry: CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]), ), ); // 2. protoファイルから生成したClientのオブジェクトを作る final stub = TodoServiceClient(channel); // 3. gRPCのAPIを呼ぶ。 try { final response = await stub.createTodo( CreateTodoRequest( todo: Todo(title: 'title3', description: 'description3')), options: CallOptions(compression: const GzipCodec()), ); } catch (e) { ... } await channel.shutdown(); }
• 良かったこと ◦ アプリ開発とノウハウは共有できる ▪ riverpodは初めて使ったが、モバイルアプリ開発にも知見を転用でき る ◦ Dartの書き方をほぼ忘れていたが、Goよりは書きやすい ▪
並列処理が出てきたら、感想は変わりそう • 懸念 ◦ サーバ向けライブラリが充実していない ▪ 有力なORMが少ない • Web Framework Aqueductの一部としてならORMあるが・・・ ▪ AWSの公式SDKはなさそう・・・ 5.感想
• モバイルアプリ用のAPI Gatewayで採用する 6.実戦投入のはじめの一歩 BFFでは、API GatewayはAPIクライアント ごとの要件に沿って実装する。 開発の担当は、APIクライアント開発者が 良いらしい。クライアントの要件に詳しいの は、クライアントの開発者のため。
モバイルアプリ開発者が慣れている Dart をAPI Gatewayに採用すると、開発効率 は上がるはず。 ※今のANDPADにはAPI Gatewayなし
ANDPADでは、マイクロサービスを開発する メンバーを募集しています! こんな方におすすめです。 • アプリ開発以外もやってみたい • ユーザの業務を考えつつ開発をしたい • サービスの基盤を考えたい 最後に
番外 言語 MSにたとえると 補足 Kotlin ゲルググ Dart リック・ドムⅡ C# ドワッジ
Java ドム Go イフリート グフとドムの中間。 Rust グフ ゲームだと格闘が強い。使ったことはない。 C++ ザク C 旧ザク GCの壁