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