Create a REST API With Deno Oak Framework
Creating a server-side web API with Javascript or Typescript means solving two objectives with one single action. You don't have to learn other backend programming languages like C#, Python, etc. to create a web application.
Deno is a secure runtime environment for Javascript and Typescript where you can run your Javascript/Typescript code. To create REST API we are going to use a Deno middleware web framework called Oak.
What is Middleware in Deno?
Middleware makes web development easier for developers so they can focus on the specific purpose of their applications. For example, the Oak framework was created for Deno's Http server where a client can send a request to a server and get a response from the server.
Let's say you want to upload files on google drive or somewhere on the internet and you clicked the upload button after selecting files. By pressing that button you send a request to the web-server and when it says "Your files uploaded successfully" or something like that, that is the response from the web server.
You will understand much better when you will create the REST API.
Prerequisites
To follow this post, you should have basic knowledge of Typescript.
Also, I recommend you to learn HTTP Messages like Http request, response, etc. That way you can understand how data is being exchanged between a server and client.
Getting Started
If you haven't installed Deno on your computer, check out the Deno Installation on Windows, Mac, and Linux Operating Systems article.
I am going to use the most popular text editor VS Code for this project. You have to install the Deno official plugin to work with the Deno project otherwise it will give you some errors. I recommend you to read the Deno IntelliSense on VS Code article to setup your Vs Code for Deno.
In any case, If you are stuck at following this post, you can check the completed code in this github repository.
Building backend web API with Deno
Create a folder and open it on the VS Code and enable Deno extension on the project folder by creating .vscode/settings.json
.
Now, create a server.ts
file on the project directory and paste the code from below.
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
app.use((context) => {
context.response.body = "Hello World!";
});
await app.listen({ port: 8000 });
In this code above, we exported the Application
from the Deno Oak module. If you visit the link that class imported from, you will see the export statement of the Application
class there.
Then we created a new instance of the Application
using the new
operator which creates a new object with Application
shape and runs the constructor to initialize it. Read the Classes in Typescript documentation to understand with more examples.
The Application
has two methods called .use()
and .listen()
. The .use()
method register the middlware and the .listen()
method first start the server then start processing requests with the registered middleware.
If you look at the code, first we registered the middleware by using app.use()
method then we used app.listen()
method to start the server and process the requests from the middleware.
In the .use()
method we passed an object called context
. Now, What is context
in the Oak middleware framework? The context
provides information about the current state of the application. For example, We are sending an Http response message(Hello World!
) to the client via context
.
Why is there no async
keyword before await
in Deno?
You might notice that there is an await
keyword before .listen()
method but no function starts with the async
keyword. So, does await
work without async
function in Deno? Yes, because Deno supports Top-level await
feature but that does not mean you can use await
in everywhere without async
functions. Let me explain in more detail.
What is the Top-level await
feature in Deno?
Top-level await
enables the capability to use the await
keyword outside of async functions which act like big async functions. But you can't use the await
keyword in regular functions without the async
keyword like the code below.
function something(){
// you have to add async before the function
await wrong()
}
Top-level await
only works at the top level of modules like the await
before .listen()
method above. So, it will wait until the Promises of app.listen()
are resolved.
Starting the API
As you saw there is a value we passed called port
in the listen()
method. So, What is port
in the .listen()
method? It's a unique port of your local testing server which will start by the .listen()
method. But why inside curly braces? Because we are Destructuring. We are passing an object as a function parameter.
Let's start the server to understand more.
Save the file, open the terminal on your VS Code and run:
deno run --allow-net server.ts
--allow-net
grant the permission to access the network. In Deno, you need to explicitly permit programs to do certain actions, such as access to the network.
Now, open your browser and visit http://localhost:8000/
. You will get the Hello World!
message in your browser.
What is localhost in Deno?
Localhost means your local computer where your server or program is running on. Developers run their programs on the localhost to test their applications working or not.
And, Ports are used to be able to run multiple servers so you can work with other application servers without closing your existing server. You can try other numbers as port too like 5000
, 3000
etc.
So, This is how you create a REST API with Deno and run it. But how can you test it? How can you send a request to the server or get the response from the server? Let's see how to do that.
How to test your web API?
There are a lot of tools to test web API. I am going to use the most popular and simple app called Insomnia Core.
Download and install the Insomnia Core on your computer then open it.
To create a new request click on the plus icon from the left side then click New Request. It will Popup a window to name your Request. Name whatever you want to name, I am naming it Default for now. Click Create to create your request.
Now, Paste your localhost URL(http://localhost:8000
) on the URL bar of insomnia. There is a dropdown menu on the left side of the URL bar. Click on the menu to see all the available Http request methods like GET
, POST
, etc. Based on our source code, we are retrieving data from the server so we will select the GET
method.
Finally, click on the Send button to send the GET
request to the server. You will see the Hello World!
message will appear on the right side.
Passing an array from Deno server to client
Let's say we want to send a list of blog posts to the client. So, we should have an array of every blog post where the blog posts will be in JSON Objects format.
So, let's create an array and pass it on context
in the .use()
method like the code below. Also, write a console.log()
message to display server information on your terminal.
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
const posts = [
{
id: 1,
title:
"sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
body:
"quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto",
},
{
id: 2,
title: "qui est esse",
body:
"est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla",
},
{
id: 3,
title: "ea molestias quasi exercitationem repellat qui ipsa sit aut",
body:
"et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut",
},
{
id: 4,
title: "eum et est occaecati",
body:
"ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit",
},
];
app.use((context) => {
context.response.body = posts;
});
app.listen({ port: 8000 });
console.log("Server running on http://localhost:8000");
Save the file, press Ctrl+C
on your terminal to close the current running server. Because every time you change your code you need to restart the server to see changes. Now, run the deno run --allow-net server.ts
command again to restart the server.
Go to insomnia and click the send button again. The posts data should appear on the right side like the screenshot below.
That's it, now you have learned how you can create, run, and test your web API with Deno.
Conclusion
In this whole post, I talked about only the GET
request method which was basic of a REST API. You should make your next goal to create a crud API with Deno if you want to learn more.
If you don't understand any part of this post make sure to comment below. Also, If you learn something good from here don't forget to share the link to others.