はじめに
「Shelf」はGoogleが開発しているDartのWebフレームワークです。
Dart公式が提供しているパッケージで、定期的にアップデートされていて、Dart SDKと親和性が高いのでDartのエコシステム全体を一貫して使用することができます。
現在、Dart3系に対応した安定版(stable)がリリースされており、安心して使用することができると考えています。
サーバサイドを「Shelf」、フロントエンドを「Flutter」で作ることにより、All Dartで開発を行うことができます。(Flutter, ShelfともにGoogle製なので、メンテナンスや信頼性も問題なさそう!)
すべてDartでシステム開発をすることで以下の利点が考えられます。
- フロントエンドとバックエンドの垣根が低くなり、柔軟な人材配置が可能になる
- バックもフロントも同じ言語なので理解しやすい
- AI駆動開発などでAIが書いたコードをレビューするときにDartエンジニアだけでできる
今回はShelfでプロジェクトを作成して、サーバー起動まで書きたいと思います。
サンプルコード
プロジェクト作成
Dartバージョン
study_web_server_shelf % dart --version
Dart SDK version: 3.6.0 (stable) (Thu Dec 5 07:46:24 2024 -0800) on "macos_arm64"
プロジェクト作成します。
以下のコマンドを実行してプロジェクトを作成します。
study_web_server_shelf % dart create todo_api
Creating todo_api using template console...
.gitignore
analysis_options.yaml
CHANGELOG.md
pubspec.yaml
README.md
bin/todo_api.dart
lib/todo_api.dart
test/todo_api_test.dart
Running pub get... 3.9s
Resolving dependencies...
Downloading packages...
Changed 50 dependencies!
Created project todo_api in todo_api! In order to get started, run the following commands:
cd todo_api
dart run
サンプルプログラムを試しに実行します。
study_web_server_shelf % cd todo_api
todo_api % dart run
Building package executable...
Built todo_api:todo_api.
Hello world: 42!
Shelfパッケージを追加
shelfはWebフレームワークとして、非常に軽量でシンプルな設計をしています。
DBクライアントやルーティング機能など必要な機能はパッケージを追加する必要があります。
※ この記事では使用するところまで書いていません
## shelfパッケージ追加
dart pub add shelf
## routerパッケージ追加
dart pub add shelf_router
## DBパッケージ追加
dart pub add postgres
## ORMパッケージ(Postgres対応)
dart pub add drift
dart pub get
サーバー起動
bin
ディレクトリにあるファイル(todo_api.dart)に以下のようにサーバーを起動させる処理を書きます。
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
void main(List<String> arguments) async {
// リクエストを処理するハンドラー追加
// ミドルウェア追加
final handler = const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);
// サーバ起動
var server = await shelf_io.serve(handler, 'localhost', 8080);
// コンテンツ圧縮機能ON(レスポンス速度が上がる)
server.autoCompress = true;
// サーバ起動メッセージ
print('Serving at http://${server.address.host}:${server.port}');
}
// リクエストを処理するハンドラー
Response _echoRequest(Request request) => Response.ok('Request for "${request.url}"');
dart run
コマンドを実行してサーバを立ち上げて、ブラウザからアクセスしてみます。
以下結果になります。
todo_api % dart run
Building package executable...
Built todo_api:todo_api.
Serving at http://localhost:8080
2024-12-31T17:36:34.376824 0:00:00.003498 GET [200] /HelloShelf!
2024-12-31T17:36:34.416905 0:00:00.000083 GET [200] /favicon.ico
おわりに
今回はDartのWebサーバーフレームワークであるshelfについてためしに触ってみました。小規模のREST APIサーバーやマイクロサービスとして使用できると思いました。
ただフレームワークとしての機能は少ないので、パッケージ導入や自前で実装する必要があります。
大規模で使用されるシステムの場合は、Spring BootとかLaravelのほうが良いかなと思いました。
もしくは 最近開発が進んでいる「Serverpod」、「Dart Frog」などもより安定すればAll Dartのバックエンドの選択肢になると思います!
すでにバックエンドでDartを採用されている企業もあるので、どんなふうにしているのか気になりました。