0
0
DenoHow-ToBeginner ยท 4 min read

How to Use Middleware in Oak Framework in Deno

In Oak for Deno, middleware are functions that receive a context and next function to process HTTP requests and responses. You use app.use() to add middleware, and call await next() inside middleware to pass control to the next one.
๐Ÿ“

Syntax

Middleware in Oak is an async function that takes two parameters: context (holds request and response info) and next (a function to call the next middleware).

You add middleware to your Oak app using app.use(middlewareFunction).

Inside your middleware, call await next() to continue to the next middleware or route handler.

typescript
import { Application } from "https://deno.land/x/oak@v12.5.0/mod.ts";

const app = new Application();

// Middleware function
async function logger(context, next) {
  console.log(`Request: ${context.request.method} ${context.request.url}`);
  await next(); // Pass control to next middleware
  console.log(`Response status: ${context.response.status}`);
}

app.use(logger);

app.use((context) => {
  context.response.body = "Hello from Oak middleware!";
});

await app.listen({ port: 8000 });
๐Ÿ’ป

Example

This example shows a simple Oak server with a logging middleware that prints request and response info to the console. It demonstrates how middleware can run code before and after the next middleware or route handler.

typescript
import { Application } from "https://deno.land/x/oak@v12.5.0/mod.ts";

const app = new Application();

// Logger middleware
app.use(async (context, next) => {
  console.log(`--> ${context.request.method} ${context.request.url}`);
  await next();
  console.log(`<-- ${context.response.status}`);
});

// Simple response middleware
app.use((context) => {
  context.response.body = "Hello Oak Middleware!";
});

console.log("Server running on http://localhost:8000");
await app.listen({ port: 8000 });
Output
Server running on http://localhost:8000 --> GET http://localhost:8000/ <-- 200
โš ๏ธ

Common Pitfalls

One common mistake is forgetting to call await next() inside middleware, which stops the chain and prevents later middleware or route handlers from running.

Another pitfall is modifying the response before calling await next() without considering that later middleware might overwrite it.

typescript
import { Application } from "https://deno.land/x/oak@v12.5.0/mod.ts";

const app = new Application();

// Wrong: missing await next(), so response never reaches final handler
app.use(async (context) => {
  console.log("Middleware without next call");
  // No await next() here
  context.response.body = "Stopped here";
});

// This middleware will never run
app.use((context) => {
  context.response.body = "This will not show";
});

await app.listen({ port: 8000 });

// Correct way:
// app.use(async (context, next) => {
//   console.log("Middleware with next call");
//   await next();
// });
๐Ÿ“Š

Quick Reference

  • Middleware signature: async (context, next) => { ... }
  • Add middleware: app.use(middlewareFunction)
  • Call next middleware: await next()
  • Order matters: Middleware run in the order added
  • Use middleware for: logging, authentication, error handling, modifying requests/responses
โœ…

Key Takeaways

Middleware in Oak are async functions with parameters context and next.
Always call await next() inside middleware to continue the chain.
Add middleware using app.use() in the order you want them to run.
Middleware can run code before and after calling next() for flexible control.
Forgetting await next() stops later middleware and handlers from running.