Building and Deploying a Dart Web Server

In this article, you will learn how to set up and deploy a simple Dart web server that exposes an API call to easily generate Stream user tokens, based on the provided user ID.

Reuben T.
Reuben T.
Published November 15, 2021
Building and deploying a Dart web server

The Problem
Recently, as a result of Stream's work on the stream_feed_flutter sample application, it became problematic to not have some kind of "mock” authentication system in place to better test the application. After all, what good is a social feed if there's only one person in it?

The stream_feed Dart package (upon which stream_feed_flutter is based) contains a function to generate user authentication tokens. However, this token generation function is only meant to be used server-side, and not on the client itself. That means we needed a server.

Note: At the time of writing, Stream is still working on some of the packages mentioned in this article. For example, the stream_feed_flutter package has not been released at the time of writing this article.

The Solution
Stream's Activity Feeds support a variety of different backend clients, but for the purposes of this demo, the stream_feed Dart package will work perfectly. It may not be a well-known fact, but you can use Dart to create web servers!

This article will take you through the process we used to create and deploy a simple Dart server to generate Stream user tokens.

Ready? Let’s get started!

Step One - Create the Initial Project

The first step is to create a Dart web server project:

  1. In your terminal, navigate to where you'd like to save your project.
  2. Run the following command: $ dart create -t server-shelf stream_auth_generator
  3. Open the newly created project in your preferred IDE.

You should now see your server.dart file, and it should look like this:

dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import 'dart:io'; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart'; import 'package:shelf_router/shelf_router.dart'; // Configure routes. final _router = Router() ..get('/', _rootHandler) ..get('/echo/<message>', _echoHandler); Response _rootHandler(Request req) { return Response.ok('Hello, World!\\n'); } Response _echoHandler(Request request) { final message = params(request, 'message'); return Response.ok('$message\\n'); } void main(List<String> args) async { // Use any available host or container IP (usually `0.0.0.0`). final ip = InternetAddress.anyIPv4; // Configure a pipeline that logs requests. final _handler = Pipeline().addMiddleware(logRequests()).addHandler(_router); // For running in containers, we respect the PORT environment variable. final port = int.parse(Platform.environment['PORT'] ?? '8080'); final server = await serve(_handler, ip, port); print('Server listening on port ${server.port}'); }

Step Two - Create an Application in your Stream Dashboard

If you haven’t already, sign up for a free Stream account. Once you’ve signed up, create a project:

  1. Go to your Stream dashboard.
  2. Create a new project by clicking Create app.
  3. Take note of your key, secret, and appid.

Are you looking for a chat solution to integrate into your app? If you’re a qualifying startup, apply for a free Maker Account today! You’ll gain access to Stream’s Chat Startup Plan, Activity Feeds Growth Plan, and more.

Step Three - Set Your Environment Variables

In order to securely use your key, secret, and appid, you need to pass them into our program as runtime environment variables.

This is done via the --define command. Add the following lines to your main function, prior to the existing code, in order to receive these environment variables:

dart
1
2
3
const key = String.fromEnvironment('key'); const secret = String.fromEnvironment('secret'); const appId = String.fromEnvironment('appId');

At this point, you can run your server like so:

dart
1
$ dart run bin/server.dart --define=key=YOUR_KEY_HERE --define=secret=YOUR_SECRET_HERE --define=appId=YOUR_APPID_HERE

Optionally, you can create a run configuration in either VSCode or IntelliJ to handle this for you.

Step Four - Add Stream Feed to Your Server

Go to your pubspec.yaml file and add the following under the dependencies section:

yaml
1
stream_feed: ^latest_version

Note: At the time of writing, the latest version is 0.3.0.

Run pub get.

Back in server.dart, add the following code below your environment variables:

dart
1
2
3
4
5
6
7
8
9
10
var client = StreamFeedClient.connect( key, secret: secret, runner: Runner.server, appId: appId, options: StreamHttpClientOptions( location: Location.usEast, connectTimeout: Duration(seconds: 15), ), );

This instantiates a StreamFeedClient that you can use for various Feeds operations. You will use it to generate your user tokens.

Step Five - Configure the Server to Return User Tokens

At the top of server.dart, remove the _rootHandler and _echoHandler functions. Adjust your _router so that it looks like this:

dart
1
final _router = Router();

Back in main, add the following code underneath where the IP address is set:

dart
1
2
3
4
5
_router.post('/v1/auth', (Request req) async { final payload = await req.readAsString(); final token = client.frontendToken(payload); return Response.ok(token.token); });

This code does the following:

  1. Sets up an endpoint called /v1/auth.
  2. Accepts the request as a String.
  3. Creates a token using the client.
  4. Returns an ok response containing the token.

Now, if you restart the server, you should be able to make a curl HTTP request in your terminal and receive a token back:

shell
1
$ curl -d "username=YOUR_USERNAME_HERE" -X POST <http://localhost:8080/v1/auth>

You should now have a working server that generates a Stream user token for any username that you pass to the server.

Step Six - Deploy to Google Cloud

At this point, you are ready to deploy your server to Google Cloud. To do so, follow the instructions below:

  1. Download and install the Google Cloud SDK (the link will give you pretty detailed installation instructions). If you don’t want to read the instructions, the short story is:
    1. Download and extract the SDK (make sure you download the right SDK for the OS you're working on.)
    2. Install the SDK using the [install.sh](<http://install.sh>) script as outlined in the instructions to ensure that the SDK gets added to your PATH.
  2. In the Google Cloud console on the web, create a new project for your server.
  3. In the terminal for your project, run gcloud run deploy per Google’s deployment instructions. When you are finished, you will see your live server’s service URL.

Congratulations! Now your server is deployed! Thanks for reading, and be sure to tweet us and let us know what you build with Dart on the server!

Integrating Video With Your App?
We've built a Video and Audio solution just for you. Check out our APIs and SDKs.
Learn more ->