DEV Community

Cover image for Introduction to Deno
Swayam Samyak Debasis
Swayam Samyak Debasis

Posted on

Introduction to Deno

Introduction

Deno is an opensource runtime for Javascript which supports typescript out of the box.It uses V8 engine. According to Ryan Dahl, he made many mistakes in node he rectified in Deno. One of them is the use of npm to manage packages. Instead of doing that Deno can directly download the packages after importing it in the code via a link. So, there is no need for package.json but it was cool how it organized every asset of code and allows to change it manually.

Advantages of using Deno:-

  • It is more secure.
  • Is typescript dependant
  • Packages can be directly imported without the use of npm.
  • It has a standard library.

Installation

There are various ways of installing Deno based on the operating system:-
Linux Shell:
curl -fsSL https://deno.land/x/install/install.sh | sh
Windows:
For installation in windows installation through chocolatey is the better option but there are several other ways.
choco install deno
Mac(Homebrew):
brew install deno

Importing modules via Standard library

Deno Provides the use of Standard Library rather than using npm to install modules as a result of this there is no need for the creation of the massive folder known as node_modules.
import { module } from "URL of the standard library";

Use of TypeScript

const greeting: string = "Hello World";
console.log(greeting);

In this case, if we do not mention the datatype it compiles and runs in a regular manner but if we mention a datatype Deno detects the use of typescript and compiles accordingly by taking the datatype into consideration.

Setting up a simple server

import { serve } from "https://deno.land/std/http/server.ts";
const server = serve({ port: 8000 });
console.log("http://localhost:8000/");
for await (const req of server) {
  req.respond({ body: "Hello World\n" });
}

This is a simple server setup built-in, Deno. Here we are first importing the serve module from the HTTP standard library and then setting up the req object and sending a response of "Hello world" to the body.

Running the Server

deno run --allow-net simpleServer.ts
This is the command which is used to run our server which resides in the file simpleServer.ts.The "--allow-net" part is used because of security purposes.

Setting up Restful API using oak

Server.ts

import { Application } from 'https://deno.land/x/oak/mod.ts'
import router from './Routes.ts';

const port = 5000

const app = new Application()



app.use(router.routes())
app.use(router.allowedMethods())




console.log(`Server running on port ${port}`)

await app.listen({ port })

This is the setup of the server which uses top-level await which does not require an async function. It runs on port 5000. It's importing the routes from Routes.ts file.

Routes.ts

import { Router } from 'https://deno.land/x/oak/mod.ts'
import { getProducts,getProduct,addProduct,updateProduct,deleteProduct } from './controllers/products.ts' 


const router = new Router()


router.get('/api/v1/products',getProducts)
       .get('/api/v1/products/:id',getProduct)
       .post('/api/v1/products',addProduct)
       .put('/api/v1/products/:id',updateProduct)
       .delete('/api/v1/products/:id',deleteProduct)


export default router;

This specifies the routes of different operations in CRUD which are taking place in products.ts in controllers folder.

product.ts

import { v4 } from 'http://deno.land/std/uuid/mod.ts'
import { Product } from '../Types.ts';

let products: Product[] = [


{
    id:"1",
    name: "Product one",
    description:"This is product one",
    price: 29.99

},
{
    id:"2",
    name: "Product two",
    description:"This is product two",
    price: 39.99

},
{
    id:"3",
    name: "Product three",
    description:"This is product three",
    price: 59.99

}

]

// @desc Get all Products
// @route GET /api/v1/products

const getProducts = ({ response }: { response: any }) => {
    response.body = {
    success: true,
    data: products
    }
}

// @desc Get single Product
// @route GET /api/v1/product/:id

const getProduct = ({ params,response }: { params: { id: string }, response: any }) => {
   const product: Product| undefined = products.find(p => p.id === params.id)

   if(product) {
    response.status = 200
    response.body = {
        success: true,
        data: product
    } 
    }else {
        response.status = 404
        response.body = {
        success: false,
        msg: 'No Product found'
        }

   }
}


// @desc Add Product
// @route POST /api/v1/products

const addProduct = async({ request,response }: { request:any , response: any }) => {
const body = await request.body()

if(!request.hasBody){
response.status = 400
    response.body = {
    success:false,
    msg: 'No Data'
    } 
    }else {
        const product: Product = body.value
        product.id = v4.generate()
        products.push(product)
        response.status = 201
        response.body = {
            success: true,
            data:product
        }
}

}

// @desc Update Product
// @route PUT /api/v1/products

const updateProduct = async({ params,request,response }: { params: { id:string },request:any, response: any }) => {
   const product: Product| undefined = products.find(p => p.id === params.id)

   if(product) {
        const body = await request.body()

        const updateData: { name?:string;description?:string;price?:number } = body.value

        products = products.map(p => p.id === params.id ? { ...p,...updateData }:p)

        response.status = 200
        response.body = {
            success: true,
            data: products
        }
    }else {
        response.status = 404
        response.body = {
        success: false,
        msg: 'No Product found'
        }
    }

   }


// @desc DELETE Product
// @route DELETE /api/v1/product/:id

const deleteProduct = ({ params,response }: { params:{ id:string }, response: any }) => {
    products = products.filter(p => p.id !== params.id)
    response.body = {
        success: true,
        msg: 'Product removed'
    }
}
export { getProducts,getProduct,addProduct,updateProduct,deleteProduct }

In this file, we use some temporary data to perform our CRUD operations. This file is responsible for the fetching of data, creating, deleting, and updating it. As these data are temporary(no data stored in a database) the effect disappears after closing the server.
Types.ts

export interface Product {
    id:string;
    name:string;
    description:string;
    price:number;
}

This is basically the interface where we specify the datatypes which are being used in product.ts file.

Conclusion

Deno is having a great future in the field of web development and can someday replace node. For the people who are starting node and having a thought that node is dead, in my opinion, that's not true as we can't replace the current technologies which are made in node to Deno. But the current features in Deno makes it a little more superior to node. But currently continuing with node is a better option as both are nearly the same.

The Github link to this code is https://github.com/Swayamsvk/Deno_REST
This blog is inspired by This youtube video

Latest comments (10)

Collapse
 
architectak profile image
Ankit Kumar

Nice write up

Collapse
 
swayamsvk profile image
Swayam Samyak Debasis

Thanks

Collapse
 
leonlafa profile image
Leon Lafayette • Edited

Deno rocks 🤟

Collapse
 
swayamsvk profile image
Swayam Samyak Debasis

Yup it's great

Collapse
 
viskjha profile image
Vishal kumar Jha

New topic.. great...👍

Collapse
 
swayamsvk profile image
Swayam Samyak Debasis

Thanks

Collapse
 
codewithsaviour profile image
Dibyamohan Acharya

Excellent one...insightful...keep writing

Collapse
 
swayamsvk profile image
Swayam Samyak Debasis

Thanks

Collapse
 
kirtijyotis profile image
Kirtijyoti Senapati

Nice blog

Collapse
 
swayamsvk profile image
Swayam Samyak Debasis

Thanks