
Start by initializing a Deno project
deno init rest_deno_oak
Open this project in VS Code
code rest_deno_oak
Open main.ts and import the Application and Router from Oak
import { Application, Router } from "https://deno.land/x/oak@v11.1.0/mod.ts";
Now initialize the Application and Router
const app = new Application();
const router = new Router();
Register all route handlers
app.use(router.routes());
Start listening on PORT 8000
await app.listen({ port: 8000 });
Create a test route
router.get("/", (context) => {
context.response.body = "Hello World"
})
After this, the entire main.ts file should look like this.
import { Application, Router } from "https://deno.land/x/oak@v11.1.0/mod.ts";
const app = new Application();
const router = new Router();
router.get("/", (context) => {
context.response.body = "Hello World"
})
app.use(router.routes());
await app.listen({ port: 8000 });
Start the server by running the following command
deno task dev
Open Postman and make a GET request at the following URL
http://localhost:8000
Let's do some database operations in this deno app.
Create a .env file in the root directory of the project
DATABASE_USER="<YOUR_DATABASE_USER>"
DATABASE_NAME="<YOUR_DATABASE_NAME>"
DATABASE_PORT=<YOUR_DATABASE_PORT>
DATABASE_HOST="<YOUR_DATABASE_HOST>"
DATABASE_PASS="<YOUR_DATABASE_PASSWORD>"
Replace values in all of the above keys in the .env file with your actual values.
Create a file inside db/db.ts and paste below code inside it.
import postgres from "https://deno.land/x/postgresjs@v3.4.4/mod.js";
import { load } from "https://deno.land/std@0.224.0/dotenv/mod.ts";
// Load all environment variables in envVars.
const envVars = await load();
export const DB_NAME = envVars.DATABASE_NAME;
export const DB_USERNAME = envVars.DATABASE_USER;
export const DB_PORT = Number(envVars.DATABASE_PORT);
export const DB_HOST = envVars.DATABASE_HOST;
export const DB_PASS = envVars.DATABASE_PASS;
// Create a connection with Postgres database
export const sql = postgres({
user: DB_USERNAME,
port: DB_PORT,
host: DB_HOST,
database: DB_NAME,
password: DB_PASS,
});
The above code will help us establish a connection with our Postgres database and perform database operations.
Now, create a file inside db/seed.ts and paste the code below
import type { Author, AuthorCreateInput } from "../types/author.ts";
import type { Post, PostCreateInput } from "../types/post.ts";
import { sql } from "./db.ts";
import { faker } from "https://esm.sh/@faker-js/faker@9.0.3";
// Create Author table
await sql`
CREATE TABLE IF NOT EXISTS author (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`;
// Create post table
await sql`
CREATE TABLE IF NOT EXISTS post (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT NOT NULL,
slug TEXT NOT NULL,
author_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (author_id) REFERENCES author (id) ON DELETE CASCADE
);
`;
// Create fake authors
const authors: AuthorCreateInput[] = Array(4)
.fill(null)
.map(() => ({
name: faker.person.fullName(),
age: faker.number.int({ min: 10, max: 100 }),
}));
// Insert author details into author table
const authorInsertResult: Author[] = await sql`
INSERT INTO author ${sql(authors)} returning id,name,age,created_at`;
console.log(authorInsertResult);
// Create fake posts
const postsToCreate: PostCreateInput[] = [];
authorInsertResult.forEach((author) => {
const posts: PostCreateInput[] = [];
const numberOfPosts = Math.floor(Math.random() * 10) + 1;
for (let i = 0; i < numberOfPosts; i++) {
posts.push({
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(),
author_id: author.id,
slug: faker.lorem.slug(),
});
}
postsToCreate.push(...posts);
});
// Insert post details into post table
const postInsertResult: Pick<Post, "id">[] = await sql`
INSERT INTO post ${sql(postsToCreate)} returning id, slug`;
console.log(postInsertResult);
self.close();
This file will create two tables in our database, post and author. It will also insert some dummy data in both of these tables. Let's create type files for them.
Create a file inside types/author.ts and paste below code in it.
export type Author = {
id: number;
name: string;
age?: number;
created_at: Date;
};
export type AuthorCreateInput = Omit<Author, "id" | "created_at">;
Create a file inside types/post.ts and paste below code in it.
export type Post = {
id: number;
title: string;
content: string;
slug: string;
author_id: number;
created_at: Date;
};
export type PostCreateInput = Omit<Post, "id" | "created_at">;
Create a file inside modules/author/handler.ts and paste the code below.
import type { Context } from "https://deno.land/x/oak@v11.1.0/mod.ts";
import { sql } from "../../db/db.ts";
// Get all authors from database
export const getAuthors = async (context: Context) => {
const authors = await sql`
SELECT * FROM author
`;
context.response.body = authors;
};
Now create another file inside module/author/routes.ts and paste the code below.
import { Router } from "https://deno.land/x/oak@v11.1.0/mod.ts";
import { getAuthors } from "./handler.ts";
// Initialize a new router
export const authorRouter = new Router();
// Bind "/" route on authorRouter
authorRouter.get("/", getAuthors);
Now bind authorRouter to the router in the main.ts file.
import { authorRouter } from "./modules/author/routes.ts";
...
router.use("/author", authorRouter.routes());
Open Postman and make a GET request at the following URL. You should see the list of all authors present in the database.
http://localhost:8000/author
Written On: 11 Nov, 2024
Last Updated On: 11 Nov, 2024

Abhishek Diwakar
Software Engineer