DEV Community

Cover image for ⚡A powerful HTTP router and URL matcher for building Deno web servers with dragon 🐲.
Yasser Ameur el idrissi
Yasser Ameur el idrissi

Posted on

⚡A powerful HTTP router and URL matcher for building Deno web servers with dragon 🐲.

Dragon is a simple, fast and low HTTP router and URL matcher for building Deno servers. If you need performance and good productivity, you will love it.

Dragon is exchangeable with other web application frameworks for the backend the same way as React.js is exchangeable with Vue.js and Angular.js when it comes to frontend applications.

That being said, let’s now move further with this article and find out the various features of this framework. Below I have picked out a few of the most important features of Dragon:

  • Lightweight and modular design allows for a flexible framework.
  • Focus on high performance.
  • Middleware support, incoming HTTP request can be handled by a chain of middlewares and the final action.
  • It helps in simplifying the configuration and customization steps for the application.

These were a few of the major advantages of using Dragon in web application development. Let's start by using Dragon in your Deno application.

First things first let's install Deno. I am on a Ubuntu OS so I am using Shell. Simply open your terminal and type:

curl -fsSL https://deno.land/x/install/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

Next step is specifying Deno’s path to bash.

nano ~/.bashrc
export DENO_INSTALL="/home/$USER/.deno"
export PATH="$DENO_INSTALL/bin:$PATH"
Enter fullscreen mode Exit fullscreen mode

Once you have it installed, close the terminal, open a new one, and type:

deno --version
Enter fullscreen mode Exit fullscreen mode

It should output something like this:

deno 1.6.3 (release, x86_64-unknown-linux-gnu)
v8 8.8.294
typescript 4.1.3
Enter fullscreen mode Exit fullscreen mode

💬 If you are using a different operating system, just head over to deno.land installation. They have a lot of ways you can easily install it on your machine.

Awesome!

Let's move ahead

  • Create a new folder and call it dragon_demo (but you can call it anything you want)

  • Once you create a folder simply cd into your new project. Create a file called server.ts.

In your src/server.ts TypeScript file, use the following code to import Dragon, to create an instance of an Dragon application:

import { Application, RequestMethod, HttpRequest, HttpResponse } from "https://deno.land/x/dragon@v1.1.0/lib/mod.ts";
const app = new Application();

app.listenAndServe({ port: 8080 });

console.log("🐉 Serveur listining");
Enter fullscreen mode Exit fullscreen mode

Let's run this file. Open your terminal and in your project root folder type:

$ deno run --allow-net server.ts
Enter fullscreen mode Exit fullscreen mode

💬 Deno is secure by default. Therefore, unless you specifically enable it, a deno module has no file, network, or environment access for example.

You should get something like this:

🐉 Serveur listining
Enter fullscreen mode Exit fullscreen mode

When you run deno run ---allow-net <file_name> in your terminal, Deno will look at all your imports and install them locally in your machine if they are not there.

The first time you run this it will go to this URL https://deno.land/x/dragon@v1.1.0/lib/mod.ts and install the dragon package.

In the next line we do this:

const app = new Application();
Enter fullscreen mode Exit fullscreen mode

This creates a new instance of our application with various options, and it will be the basis of everything as you progress further in this tutorial.

An instance of application has some optional properties as well:

  • hostname: A unique name for a computer or network node in a network. This defaults to 0.0.0.0.

  • port: Numbers used by protocols for operation of network applications.

  • certFile: A concatenation of all Certificate Authority (CA).

🖇 Learn more about application options

Then we write:

app.listenAndServe({ port: 8080 });
Enter fullscreen mode Exit fullscreen mode

Here the port number and tell Deno to listen to the port, which is 8080.

Let's register two routes mapping URL path to handler.

💬 We believe development must be an enjoyable and creative experience to be truly fulfilling (HttpRequest, HttpResponse) as parameters.

const r = app.routes();
  r.Path("/hello")
  .withMethods(RequestMethod.GET)
  .handleFunc(async function (Request: HttpRequest, ResponseWriter: HttpResponse) {
    ResponseWriter.withBody("Hello Dragon").end();
  });
Enter fullscreen mode Exit fullscreen mode

We create a new router instance by doing const r = app.routes(); and then we create a new route called hello which is of type RequestMethod.GET. If an incoming request URL matches one of the paths, the corresponding handler is called passing.

💬 By default Dragon all methods for this route(s) like PUT, DELETE, PATCH

And now we are done. ✅ Let's run this and see what we have:

$ deno run --allow-net server.ts
Enter fullscreen mode Exit fullscreen mode

Now open your favorite browser and go to http://localhost:8080/hello. You will see something like this:

Hello Dragon
Enter fullscreen mode Exit fullscreen mode

Awesome

Honestly the hardest part is done. Conceptually we are 50% there.

Now we only have two things remaining:

  • Add a not found route so that when the user tries to access an unknown route.
  • Add a logger middleware that consoles the response time.

Using the notFoundHandler options you may define a route that will be executed when no other route matches the incoming request.

const fallback = async function(Request: HttpRequest, ResponseWriter: HttpResponse) {
  ResponseWriter.html`🤦 Page Not Found`.end();
  return MiddlewareState.Cancel;
}

const r = app.routes({
  notFoundHandler: fallback
});
Enter fullscreen mode Exit fullscreen mode

fallback is a Middleware literally means anything you put in the middle of one layer of the software and another. As you can see fallback has access to the HttpRequest and HttpResponse. Middleware can either terminate the HTTP request or pass it on to another middleware function using MiddlewareState.Next or MiddlewareState.Cancel

Let's see if this works.

Restart the server:

$ deno run --allow-net server.ts
Enter fullscreen mode Exit fullscreen mode

Open up a new tab Set the request to GET and in the URL bar type http://localhost:8080/something-unknown.
You should get something like this:

🤦 Page Not Found
Enter fullscreen mode Exit fullscreen mode

Logging Response time in console, create a new file called logger.ts and enter the following code:

import { HttpRequest, HttpResponse, MiddlewareState } from "https://deno.land/x/dragon@v1.1.0/lib/mod.ts";

export const Logger = async function(Request: HttpRequest, ResponseWriter: HttpResponse) {
  //
  console.log(`Handle at: ${Date.now()}`);
  return MiddlewareState.Next;
}
Enter fullscreen mode Exit fullscreen mode

In your server.ts file add this code:

Now let's import and register the middleware.

import { Application, RequestMethod, HttpRequest, HttpResponse } from "https://deno.land/x/dragon@v1.1.0/lib/mod.ts";
import { Logger } from "./logger.ts"; 

const app = new Application();

const r = app.routes({ maxRoutes:2 });

r.Path("/hello")
 .withMethods(RequestMethod.GET)
 .handleFunc(async function (Request: HttpRequest, ResponseWriter: HttpResponse) {
      ResponseWriter.withBody("Hello Dragon").end();
  }).middleware(Logger);

app.listenAndServe({ port: 8080 });

console.log("🐉 Serveur listining");

Enter fullscreen mode Exit fullscreen mode

I hope that you found this article useful and that it was able to help you learn something today.

If you are interested in joining the dragon team to improve the framework, You are welcome.

A Star 🌟 on our github repository could be a good and very feedback for us.

Top comments (0)