$30 off During Our Annual Pro Sale. View Details »
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
140
「もっと正確に、もっと効率的に」ANDPADの写真書き込み機能における、 現場の声を形にしたエンハンス
andpad
0
520
複数チーム並行開発下でのコード移行アプローチ ~手動 Codemod から「生成AI 活用」への進化
andpad
0
220
Building the Real World with Ruby
andpad
0
50
Catch Up: Go Style Guide Update
andpad
0
300
OSS開発者という働き方
andpad
5
1.8k
Vue・React マルチプロダクト開発を支える Vite
andpad
0
170
プロダクト開発を支えるデータ利活用:中央集権から「民主化」までの軌跡
andpad
0
240
アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介
andpad
0
440
Other Decks in Programming
See All in Programming
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
190
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
8
3.4k
クラウドに依存しないS3を使った開発術
simesaba80
0
170
Graviton と Nitro と私
maroon1st
0
140
Python札幌 LT資料
t3tra
7
1.1k
Flutter On-device AI로 완성하는 오프라인 앱, 박제창 @DevFest INCHEON 2025
itsmedreamwalker
1
160
生成AI時代を勝ち抜くエンジニア組織マネジメント
coconala_engineer
0
25k
The Art of Re-Architecture - Droidcon India 2025
siddroid
0
130
ZJIT: The Ruby 4 JIT Compiler / Ruby Release 30th Anniversary Party
k0kubun
1
280
Developing static sites with Ruby
okuramasafumi
0
330
「コードは上から下へ読むのが一番」と思った時に、思い出してほしい話
panda728
PRO
39
26k
LLMで複雑な検索条件アセットから脱却する!! 生成的検索インタフェースの設計論
po3rin
4
980
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
246
13k
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
Rails Girls Zürich Keynote
gr2m
95
14k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
0
130
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
38
Ruling the World: When Life Gets Gamed
codingconduct
0
100
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
0
280
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
38
Leadership Guide Workshop - DevTernity 2021
reverentgeek
0
170
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
0
78
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
130
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
580
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の壁