We will cover briefly:

  1. Writing dart server API
  2. Deploying on Cloud Run

Note: This article assumes the reader knows about Cloud Run, and GCP.

Writing dart server API

Upgrade to the latest version of Dart 2.13

Dart version 2.13

There are two ways of writing server API

  1. Manually create each file, place them correctly, and fail
  2. Use a scaffolding (a pre defined folder structure with minimum necessary files)

We will go with point 2

Introducing Stagehand : A Dart Project Generator

  • This will help us in getting all the necessary files packed together in a folder.
  • Install this via
dart pub global activate stagehand
  • Once installed, you have now access to following generator commands
Stagehand generators
Stagehand generators
  • For our case we will go with
stagehand server-shelf

and we get the folder structure as 

Web server folder structure
Web server folder structure
  • Looking into the pubspec.yaml, we have the dependencies for shelf and args

For package args: 

  • It is useful for command line applications, where we supply arguments

What is Shelf?

It helps to create and compose web servers. 

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;

// For Google Cloud Run, set _hostname to ''
const _hostname = '';

void main() async {
  var handler =
      const  Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);
var server = await shelf_io.serve(handler, _hostname, 8080);
Response _echoRequest(Request request) =>
    Response.ok('Hello world');
  • Package shelf is imported by default inside our server.dart
  • We create a handler _echoRequest

A handler is basically something that handles a request (shelf.Request) and gives back a response (shelf.Response)

In our case, we return the response as “Hello World”.

  • Let’s say we want to log the requests(logRequests) to our api, we need to add another handler.

Here comes the concept of Pipeline

Pipeline is a combination of middleware and a handler.

  • We add in the logRequests, which is predefined inside the shelf.

Think of middleware as a function that takes a handler and wraps it in another handler to provide additional functionality

  • To start the server, we call in the serve function. 

Starts an HttpServer that listens on the specified address and port and sends requests to handler.

handler: defined earlier

address: We are using (for cloud run, see next step)

port: 8080

Deploying on Cloud Run

It was announced in Google I/O 2021, that Dart is now available as Docker Official Images

According to the announcement

“The new Dart images are tested and validated by Docker to follow best practices”.

They also support ahead-of-time (AOT) compilation, which can dramatically reduce the size of built containers and can improve the speed of deployment in container environments — like Cloud Run.

Let’s deploy our hello_world application now

  • Create a docker file and put the contents from here
  • We will be building a docker image using the command
docker build -t hello_world .

Note: This requires the docker to be installed on your machine. Refer this

  • Run the image (you built from step2) locally using
docker run -it -p 8080:8080 \hello_world:latest
  • When tested, you can stop the container using
// For getting container id, you can use
docker ps

docker stop [YOUR CONTAINER ID]

Time to deploy this image(from above), to Cloud Run.

  • Make sure you have the Google Cloud SDK installed on your machine. Refer this.

Note: You also need a GCP project with billing enabled.

  • Authenticate your user account with the gcloud CLI using
gcloud auth login
  • List your projects and set the preferred project
// List your GCP projects
gcloud projects list

// Set your project
gcloud config set project \

Now we need to publish our image inside the Google Container Registry (storing our docker image in GCP) using

gcloud builds submit --tag gcr.io/[YOUR-PROJECT-ID]/hello_world
// Replace [YOUR-PROJECT-ID] with your project id
  • Finally, we deploy this container image to Cloud Run using
gcloud run deploy --image gcr.io/[YOUR-PROJECT-ID]/hello_world
// Replace [YOUR-PROJECT-ID] with your project id

Reference to commands here

  • If all successful, you will see an endpoint after the previous step.

Endpoint (for my case): https://helloworld-rahizluroq-uc.a.run.app

What’s next

Dart team is bringing the Functions Framework for Dart

  • a collection of packages, tools, and examples to write Dart functions to deploy for handling HTTP requests and CloudEvents.
Source code

Valuable comments