この記事はDart Advent Calednar 22日目の記事です(遅刻してしまいすいません……)。この記事ではJaguarというDartのサーバーサイドフレームワークの説明をしていきます。
Jaguar は Dart のサーバーサイドフレームワークです。
ORM や Serialization、Auth 等の基本的な機能を揃えたサーバーサイドフレームワークとなっています。サンプルプロジェクトも豊富にあるので、導入も簡単にできそうですね。まだドキュメントが整備段階のようなので、試してみたい方に簡単な特徴の説明等をしていきます。
セットアップ
Jaguar をとりあえず試してみるのは簡単です。
name: jaguar_example
version: 0.0.1
dependencies:
jaguar: ^2.2.6
import 'package:jaguar/jaguar.dart';
main() => Jaguar(port: 8080)
..get('/about', (ctx) => 'Jaguar')
..postJson('/echo', (ctx) => ctx.bodyAsJson())
..serve();
$ pub get # 依存関係の解決
$ dart bin/main.dart
これだけで localhost:8080 にアクセスすればサーバーサイドのプログラムが実行されています。この辺の導入がシンプルなのはいいですね。
特徴
Routing
Jaguar のルーティングは簡単に記述・構成が可能です。
// その他の例はこちらに
/// https://github.com/Jaguar-dart/jaguar/wiki/Powerful-path-matching
/// https://github.com/Jaguar-dart/jaguar/wiki/Path-parameters
/// 詳しい記事 https://medium.com/@tejainece/route-paths-and-path-variables-in-jaguar-dart-344525b94542
main(){
final server = Jaguar();
// シンプルなレスポンス
server.get('/',(Context ctx) => 'Hello World!');
server.post('/',(Context ctx) => 'Hello World!');
// パラメータ指定
final UserName = <String>[
'Bob',
'Alice',
'Anyone'
];
server.get('/api/user/:id',(Context ctx){
final int index = ctx.queryParams.getInt('id', 1);
return quotes[index - 1];
})
// glob
server.get('/api/v1/*',(_) => new Response('Depreacted',statusCode: 500));
}
もちろん直で Routing をするのが必須なわけではありません。Controller classを利用することで継承が可能になっています1。
import 'dart:async';
import 'package:jaguar/jaguar.dart';
import 'package:jaguar_reflect/jaguar_reflect.dart';
/// Collection of routes students can also access
@GenController(path: '/books')
class BookRoutes extends Controller {
@GetJson()
List<String> getAllBooks(Context ctx) => <String>['the dummy book title'];
}
@GenController(path: '/api')
class LibraryApi extends Controller {
@IncludeController()
final book = BookRoutes();
}
main() async {
final server = Jaguar(port: 10000);
server.add(reflect(LibraryApi()));
server.log.onRecord.listen(print);
await server.serve(logRequests: true);
}
JSON Serialization
JSONへのSerializationはシンプルに行うことが出来ます。
server.post('/api/book', (Context ctx) async {
final Map<String, dynamic> json = await ctx.req.bodyAsJsonMap();
Book book = new Book.fromMap(json);
});
json_serializable等のライブラリと組み合わせて使えば簡単にシリアライズ・デシリアライズが可能です。
ユーザー認証
UserFetcher
というクラスを継承することで、ユーザー認証を行うことが出来ます。UserFetcher
自体はAbstract Classなので、継承を行い実装していくパターンですね。公式ではFacebook認証用のライブラリもあります。Postgresqlでの実装のサンプルも参考になると思います。
Session
リクエストハンドラでSessionを簡単に扱うことができます。
server.get('/example', (ctx) async {
final Session session = await ctx.session;
session['item'] = 'test';
return session['item'];
});
ドキュメントにもある通り、Session管理としては、CookieやMongodb、JWTを選ぶことが可能です。
データベース
ORMが存在しており、Modelの定義に対してModelBeanを作成することでORMとして機能するようになっています。
class Book {
@PrimaryKey(auto: true)
int id;
String title;
String author;
}
@GenBean()
class BookBean extends Bean<BookBean> with _BookBean {
BookBean(Adapter adapter) : super(adapter);
@override
String get tableName => 'bookBean';
}
これに対してbuild_runnerを走らせると、自動的にデータベース用のソースコードが出力されます。
まとめ
簡単でしたがJaguarの特徴をまとめました。JaguarはDart2.0に対応していることもあって非常に扱いやすいフレームワークになっていると思います。source_genやAngular Dartとの連携も考えてあるのも嬉しいポイントかなと。まだドキュメント周りが多少整っていないので、少しでも使うためのハードルを下げられたら幸いです。
-
jaguar_reflectをdependenciesに追加する必要があります ↩