Step-by-Step Deno REST API Development for Modern Web Services

Developing a REST API is essential for creating modern web services that are scalable, efficient, and easy to maintain. Deno, a secure runtime for JavaScript and TypeScript, offers a streamlined environment for building such APIs. In this article, we will walk through a step-by-step process to develop a REST API using Deno, covering setup, routing, data handling, and deployment.

Prerequisites and Setup

Before we begin, ensure you have the following installed on your system:

  • Node.js (for managing dependencies, optional)
  • Deno (latest version)
  • Code editor (e.g., VS Code)
  • Postman or any API testing tool

Install Deno from the official website: https://deno.land/. Verify the installation by running:

deno --version

Creating the Project Structure

Create a new directory for your project and initialize your files:

mkdir deno-rest-api
cd deno-rest-api
touch main.ts

Installing Dependencies

For routing, we’ll use the Oak middleware framework, which is popular in Deno projects. Import it directly from a CDN in your main.ts file.

// main.ts
import { Application, Router } from "https://deno.land/x/oak/mod.ts";

const app = new Application();
const router = new Router();

Building the API Endpoints

Define routes for CRUD operations: Create, Read, Update, and Delete.

// In main.ts
let items = [
  { id: 1, name: "Item One" },
  { id: 2, name: "Item Two" },
];

// GET all items
router.get("/items", (context) => {
  context.response.body = items;
});

// GET item by ID
router.get("/items/:id", (context) => {
  const id = parseInt(context.params.id);
  const item = items.find((item) => item.id === id);
  if (item) {
    context.response.body = item;
  } else {
    context.response.status = 404;
    context.response.body = { message: "Item not found" };
  }
});

// POST create new item
router.post("/items", async (context) => {
  const body = await context.request.body().value;
  const newItem = {
    id: items.length + 1,
    name: body.name,
  };
  items.push(newItem);
  context.response.status = 201;
  context.response.body = newItem;
});

// PUT update item
router.put("/items/:id", async (context) => {
  const id = parseInt(context.params.id);
  const body = await context.request.body().value;
  const index = items.findIndex((item) => item.id === id);
  if (index !== -1) {
    items[index] = { id, name: body.name };
    context.response.body = items[index];
  } else {
    context.response.status = 404;
    context.response.body = { message: "Item not found" };
  }
});

// DELETE item
router.delete("/items/:id", (context) => {
  const id = parseInt(context.params.id);
  items = items.filter((item) => item.id !== id);
  context.response.status = 204;
});

Starting the Server

Bind the router to the application and start listening on a port.

// In main.ts
app.use(router.routes());
app.use(router.allowedMethods());

console.log("Server running on http://localhost:8000");
await app.listen({ port: 8000 });

Testing the API

Use Postman or curl to test your API endpoints. For example, to fetch all items:

curl http://localhost:8000/items

To add a new item:

curl -X POST -H "Content-Type: application/json" -d '{"name": "New Item"}' http://localhost:8000/items

Conclusion

With these steps, you’ve built a simple REST API using Deno and Oak. This serves as a foundation for more complex web services, including database integration, authentication, and real-time features. Deno’s modern architecture and TypeScript support make it an excellent choice for developing scalable APIs.