Let’s Build a Todo App with Deno

An introduction to Deno, the new JavaScript runtime environment

Abrar Hayat
JavaScript in Plain English

--

Simple Todo Web App

Deno is a secure JavaScript runtime environment which was built to resolve some pitfalls in Node.js which were not addressed during its development. Even though Deno is not ready for deploying applications in production yet, it has the potential to replace Node.js in the future, so let’s dive in!

This article will introduce us to the Deno environment by building a simple Todo app which will use the Oak Middleware Framework for handling requests and denoDB for persistence. Since Deno can run TypeScript, this project is also entirely written in it. After wiring up the app, it will look something like this:

Deno Todo App (react-todo-deno-abrar.web.app)

Before getting started, here are the full source code for the application, this should give us a good overview of the file structure of the application. We will only focus on the backend code and the front end will be used to just test out the backend. Another point to keep in mind is that only the master branches of these repositories are relevant to this article.

Backend: https://github.com/abrarhayat/deno-app-oak

Frontend: https://github.com/abrarhayat/react-todo-app

Before proceeding further with the source code, we need to follow these steps from the README.md file in the backend repository. The app will not work until those requirements are fulfilled. We write the scripts.json file to use denon which is a package that can simulate our Deno environment variables and make our development experience smoother. We will allow Deno runtime access to our our network and our environment variables. Our start script will look like this:

deno run --allow-net --allow-env app.ts

Now we look closely into the backend code, starting from app.ts.

At first we make our necessary imports. Imports for any libraries in Deno JS is done from urls and then cached into the system unlike the imports we previously made in Node JS applications from node_modules.

In the Oak middleware framework, each middleware in the application runs inside the prior middleware. So we define the error handling middleware as the first middleware so that we can catch the errors from all other middlewares here and handle it. We also always await for the next() function to make sure all promises returned on the subsequent middlewares are completed.

We register a middleware to handle cors headers since we have a separate frontend application, and then we register the routes for our endpoints. We need to register the routes a little bit differently than we do in NodeJS Express applications. We actually register the result of the .routes() and .allowedMethods() of the router. Then we get our desired port from the Deno environment and fire up our application.

We connect to the database before we fire up our application using the connect() function which we will discuss in detail later.

A closer look into the endpoints:

We will be using the DenoDB package for persistence and will implement a MySQL server. We need to put valid MySQL details in the scripts.json file as mentioned in the README.md file. We then export our db to be used in our models and use the connect function in app.ts before firing up our application.

We define the model for our todos with the help of the DenoDB. Our Model will have two fields, the id field which will be auto-incremented and will serve as the primary key and our text field will hold our todo text. We then, link our Todo model to the db object we created in the previous step and sync our model.

And last but not least, we have our controller logic defined for all our Todo CRUD operations. For middlewares in Oak, we get a context object and a next function as params to the request handler function.

We use the context object to decide what we are going to send in our response or to retrieve data from the request body and the next function to lead us to the next middleware. We just need to configure the response, and not send it. The response will then be sent by the framework itself.

We configure the contents of the response body in ctx.response.body and acquire the request body from ctx.request.body.value which basically returns a promise, so we have to wait for it.

Let us compare Express.js with Oak in terms of dealing with REST api transactions.

Retrieving request body and sending JSON response in Express vs in Oak:

//get the request body
const body = request.body //Express
const body = await ctx.request.body.value //Oak
//send JSON data response
response.json(data) //Express
ctx.response.body = data //Oak

Conclusion

And there we have it, our first application written for the Deno environment. This is a very simple app but it is a good starting point to go further. Deno is promising, so we should definitely keep playing around with it and go through more of the exciting third party libraries!

--

--

Software Developer @UniMelbLE, Master of I.T, Artificial Intelligence @UniMelb