MongoDB

Finch uses the mongo_dart package for MongoDB. Configuration is set in FinchConfigs and the connection is managed automatically by FinchApp.

Configuration

FinchConfigs configs = FinchConfigs(
  dbConfig: FinchDBConfig(
    enable: true,
    host: env['MONGODB_CONNECTION'] ?? 'localhost',
    port: env['MONGODB_PORT'] ?? '27017',
    user: env['MONGODB_USER'] ?? 'root',
    pass: env['MONGODB_PASSWORD'] ?? 'password',
    dbName: env['MONGODB_NAME'] ?? 'my_app',
    auth: env['MONGODB_AUTH'] ?? 'admin',  // authentication source database
  ),
);

Finch generates the connection string automatically: mongodb://user:pass@host:port/dbName/?authSource=auth

Accessing the Database

var db = app.mongoDb; // returns mongo_dart Db instance

Check connection status:

if (app.mongoDb.isConnected) {
  // safe to query
}

DBCollection

DBCollection is the Finch base class for MongoDB collection wrappers. Extend it to define type-safe query methods for your collection:

import 'package:finch/finch_model.dart';
import '../app.dart';
import '../models/example_model.dart';

class ExampleCollections extends DBCollection {
  ExampleCollections() : super(db: app.mongoDb, name: 'example');

  Future<ExampleModel> insertExample(ExampleModel model) async {
    var res = await collection.insert(model.toJson());
    return ExampleModel.fromJson(res);
  }

  Future<List<ExampleModel>> getAllExample({
    int? start,
    int? count,
  }) async {
    start = (start != null && start > 0) ? start : null;
    var rows = await collection
        .modernFind(
          limit: count,
          skip: start,
          sort: DQ.order('_id'),
        )
        .toList();
    return ExampleModel.fromListJson(rows);
  }
}

collection is the underlying mongo_dart DbCollection. DQ is a query builder alias re-exported from finch_model.dart.

Querying Data

Use modernFind for queries:

// Find all, sorted by _id descending
var rows = await collection
    .modernFind(
      sort: DQ.order('_id', descending: true),
    )
    .toList();

// Find with filter
var rows = await collection
    .modernFind(
      filter: where.eq('slug', 'my-slug'),
      limit: 10,
      skip: 0,
    )
    .toList();

Model

Finch models are plain Dart classes that implement JSON serialisation. A typical model:

class ExampleModel {
  String? id;
  String title;
  String slug;

  ExampleModel({this.id, required this.title, required this.slug});

  Map<String, dynamic> toJson() => {
    if (id != null) '_id': id,
    'title': title,
    'slug': slug,
  };

  factory ExampleModel.fromJson(Map<String, dynamic> json) => ExampleModel(
    id: json['_id']?.toString(),
    title: json['title'] ?? '',
    slug: json['slug'] ?? '',
  );

  static List<ExampleModel> fromListJson(List<Map<String, dynamic>> list) =>
      list.map(ExampleModel.fromJson).toList();
}

Using the Collection in a Controller

class HomeController extends Controller {
  Future<String> exampleDatabase() async {
    var col = ExampleCollections();

    if (rq.isPost) {
      var model = ExampleModel(
        title: rq.get<String>('title', def: ''),
        slug: rq.get<String>('slug', def: ''),
      );
      await col.insertExample(model);
      return rq.redirect('/example/database');
    }

    var items = await col.getAllExample(count: 20);
    rq.addParam('items', items.map((e) => e.toJson()).toList());
    return rq.renderView(path: 'example/database');
  }
}