Aqueduct

Aqueduct #

Aqueduct sudah tidak aktif dikembangkan. Package terakhir dirilis untuk Dart 2.x dan tidak kompatibel dengan Dart 3.x. Jika kamu memulai project baru, gunakan Conduit — fork resmi Aqueduct yang aktif dikembangkan dengan API yang hampir identik. Artikel ini tetap relevan sebagai referensi untuk memahami codebase Aqueduct yang sudah ada, dan panduan migrasi ke Conduit.

Aqueduct adalah framework web server Dart yang sangat berpengaruh — memperkenalkan konsep ORM berbasis Dart, autentikasi OAuth2 terintegrasi, dan migration database ke ekosistem Dart jauh sebelum alternatif lain ada. Banyak tutorial, artikel, dan codebase di internet masih menggunakan Aqueduct. Memahami Aqueduct — terutama bedanya dengan Conduit — penting jika kamu bekerja dengan kode yang sudah ada atau membaca dokumentasi lama.

Sejarah Singkat #

flowchart LR
    A["Aqueduct\n2016-2021\nAktif dikembangkan\nPopular di Dart 2.x"] -->|Tidak kompatibel Dart 3\nMaintainer berhenti| B["Abandoned\n2021+"]
    B -->|Community fork\nAktif dikembangkan| C["Conduit\n2021-sekarang\nKompatibel Dart 3\nAPI hampir identik"]
Aspek Aqueduct Conduit
Status ❌ Deprecated ✅ Aktif
Dart 3 support ❌ Tidak ✅ Ya
API Original Hampir identik
Package aqueduct conduit_core
CLI aqueduct conduit
Migration dari Aqueduct Mudah (perubahan minimal)

Konsep Inti Aqueduct yang Masih Relevan #

Meski Aqueduct sudah deprecated, konsep-konsepnya hidup di Conduit. Memahami Aqueduct berarti memahami fondasi Conduit:

ApplicationChannel #

// Aqueduct — ApplicationChannel
import 'package:aqueduct/aqueduct.dart';

class TokoChannel extends ApplicationChannel {
  ManagedContext? context;

  @override
  Future prepare() async {
    final config = TokoConfig(options!.configurationFilePath!);
    final dataModel = ManagedDataModel.fromCurrentMirrorSystem();
    final psc = PostgreSQLPersistentStore(
      config.database.username,
      config.database.password,
      config.database.host,
      config.database.port,
      config.database.databaseName,
    );
    context = ManagedContext(dataModel, psc);
  }

  @override
  Controller get entryPoint {
    final router = Router();

    router
      .route('/produk/[:id]')
      .link(() => ProdukController(context!));

    return router;
  }
}
// Conduit — hampir identik, hanya import yang berbeda
import 'package:conduit_core/conduit_core.dart';  // bukan aqueduct

class TokoChannel extends ApplicationChannel {
  // Kode yang sama persis dengan di atas
}

ResourceController #

// Aqueduct
import 'package:aqueduct/aqueduct.dart';

class ProdukController extends ResourceController {
  ProdukController(this.context);
  final ManagedContext context;

  @Operation.get()
  Future<Response> ambilSemua() async {
    final query = Query<Produk>(context);
    final hasil = await query.fetch();
    return Response.ok(hasil.map((p) => p.asMap()).toList());
  }

  @Operation.get('id')
  Future<Response> ambilSatu(@Bind.path('id') int id) async {
    final query = Query<Produk>(context)
      ..where((p) => p.id).equalTo(id);
    final produk = await query.fetchOne();
    if (produk == null) return Response.notFound();
    return Response.ok(produk.asMap());
  }
}
// Conduit — IDENTIK, hanya import yang berbeda
import 'package:conduit_core/conduit_core.dart';

class ProdukController extends ResourceController {
  // Kode yang sama persis
}

ManagedObject / ORM #

// Aqueduct — definisi model
import 'package:aqueduct/aqueduct.dart';

class Produk extends ManagedObject<_Produk> implements _Produk {}

class _Produk {
  @primaryKey
  int? id;

  String? nama;
  double? harga;
  bool? aktif;
}
// Conduit — IDENTIK
import 'package:conduit_core/conduit_core.dart';

class Produk extends ManagedObject<_Produk> implements _Produk {}
class _Produk {
  @primaryKey
  int? id;
  String? nama;
  double? harga;
  bool? aktif;
}

Panduan Migrasi Aqueduct → Conduit #

Migrasi dari Aqueduct ke Conduit relatif mudah karena API-nya hampir identik. Yang perlu diubah:

1. pubspec.yaml #

# SEBELUM (Aqueduct)
dependencies:
  aqueduct: ^4.0.0

dev_dependencies:
  aqueduct_test: ^4.0.0

# SESUDAH (Conduit)
dependencies:
  conduit_core: ^4.3.0
  conduit: ^4.3.0

dev_dependencies:
  conduit_test: ^4.3.0

2. Import Statements #

// SEBELUM — semua import dari aqueduct
import 'package:aqueduct/aqueduct.dart';
import 'package:aqueduct_test/aqueduct_test.dart';

// SESUDAH — ganti ke conduit
import 'package:conduit_core/conduit_core.dart';
import 'package:conduit_test/conduit_test.dart';

Cara paling cepat untuk mengganti semua import di project:

# Ganti semua import aqueduct ke conduit secara sekaligus
find lib test -name "*.dart" -exec sed -i \
  "s/package:aqueduct\/aqueduct.dart/package:conduit_core\/conduit_core.dart/g" {} \;
find lib test -name "*.dart" -exec sed -i \
  "s/package:aqueduct_test\/aqueduct_test.dart/package:conduit_test\/conduit_test.dart/g" {} \;

3. CLI Commands #

# SEBELUM (Aqueduct CLI)
aqueduct create nama_project
aqueduct serve
aqueduct db generate
aqueduct db upgrade
aqueduct db upgrade --dry-run

# SESUDAH (Conduit CLI)
conduit create nama_project
conduit serve
conduit db generate
conduit db upgrade
conduit db upgrade --dry-run

4. Perubahan API yang Tidak Kompatibel #

Beberapa perubahan kecil yang mungkin ada:

// Beberapa nama kelas berubah (jarang)
// Aqueduct
import 'package:aqueduct/managed_auth.dart';
class Pengguna extends ManagedObject<_Pengguna>
    implements _Pengguna, ManagedAuthResourceOwner<_Pengguna> {}

// Conduit — nama package berbeda
import 'package:conduit_core/managed_auth.dart';
class Pengguna extends ManagedObject<_Pengguna>
    implements _Pengguna, ManagedAuthResourceOwner<_Pengguna> {}

Fitur Aqueduct yang Ada di Conduit #

Semua fitur utama Aqueduct tersedia di Conduit:

✅ ResourceController dengan @Operation dan @Bind
✅ ManagedObject ORM
✅ Query builder type-safe
✅ Migration database otomatis
✅ OAuth2 server (AuthServer, AuthController, Authorizer)
✅ ApplicationChannel
✅ Router dengan path parameter
✅ Testing dengan Agent/TestClient
✅ Configuration dari YAML
✅ Multiple isolate support

Contoh Lengkap: Kode Aqueduct yang Perlu Dimigrasikan #

Berikut contoh kode Aqueduct lengkap beserta versi Conduit-nya:

// AQUEDUCT — main.dart
import 'package:aqueduct/aqueduct.dart';

Future main() async {
  final app = Application<TokoChannel>()
    ..options.configurationFilePath = 'config.yaml'
    ..options.port = 8888;

  await app.start(numberOfInstances: 3, consoleLogging: true);
}

// CONDUIT — main.dart (identik)
import 'package:conduit_core/conduit_core.dart';

Future main() async {
  final app = Application<TokoChannel>()
    ..options.configurationFilePath = 'config.yaml'
    ..options.port = 8888;

  await app.start(numberOfInstances: 3, consoleLogging: true);
}
// AQUEDUCT — query.dart
import 'package:aqueduct/aqueduct.dart';

Future<List<Produk>> ambilProdukMahal(ManagedContext context) async {
  return await (Query<Produk>(context)
    ..where((p) => p.harga).greaterThan(5000000)
    ..sortBy((p) => p.harga, QuerySortOrder.descending)
    ..fetchLimit = 10
  ).fetch();
}

// CONDUIT — query.dart (identik)
import 'package:conduit_core/conduit_core.dart';

Future<List<Produk>> ambilProdukMahal(ManagedContext context) async {
  return await (Query<Produk>(context)
    ..where((p) => p.harga).greaterThan(5000000)
    ..sortBy((p) => p.harga, QuerySortOrder.descending)
    ..fetchLimit = 10
  ).fetch();
}

Kapan Masih Relevan Membaca Dokumentasi Aqueduct? #

Meskipun Aqueduct deprecated, ada beberapa situasi di mana dokumentasi dan tutorial Aqueduct lama masih berguna:

MASIH RELEVAN ketika:
  ✓ Memelihara codebase Aqueduct yang sudah ada dan belum bisa dimigrasikan
  ✓ Membaca tutorial lama (2018-2021) — konsep dan pattern yang sama
  ✓ Memahami keputusan desain Conduit (Conduit mewarisi filosofi Aqueduct)
  ✓ Belajar dari contoh kode Aqueduct — hampir semuanya berlaku di Conduit

TIDAK RELEVAN ketika:
  ✗ Memulai project baru — gunakan Conduit langsung
  ✗ Mengikuti setup/instalasi Aqueduct — CLI-nya tidak kompatibel Dart 3
  ✗ Menggunakan fitur yang spesifik Aqueduct 3.x ke bawah

Proyek yang Masih Menggunakan Aqueduct #

Jika kamu bergabung ke tim yang memiliki codebase Aqueduct lama, berikut pendekatan yang direkomendasikan:

1. Jika project masih berjalan dengan Dart 2.x — tidak perlu migrasikan segera
   Aqueduct bekerja fine di Dart 2.x. Prioritaskan fitur bisnis dulu.

2. Jika perlu upgrade ke Dart 3.x — migrasi ke Conduit tidak bisa dihindari
   Ikuti panduan migrasi di atas: ganti import, update pubspec.yaml, ganti CLI.

3. Jika codebase besar dan migrasi beresiko — lakukan secara bertahap
   Conduit dan Aqueduct bisa tidak berjalan bersamaan (conflict package),
   sehingga harus dimigrasikan sepenuhnya dalam satu langkah.

4. Uji semua test setelah migrasi — kemungkinan ada perbedaan minor
   Terutama pada behavior autentikasi dan beberapa query edge case.

Ringkasan #

  • Aqueduct sudah deprecated dan tidak kompatibel dengan Dart 3.x. Untuk project baru, gunakan Conduit yang merupakan fork aktif dengan API hampir identik.
  • Migrasi ke Conduit sangat mudah — ubah import dari package:aqueduct/aqueduct.dart ke package:conduit_core/conduit_core.dart, update pubspec.yaml, dan ganti CLI aqueduct dengan conduit.
  • Semua konsep Aqueduct berlaku di ConduitApplicationChannel, ResourceController, ManagedObject, Query, AuthServer, Router semuanya tersedia dengan nama dan API yang sama.
  • Tutorial dan artikel Aqueduct lama masih berguna untuk belajar konsep — cukup ganti nama package saat mengikuti contoh kode.
  • Dokumentasi resmi Conduit ada di conduit.dart.io — lebih akurat dan up-to-date dari dokumentasi Aqueduct yang lama.
  • Jangan install Aqueduct untuk project baru — package tidak kompatibel Dart 3.x dan tidak akan mendapat perbaikan bug atau security update.
  • Codebase Aqueduct yang sudah berjalan di Dart 2.x bisa tetap dibiarkan jika tidak ada kebutuhan mendesak untuk upgrade. Prioritaskan migrasi saat butuh Dart 3.x.
  • Import aqueduct/managed_auth.dart di Aqueduct menjadi conduit_core/managed_auth.dart di Conduit — salah satu perbedaan yang paling sering menyebabkan error saat migrasi.

← Sebelumnya: Conduit   Berikutnya: Angel →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact