Developing REST Api using Deno, Oak and MongoDB
In this article i will explain you step by step to setup REST Api with deno, oak and mongodb and iam using macOS operating system but procedure is same for Windows and Linux users
Step 1: Install deno
For macOS and Linux user use below command
curl -fsSL https://deno.land/install.sh | sh
For Window user Using Powershell use below command
iwr https://deno.land/install.ps1 -useb | iex
Step 2: Download Visual Studio Code and install extension deno
Step 3: Create app.ts file under root path of your deno project
Advantage of using deno is we don't need to install packages instead we call standard deno library
Inside your app.ts file copy paste below code this is the main file for your deno rest api
import { Application } from "https://deno.land/x/oak/mod.ts";
import notesRoutes from "./routes/notes.ts";
import { connect } from "./helpers/db.ts";
connect();
const app = new Application();
app.use(async (ctx, next) => {
console.log("Middleware!");
await next();
});
app.use(async (ctx, next) => {
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
ctx.response.headers.set(
"Access-Control-Allow-Methods",
"GET,POST,PUT,DELETE"
);
ctx.response.headers.set("Access-Control-Allow-Headers", "Content-Type");
await next();
});
app.use(notesRoutes.routes());
app.use(notesRoutes.allowedMethods());
await app.listen({ port: 3000 });
Step 4: Create controllers folder under root path of your project folder and under that folder create notes.ts file
This is the controller file where you will be writing all the logic for GET, POST, PUT , DELETE Rest API methods
Copy paste below code in you controller file
import { ObjectId } from "https://deno.land/x/mongo@v0.29.4/mod.ts";
import { getDb } from "../helpers/db.ts";
import { Notes } from "../interfaces/notes.ts";
export default {
getAllNotes: async ({ response }: { response: any }) => {
const notes = await getDb().collection("notes").find({}).toArray();
response.status = 201;
response.body = { message: "All Notes!", notes: notes };
},
createNotes: async ({
request,
response,
}: {
request: any;
response: any;
}) => {
const data = await request.body().value;
const newNotes: Notes = {
text: data.text,
};
await getDb().collection("notes").insertOne(newNotes);
response.status = 201;
response.body = { message: "Created notes!", todo: newNotes };
},
getById: async ({
params,
response,
}: {
params: { noteId: string };
response: any;
}) => {
const tid = params.noteId!;
const notes = await getDb()
.collection("notes")
.findOne({ _id: new ObjectId(tid) });
response.status = 201;
response.body = { message: "New notes!", notes: notes };
},
updateNoteById: async ({
params,
request,
response,
}: {
params: { noteId: string };
request: any;
response: any;
}) => {
const tid = params.noteId!;
const data = await request.body().value;
const notes = await getDb()
.collection("notes")
.updateOne({ _id: new ObjectId(tid) }, { $set: { text: data.text } });
response.status = 201;
response.body = { message: "Updated notes", notes: notes };
},
deleteNoteById: async ({
params,
response,
}: {
params: { noteId: string };
response: any;
}) => {
const tid = params.noteId!;
const notes = await getDb()
.collection("notes")
.deleteOne({ _id: new ObjectId(tid) });
response.status = 201;
response.body = { message: "Deleted notes", notes: notes };
},
};
Step 5: Create interface/types
As we clearly know typescript do check types strictly that is what that advantage we have over using typescript so we need to either create interface or types for defining the types of data we are passing in request and getting in request
Create interfaces folder under root path of your project and inside that folder create notes.ts file and copy paste below code inside notes.ts file
export interface Notes {
text: string;
}
Step 6: Create routes folder under root path of your project folder and under that folder create notes.ts file
This is the route file for your deno Rest API here you will be defining paths for your UPDATE, DELETE, GET, POST request
Copy paste below code in the file
import { Router } from "https://deno.land/x/oak/mod.ts";
const router = new Router();
import notesController from "../controllers/notes.ts";
router.get("/notes", notesController.getAllNotes);
router.post("/notes", notesController.createNotes);
router.put("/notes/:noteId", notesController.updateNoteById);
router.get("/notes/:noteId", notesController.getById);
router.delete("/notes/:noteId", notesController.deleteNoteById);
export default router;
Step 7: Create MongoDB database configuration file
Create helpers folder under root path of your project inside helpers folder create db.ts file inside db.ts file copy paste below code
import {
MongoClient,
Database,
} from "https://deno.land/x/mongo@v0.29.4/mod.ts";
let db: Database;
export async function connect() {
const client = new MongoClient();
await client.connect("mongodb://localhost:27017");
console.log("Database connected");
db = client.database("notes");
}
export function getDb() {
return db;
}
Complete folder structure, run the project, test the API
By default deno deosn't allow permission for anything this is extra feature which deno has introduced so in order to allow permission we need to mention in the command itself
Copy paste below command and run in your terminal by navigating to project folder
deno run --allow-net --allow-read --allow-write app.ts