Counter 🔢
Difficulty: 🟢 Beginner
Length: 15 minutes
Before getting started, read the prerequisites to make sure your development environment is ready.
Overview
In this tutorial, we're going to build an app that exposes a single endpoint and responds with the number of times the route was requested.
When we're done, we should be able to make multiple GET
requests to the /
endpoint:
# 1st time
curl --request GET \
--url http://localhost:8080
# 2nd time
curl --request GET \
--url http://localhost:8080
And our server should respond with the following responses:
HTTP/1.1 200 OK
Connection: close
Content-Length: 21
Content-Type: text/plain; charset=utf-8
You have requested this route 1 time(s).
---
HTTP/1.1 200 OK
Connection: close
Content-Length: 21
Content-Type: text/plain; charset=utf-8
You have requested this route 2 time(s).
Creating a new app
To create a new Dart Frog app, open your terminal, cd
into the directory where you'd like to create the app, and run the following command:
dart_frog create counter
You should see an output similar to:
✓ Creating counter (0.1s)
✓ Installing dependencies (1.7s)
Created counter at ./counter.
Get started by typing:
cd ./counter
dart_frog dev
Install and use the Dart Frog VS Code extension to easily create Dart Frog apps within your IDE.
Running the development server
You should now have a directory called counter
-- cd
into it:
cd counter
Then, run the following command:
dart_frog dev
This will start the development server on port 8080
:
✓ Running on http://localhost:8080 (1.3s)
The Dart VM service is listening on http://127.0.0.1:8181/YKEF_nbwOpM=/
The Dart DevTools debugger and profiler is available at: http://127.0.0.1:8181/YKEF_nbwOpM=/devtools/#/?uri=ws%3A%2F%2F127.0.0.1%3A8181%2FYKEF_nbwOpM%3D%2Fws
[hotreload] Hot reload is enabled.
Make sure it's working by opening http://localhost:8080 in your browser or via cURL
:
curl --request GET \
--url http://localhost:8080
If everything succeeded, you should see Welcome to Dart Frog!
.
Updating the root route
Now that we have a running application, let's start by updating the root route at routes/index.dart
:
import 'package:dart_frog/dart_frog.dart';
Response onRequest(RequestContext context) {
const count = 1;
return Response(
body: 'You have requested this route $count time(s).',
);
}
Save the changes and hot reload should kick in ⚡️
[hotreload] - Application reloaded.
Now if we visit http://localhost:8080 in the browser or via cURL
:
curl --request GET \
--url http://localhost:8080
We should see our new response:
You have requested this route 1 time(s).
Awesome! There's just one small issue...
Make another request and note that the count does not increment. This is expected because we hard-coded the count in our route handler. Let's fix that by introducing some middleware!
Creating middleware
In Dart Frog, middleware allows you to execute code before and/or after a request is processed. In this example, we're going to create a piece of middleware that provides a count to our routes.
A piece of middleware can modify the inbound request and outbound responses, provide dependencies, and more! Learn more about middleware.
For this example, we're going to create a single global piece of middleware but a Dart Frog application can consist of multiple pieces of middleware which are scoped to nested routes.
To create a global piece of middleware, we just need to create a file called _middleware.dart
in the routes
directory and define a middleware
method:
import 'package:dart_frog/dart_frog.dart';
// This piece of middleware does nothing at the moment.
Handler middleware(Handler handler) {
return handler;
}
Install and use the Dart Frog VS Code extension to easily create new middleware within your IDE.
Now that we've defined the middleware, we can create our private count
and provide the count to all sub routes:
import 'package:dart_frog/dart_frog.dart';
int _count = 0;
Handler middleware(Handler handler) {
return handler.use(provider<int>((_) => ++_count));
}
The use
method on a Handler
allows you to chain multiple middleware
.
In the above snippet, we are automatically incrementing the _count
whenever the value is read.
The last thing we need to do is update our route handler to use the provided count.
Open routes/index.dart
and replace the hard-coded count with the provided value using context.read
:
import 'package:dart_frog/dart_frog.dart';
Response onRequest(RequestContext context) {
final count = context.read<int>();
return Response(
body: 'You have requested this route $count time(s).',
);
}
context.read<T>()
allows a route to access an instance of type T
which was provided via middleware
.
Be sure to save all the changes and hot reload should kick in ⚡️
[hotreload] - Application reloaded.
Now if we visit http://localhost:8080 in the browser or via cURL
:
curl --request GET \
--url http://localhost:8080
We should see our response:
You have requested this route 1 time(s).
Now if we reload the page or make another request, the count should update:
You have requested this route 2 time(s).
If you restart the server, the count will be reset to 0 because it is only maintained in memory.
🎉 Congrats, you've created a counter
application using Dart Frog. View the full source code.