Dart Shelf — Backend with Dart

Filipe A. Barroso
4 min readNov 5, 2021

--

Photo by Museums Victoria on Unsplash

This article is mostly a gathering of examples from Shelf and its official add-ons. Where I add my own comments that helped me understand the project and building a web server with Shelf, more about that in the end of the blogpost.

Shelf, is a Web Server Middleware, not a full blown server framework like Django, it is modular, and you add add-ons for the functionalities you need. This modular structure gives the community an easy way to expand the project.

While other Dart for backend solutions exist. At the time of writing, two of the most promising Dart server frameworks, Aqueduct and Angel, have stopped their development. Relying on the community to grab where they left and continuing the work done. While from Angel came Angel3 and from Aqueduct came Conduit, I prefer to use a more stable solution, stable as maintained by a team with more resources. So, never forget to support the open-source community projects!

Shelf, is maintained by the Dart team itself but still lacks functionalities, again because is not a server framework. If we want Shelf to compete with other server frameworks, such as Django (Python) it is necessary quite a bit of work. However, at the current status, we can create a web server that suits our needs.

These are the official add-ons maintained by the Dart team:

  • Shelf (core)
  • Shelf Router
  • Shelf Router Generator
  • Shelf Static
  • Shelf WebSocket
  • Shelf CORS Headers

Starting a backend Project

I am assuming you have Dart installed on your machine, if not you can follow the instructions at https://dart.dev/get-dart.

To run a server you need to create a new Dart project, I’ll be using the terminal and the following command

dart create shelf_core_example

This will create a folder with all the code inside shelf_core_example if you move into the new folder created you will notice the following file structure

CHANGELOG.md 
analysis_options.yaml
pubspec.lock
pubspec.yaml
README.md
bin/shelf_core_example.dart # Same name as the project name created

The file shelf_core_example.dart has a simple main file.

void main(List<String> arguments) {
print('Hello world!');
}

You can run the existing file, with a simple command:

dart run bin/shelf_core_example.dart

Then you will be prompted with the following message

$ dart run bin/shelf_core_example.dart 
Hello World!

Adding Shelf

package: https://pub.dev/packages/shelf

Now that you have the project created, to use Shelf we simply add a Dart package dependency.

In the project root you can add it by running the following:

dart pub add shelf

Now you are ready to work on your dart server! This command will also be used to add the other Shelf add-ons we will later add.

Shelf Example

Adding Add-ons

The core library for Shelf, gives you the main functionalities of a server. The following example shows the barebones of a simplest server you can start running with Shelf.

Shelf Router

package: https://pub.dev/packages/shelf_router

While Shelf (core) lacks the functionality of setting Routes, we use the add-on shelf_router which will give you the router instance, with all the REST methods, such as GET and POST and all other calls that make up REST.

dart pub add shelf_router

Shelf Router Example

With the previous code setup you can now run the server in the root of the project simply by executing

Shelf Router Generator

package: https://pub.dev/packages/shelf_router_generator

To reduce boilerplate, the add-on shelf_router_generator helps us with the code generation. The add-on gives us annotations that replaces the need to call the 'router' instance.

Shelf router generator leverages build_runner to generate code, check the bullet Dependency for more information.

dart pub add shelf_router_generator

Dependency

package: https://pub.dev/packages/build%5Frunner

To learn on how to use build_runner check check the package URL.

Add the build_runner has dev_dependencies

dart pub add builder_runner

Shelf Router Generator Example

You need run once the build_runner and only then the dart run.

Shelf Static

If you need server side processing, to show an html page, you will need to add this add-on so that so you can present the users to

package: https://pub.dev/packages/shelf_static

dart pub add shelf_static

Shelf Static Example

Shelf WebSocket

package: https://pub.dev/packages/shelf_web_socket/

With Shelf, you don’t necessary need to work with HTTP, you also have the possibility to have a socket open through shelf_web_socket might be an add-on that not everyone uses, but it is interesting to know that it has.

dart pub add self_web_socket

Shelf WebSocket Example

To test this server with Web Socket I used the “Simple WebSocket Client” plugin for Chrome.

Shelf CORS Headers

package: https://pub.dev/packages/shelf_cors_headers

Last but not least, we have this add-on to help us change the headers to have CORS working locally. Exposes a method called corsHeaders() that returns a Middleware used in the Shelf Pipeline.

Do not confuse this add-on with shelf_cors that is not available for Dart 2.0

dart pub add shelf_cors_headers

Shelf CORS Headers Example

Conclusion

While we wait for other Dart server frameworks to mature, we can always rely on Shelf to implement our project. There is still a lot needed to implement and few add-ons available that extends Shelf ( https://pub.dev/packages?q=shelf)

Next article on the topic of Dart Backend will be about integrating Stripe into a server to pay recurrent or by metered API consumption. If I see myself using other Shelf add-on I’ll write a new blogpost

Originally published at https://filipebarroso.com on November 5, 2021.

--

--

Filipe A. Barroso

Hi friend 👋 / I'm a Software Developer 💙 I Code, Teach and Share / Community Organizer - Flutter Portugal, and GDG Lisbon