Dart backendを試す
Flutter には盛り上がりがみられる Dart でバックエンドもやってみました. この時気になるのがフレームワークどうするか問題ですね. メジャーどころは下記の 2 つです.
最終 commit 2020/09/01
最終 commit 2020/05/05
とこんな感じで開発はどちらも止まっており,もはや選択肢に入らない状態です. というわけで shelf と shelf_router で実装するのがよさそうな雰囲気です.
ひな形が stagehand で作れるのでそちらで. ただし,shelf_router は初期だと含まれていないので pubspec.yaml に追加してください.
$ stagehand server-shelfCreating server-shelf application `server_test`: /home/yuzumone/server_test/.gitignore /home/yuzumone/server_test/CHANGELOG.md /home/yuzumone/server_test/README.md /home/yuzumone/server_test/analysis_options.yaml /home/yuzumone/server_test/bin/server.dart /home/yuzumone/server_test/pubspec.yaml 6 files written.--> to provision required packages, run 'pub get'--> run your app via `dart bin/server.dart`.初期 server.dart は下記の通り.
import 'dart:io';import 'package:args/args.dart';import 'package:shelf/shelf.dart' as shelf;import 'package:shelf/shelf_io.dart' as io;// For Google Cloud Run, set _hostname to '0.0.0.0'.const _hostname = 'localhost';void main(List<String> args) async { var parser = ArgParser()..addOption('port', abbr: 'p'); var result = parser.parse(args);// For Google Cloud Run, we respect the PORT environment variable var portStr = result['port'] ?? Platform.environment['PORT'] ?? '8080'; var port = int.tryParse(portStr);if (port == null) { stdout.writeln('Could not parse port value "$portStr" into a number.'); // 64: command line usage error exitCode = 64; return; }var handler = const shelf.Pipeline() .addMiddleware(shelf.logRequests()) .addHandler(_echoRequest);var server = await io.serve(handler, _hostname, port); print('Serving at http://${server.address.host}:${server.port}');}shelf.Response _echoRequest(shelf.Request request) => shelf.Response.ok('Request for "${request.url}"');これを shelf_router を使っていい感じに GET と POST を生やしてみます. 下記の感じで handler のところを書き換えます. shelf_router を使うと対応 method と endpoint が分かりやすくなります. ちなみに shelf_router の README では app.handler を渡す感じで記載されていますが,deprecated になっており,下記のように app 自体を渡すのが正解です.
var app = Router();app.get('/status', (shelf.Request request) { return shelf.Response.ok('ok');});app.post('/post', (shelf.Request request) async { final content = await request.readAsString(); final data = json.decode(content); return shelf.Response.ok('Hello, ${data["text"]}');});var server = await io.serve(app, _hostname, port);せっかく生やしたので叩いてみます.
$ curl http://localhost:8080/statusok$ curl -X POST -d '{"text": "world"}' http://localhost:8080/postHello, worldちなみに shelf_router_generator という package もありこちらは Flask のようにデコレータで method や endpoint を指定できます. こっちも良さそうです.
shelf_router_generator | Dart Package
あとこれは完全に備考ですが,shelf はもちろん dart2native に対応しています. Aqueduct は対応していなかったので一応.
$ dart2native bin/server.dart -o testGenerated: /home/yuzumone/server_test/test