A lot of neat stuff came out of DartConf 2018, and it’s clear Google is taking Dart’s future seriously. Much of its focus is on improving the development of client-side applications with Flutter and AngularDart. Focus is good; it’s how things get done. A few folks are concerned this focus diminishes the ability to write server-side apps in Google’s Dart – this concern is overblown.

Behind the marketing, server-side development with Dart is only improving. The primary focus of Dart 2 is building a common front-end that Dart code is processed through; code will go through the same toolchain, regardless of whether it targets the Dart Virtual Machine or JavaScript. If you’re a Dart server-side developer, this is great news – it’s not even worthwhile to stop supporting server applications written in Dart. (By the way, did you know that neither Flutter or server-side Dart are compiled to JavaScript?)

More importantly, the HTTP server libraries are being moved to their own package for faster development without being tied to SDK releases. Activity has picked up on an HTTP/2 implementation maintained by Google.

Our developers who work on Aqueduct – the open-source server-side framework for building HTTP APIs – are very excited about Dart 2. We are already a few months into development for Aqueduct 3 for Dart 2, and we’ve already been running the framework’s 1300 tests against the Dart 2.0 dev SDK.

In this post, I will cover the new features of Aqueduct 3, an overview of things that are coming (or are already available), and instructions for running the pre-release version.

New Features in Aqueduct 3

You can follow development by viewing the changelog on the 3.0 branch. Here are a few of the big features that are currently in progress.

Document Data Structures in the ORM

Aqueduct’s ORM targets PostgreSQL. It is often cumbersome to manage unstructured data in a typical relational database. PostgreSQL has a solution: JSONB columns. A JSONB column stores unstructured, binary JSON data. Aqueduct’s ORM adds support for JSONB columns by introducing a Document data type. Database objects declare fields of this type to add JSONB columns to their underlying table. Additional syntax has been added to Query to use the contents of Document columns in building queries.

See the pre-release documentation guide for more details.

OpenAPI 3.0 Auto-Documentation

Aqueduct 2 loosely supported auto-generation of Swagger documents, but it was largely experimental. Work has already been completed in Aqueduct 3 to support OpenAPI 3 document generation. In most cases, you only need to define the possible responses for your endpoints – Aqueduct reflects on your codebase to figure out the rest.

By adding support for OpenAPI 3.0, you can leverage open-source tools for documentation viewers and source code generation on multiple platforms.

See the pre-release documentation guide for more details.

Better Support for OAuth 2.0 Scopes

Aqueduct already ships with an OAuth 2.0 server implementation. It is easy to set up per-route scope restrictions, but the operation-level scope wasn’t as simple as it needed to be. Aqueduct 3 adds a Scope annotation that lets you define scope restrictions for each operation – i.e., POST /users requires different scope than GET /users.

See the pre-release documentation guide for more details.

Changes to Existing APIs

Like most Dart codebases, some of the changes to Google’s Dart 2 will require changes to Aqueduct. We think all of these changes will be a net-benefit to Dart and Aqueduct developers.

Query.where syntax

Folks love Aqueduct’s statically-typed ORM. A change to the Dart 2 runtime will require the way you build the WHERE clause of the query to change slightly, but we think for the better. Instead of assigning expressions to an object’s properties, you will use a property selector. If you have used joins, paging or sorting queries, property selectors will look familiar.

final q = Query<Employee>() ..where((e) => e.lastName).equalTo("Smith") ..sortBy((e) => e.firstName, QuerySortOrder.ascending); final sortedEmployeesWithSmithLastName = await q.fetch();

This new syntax has the added benefit of an additional static type-check on values provided to expression-adding methods like equalTo.

Simplified Initialization

Application initialization has been simplified – you override two methods: one to create services and the other to create your controllers that handle requests. Controllers are now linked together using a single method.

class MyApp extends ApplicationChannel { AuthServer authServer; @override Future prepare() async { authServer = AuthServer(...); } @override Controller get entryPoint { final router = Router(); router.route(“/path”) .link(() => Authorizer(authServer)) .link(() => Controller()); return router; } }

Clearer Annotations

Aqueduct makes liberal use of annotations when defining your data model and request handling code. Some of these annotations had rather long, or in some cases, confusing names. When combined with the Dart standard 80 character columns, annotations made code more difficult to read. Here are some examples of improved annotations in Aqueduct 3.

class NoteController extends ResourceController { @Operation.get() Future getAllNotes({@Bind.query(‘since’) DateTime since}) async => …; @Operation.get(‘id’) Future getNote(@Bind.path(‘id’) int id) async => …; @Operation.post() Future createNote(@Bind.body() Note note) async => …; } class Note extends ManagedObject<_Note> implements _Note {} class _Note { @primaryKey int id; @Column(indexed: true) String contents; @Relate(#notes, onDelete: DeleteRule.cascade) User owner; }

Using Aqueduct 3 Pre-Release

You’ll need to upgrade to the developer release of Dart 2.0. On macOS, you install with Homebrew:

brew upgrade dart --devel

For other platforms, see this page.

Once you have Dart 2.0, clone Aqueduct locally, switch to the 3.0 branch and install the CLI from your local repository.

git clone git@github.com:stablekernel/aqueduct.git cd aqueduct git checkout 3.0 git pull pub global activate -spath .

Then create a new project that targets Aqueduct 3.

cd <your-project-directory> aqueduct create my_app

Because your project was created from a local version of Aqueduct, its pubspec.yaml file will point to that directory on your filesystem. To stay up to date with 3.0 (or to build remotely), change your pubspec.yaml file to reference the 3.0 branch on GitHub:

aqueduct: git: url: git@github.com:stablekernel/aqueduct.git ref: “3.0”

The documentation guides are updating as part of each change to the framework. You can view the current state of the documentation at https://aqueduct.io/prerelease-3.0/docs/.

If you are already using Aqueduct and are looking to migrate to 3.0, stop by the Slack Channel.