PLEASE NOTE: As of Dart 2 the API for Aqueduct has changed, leading to breaking changes. This article was based on Aqueduct 2.5.0 for Dart v1.
I have updated this as a new video series: http://bit.ly/aqueduct-tutorial
In this new series on yet another RESTful API tutorial (#yetanotherrat), we will be exploring the Dart platform and its offering when it comes to building server-side applications.
Following on from my last post exploring the Dart language, I’d also been investigating how one might go about building RESTful services with Dart. Some further digging and I stumbled across Aqueduct by Stable Kernel. I was impressed at first glance seeing that it has already passed version 2 and once I figured the documentation was comprehensive with easy-to-follow examples, I was convinced to explore further.
Upon the experience of such a productive and refreshing time going through its documentation and following their example, I am now pleased to be taking you on this journey with me to build a working api from start to finish!
Prefer a video? Watch on Youtube
So what's Aqueduct?
Well it’s an open-source framework for creating and deploying RESTful web apis on the server. It has a similar flavour to Express and Hapi, even .NET Web API, offering a point of entry with a comprehensive list of features.
My favourite ones are:
- Fluid, chainable routing. A functional style to composing your routes and its handler methods
- A CLI tool. This allows you to scaffold your next project by issuing commands
- Multi-threading out of the box. Spins up multiple instances of your application via Dart's "isolates", scaling across all CPU cores on the server.
- Has an inbuilt ORM. A must-have if you work with relational databases! Also supports databse migration.
- Has an integrated testing library. Because you need to test all the things! Plays well with tools like TravisCI.
In the series we will be building an api for a personal reading list (let’s call it FaveReads 📚), covering these topics:
- Part 1: Setting up and running the example (we're here)
- Part 2: Implementing routing with CRUD operations
- Part 3: Connecting Web APIs to SQL database
- Part 4: Writing automated tests
- *Bonus content* DB Migration and Model Relationships 😄
Setting up and running the example
If you haven’t already, I’d encourage you to install the Dart SDK. It’s got instructions for Windows, Mac and Linux.
You can confirm you have Dart running by checking the terminal:
dart --version
Dart comes with a tool called pub to manage its packages. Let’s use this tool to install Aqueduct:
pub global activate aqueduct
This gives us access to the aqueduct
executable. Change to your working directory and let us create our project:
aqueduct create fave_reads && cd fave_reads
You should now be in the fave_reads
directory with all the project files. For now we'll focus on:
bin/
main.dart
lib/
fave_reads_sink.dart
pubspec.yaml
- bin/main.dart creates our server and starts the app
- lib/fave_reads_sink.dart sets up your application with its configuration
- pubspec.yaml contains metadata about the project. Similar to having a package.json for Node.js development
Let’s start the application using either commands below:
aqueduct serve # or `dart bin/main.dart`
And here we go:
We now have a server running at http://localhost:8081
with /example
being the only created route. Accessing http://localhost:8081/example
will return the response below:
{ "key": "value" }
At this point its worth mentioning that Aqueduct has the concept of a RequestSink, which according to the documentation:
handles the initialization of an application, including setting up routes, authorization and database connections.
An application needs one RequestSink
subclass to enable it to receive requests. Our example has a FaveReadsSink
extending the base RequestSink
class to enable us to override its methods with our own implementation. These are setupRouter
and willOpen
. The first method will allow us to define our routes with associated controllers and other middleware, while the latter allows us to perform any asynchronous initialisation after the routes are set up and before the application can receive requests.
The default response type is set to JSON for current requests. However this can be set to whatever content type is appropriate to meet our needs.
Let’s demonstrate this by creating a second route in setupRouter method:
router.route('/').listen((request) async {
return new Response.ok('Hello world')
..contentType = ContentType.TEXT;
});
Using method cascades, we are able to set the contentType
property to text/plain
. The ContentType
utility comes inbuilt with Dart and can be used through the style below:
new ContentType(primaryType, subType, {String charset, Map parameters});
It’s already got constants for HTML, JSON and TEXT so in most scenarios you should just use those.
Now restart the server by killing the current process and running aqueduct serve
again. Accessing the root path should now give you this:
Before we wrap up, lets scale up our application instances to the number of cores we have. In bin/main.dart it is currently set to 2 when app.start is invoked:
await app.start(numberOfInstances: 2);
To resolve this, we will import Dart’s Platform class from the “dart:io” library and amend main.dart as follows:
import 'dart:io' show Platform;
Future main() async {
...
...
await app.start(numberOfInstances: Platform.numberOfProcessors);
...
}
Some development tips for VS Code 👈
Firstly, make sure to install the Dart extension by Dart Code, to enable Dart and Flutter support.
Secondly, add a launch configuration for Dart with this setting:
{
"name": "Dart",
"type": "dart",
"request": "launch",
"program": "${workspaceFolder}/bin/main.dart"
}
This will allow you to run the app through VS Code with the ability to add breakpoints to help with debugging.
Before we wrap up, I want to ask you something…What do you expect to gain at the end of this series? Add a comment below to let me know, thanks.
And this concludes Part 1 of the series. The code for this series is available on github and will be updated as we go through the series. Stay tuned for more.
Further reading
- Aqueduct documentation
- Getting started with Pub
- Presentation by Joe Conway at Dart Developer Summit 2016
Article No Longer Available
Originally posted on Medium
Top comments (13)
August 12, 2018
As of Dart 2: I want to clarify things that needs to be changed.
to
Although I would like to point out many things, it's better to check out in their documentation because a lot of it are deprecated.
Have a great day!
Thanks Vince. Will do the rounds and make the edits soon.
HI jermaine,
I had problem running "pub global activate aqueduct" i get this error
"%1 is not a valid Win32 application.
Command: C:\Program Files\Dart\dart-sdk\lib_internal\pub\asset\7zip\7za.exe e data.tar.gz
can you help resolve this error
Hi @faridak ,
Thanks for going through this tutorial series. I did some digging around and it appears to be a Windows related issue, caused when having spaces in your path, so "Program Files".
You can follow the recommended solution via that link, or even better install Dart through the Chocolatey package manager for Windows. It should be placed on a path without spaces.
Try and let me know how that turns out.
Hi Jermaine,
I did the install using Chocolatey, and this error remains.. I know it is a windows relates that the path is not defined .. but hot to set the Path so it can work... i am stuck in the installation.
Will appreciate if you can help, otherwise thank you.. .it frustrates me ..
The path is defined, its just that the Program Files folder has got spaces in it. It may be that the previous install of Dart is taking precedence over the Chocolatey install.
Can you confirm that running
where dart
in the command prompt is showingC:\tools\dart-sdk\bin\dart.exe
? If its not happening then try these steps:C:\Program Files...
C:\tools\dart-sdk\bin
to your Path in Environment Variables.where dart
to confirm the correct path is showingOr you could just remove all installs of Dart, including Chocolatey's one and reinstall using Chocolatey. Should fix the path 🤞
Hi Jermain, nice article.
Dart is very very easy to set up :-) I'll be following along hoping to get some familiarity before checking out Flutter!
Hey Rhymes,
Thanks for the feedback. I'm very pleased that you found Dart easy to set up, since first impressions really count. Part 2 will be out this week and I intend on keeping myself accountable.
Part 2 is now available 😊 – dev.to/graphicbeacon/building-rest...
Nice article, I hope by the end of your series, I will understand RESTful Web APIs.
Hey Rameses, thanks for the feedback. This article assumes you have a general understanding of RESTful Web APIs. However, I hope you see how they can be applied in a real world scenario via the Dart platform.
I can't unable to create project using aqueduct create cmd, pls guide me how can I install on Windows.
Hi Arun, please see the updated video series on get started bit.ly/aqueduct-tutorial
Install Aqueduct on Windows by running
pub global add aqueduct
, assuming you've installed Dart already. See this lesson for details on installing Dart for Windows.