Web API standards and Denos calling
Discover how web API standards like Request, Response, URL, and URLPattern simplify HTTP server development in Deno and other JavaScript runtimes. Learn to build framework-free servers with practical code examples and route handling.
Hey 👋🏼,
It's been a minute. It took me a few days to get back into the habit of writing after completely shutting down my brain over the holidays. But here we are, working on finishing the Deno and HTTP chapter of my Everything I know about Deno guide.
We will be looking at the runtime agnostic web API standards that are also implemented in Deno, which help a lot with managing requests and responses on HTTP servers. I presented these web APIs at a meetup on Tuesday and saw that not many people know about these APIs like Request, Response, URL and URLPattern.
So today I want to give you a short introduction to them, with a longer version in the Deno guide and probably a blog article as well.
For the guide, I created a simple HTTP server in Deno without any frameworks, using these web APIs. I already knew about Response, Request and URL, but it was on this day that I discovered URLPattern and understood its potential.
Using URLPattern we can easily match other URL strings or parts of them against a given pattern. This allows us to create API routes for our HTTP server. Even dynamic values are possible. More on this later.
For now, let's talk about the basics. Request and Response. Before these standards, we had to rely on frameworks to provide us with objects to work with, where we could read (or even prepare) the incoming or outgoing data. For example, the incoming full URL of the request being called. With the implementation of the request and an instance of it, its simply a request.url
to be able to read it. Even the body, headers or method of the request is readable without breaking a sweat. The same goes for the response object.
Of course, we can also define (and thus prepare) this with the new
keyword.
const req = new Request("https://example.com", {
headers: { "content-type": "application/json" },
});
console.log(req.url); // https://example.com
console.log(req.method); // GET
console.log(req.headers); // Headers { "content-type": "application/json" }
We have already mentioned the URLPattern. If we want to compare it to an incoming URL, for example, we have the URL
constructor, which helps us work with URLs.
const url = new URL("https://example.com/my-path?query=string");
console.log(url.hostname); // example.com
console.log(url.protocol); // https:
console.log(url.pathname); // /my-path
console.log(url.search); // ?query=string
console.log(url.searchParams.get("query")); // string
In the Deno guide we will see an example like the following:
// define a route
const SINGLE_BOOK = new URLPattern({ pathname: "/books/:id" });
const handler = (req: Request): Response => {
// parse the URL
const url = new URL(req.url);
// Check if the URL does not match
if (!SINGLE_BOOK.exec(url)) {
return new Response("Use /books/:id path");
}
// read the dynamic url value
const id = SINGLE_BOOK.exec(url)?.pathname.groups?.id;
if (!id) {
return new Response("Invalid id", { status: 400 });
}
return new Response(`Hello, World! The id is ${id}.`);
};
Deno.serve(handler);
We can see here that it is super easy to define routes and even read dynamic values from our request.
I find that these web api standards are incredibly helpful to work with and make a web developer's life a lot easier.
Hono, for example, is built on top of these standards, which makes it runtime agnostic. This means that we can use the HTTP framework on pretty much any JavaScript runtime (e.g. Bun, Deno, NodeJS, Cloudflare Workers).
I hope you find these standards as helpful as I have. Thanks for reading.
Niklas
P.S.: If you have any feedback, I would love to hear from you. I write the issues in a way that helps me digest the topics even more, or to have a good reason to dive deeper into things.