DartDay 22

Dartのサーバーサイドフレームワーク Jaguarについて

この記事はDart Advent Calednar 22日目の記事です(遅刻してしまいすいません……)。この記事ではJaguarというDartのサーバーサイドフレームワークの説明をしていきます。

Jaguar は Dart のサーバーサイドフレームワークです。

ORM や Serialization、Auth 等の基本的な機能を揃えたサーバーサイドフレームワークとなっています。サンプルプロジェクトも豊富にあるので、導入も簡単にできそうですね。まだドキュメントが整備段階のようなので、試してみたい方に簡単な特徴の説明等をしていきます。


セットアップ

Jaguar をとりあえず試してみるのは簡単です。


pubspec.yaml

name: jaguar_example

version: 0.0.1
dependencies:
jaguar: ^2.2.6


bin/main.dart

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との連携も考えてあるのも嬉しいポイントかなと。まだドキュメント周りが多少整っていないので、少しでも使うためのハードルを下げられたら幸いです。





  1. jaguar_reflectをdependenciesに追加する必要があります