Writing an HTTP server with the route package

We've already seen that creating an HTTP server isn't hard. We could handle different URLs with a few if statements:

var addr = InternetAddress.LOOPBACK_IP_V4;
var server = await HttpServer.bind(addr, port);
server.listen((HttpRequest request) {
  if (request.uri == '/contact') {
    // …
  } else if (request.uri == '/blog') {
    // …
  }
});

This would work and would be enough for very simple usage. However, you usually need to specify URIs with parameters and also serve static content. We can use the route package, which is an interesting package that works on both client and server sides. We'll use it here on the server side.

So, create a new project and add two dependencies: route and http_server. The second package contains the VirtualDirectory class that we'll use to make an entire directory available for URIs that don't match any route. Also, create a directory called public in the project's root, where we'll put all static content:

// bin/server.dart
import 'dart:io';
import 'package:route/server.dart';
import 'package:http_server/http_server.dart';
// Define patterns for all possible URLs.
final homeUrl = new UrlPattern('/'),
final articleUrl = new UrlPattern('/article/(.+)'),

main() async {
  // Get this script's path.
  var static = Platform.script.resolve('../public').toFilePath();
  
  var addr = InternetAddress.LOOPBACK_IP_V4;
  var server = await HttpServer.bind(addr, 8081)
  print('Server running ...'),
  // Add route handlers.
  // We're using [Stream.map()] to log all requests.
  var router = new Router(server.map(debugHandler))
    ..serve(homeUrl, method: 'GET').listen(showHome)
    ..serve(articleUrl, method: 'GET').listen(showArticle);
    
  // Serve entire directory.
  var virDir = new VirtualDirectory(staticDir);
  // Show contents of directories, rather disable it in production.
  virDir.allowDirectoryListing = true;
  // Disable following symbolic links outside the server root dir.
  virDir.jailRoot = true;
  // Use this handler for all URLs that don't match any route.
  virDir.serve(router.defaultStream);
}

HttpRequest debugHandler(HttpRequest request) {
  // We'll just log the requested URI, but at this place you could
  // also check user's credentials from cookies and so on.
  print(request.uri);
  return request;
}
void showHome(HttpRequest request) {
  request.response.write("Hello, I'm your new homepage!");
  // Send response.
  request.response.close();
}

void showArticle(HttpRequest request) {
  // Get URI parameter.
  String slug = articleUrl.parse(request.uri.path)[0];
  
  request.response.write('You requested article "$slug"'),
  /* Do whatever you want here */
  request.response.close();
}

Now we have an HTTP server that handles two specific URI patterns and serves the entire content of the public directory. The Router() constructor accepts a Stream object, but we want to log all requests to the server, so we used the map()method that converts each value of the stream into a new value and returns a new Stream object. As we don't want to modify requests in any way, we just return them in debugHandler().

Note that route handlers don't need to return anything. We're writing its response (including return codes and headers) right into the request.response object.

I placed a few test files in my public directory:

Writing an HTTP server with the route package

Now, run the server and test a few URLs in a browser:

Writing an HTTP server with the route package

In the console, I can see the requested URIs:

$ dart bin/server.dart 
Server running ...
/dart-logo.png
/
/article/my-new-dart-article
/subdir/

An obvious question is whether this is useful in a real-world application. Well, you probably wouldn't serve static files with the Dart server and use a better optimized server such as nginx instead, because it's well tested; supports caching, compression, usage statistics, and countless modules; and has already been in production for years all around the world.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.226.66