How Deno's Oak Handles Request Information

overview

In Deno’s Oak, request processing is done inside middleware functions. A context object is passed as an argument to the middleware function. Use this object to retrieve data related to the request, generate the response, and so on.

This section describes how to process requests with Oak using the following versions:

Oak v8.0.0
Deno v1.16.2

Also, all the code I’ve created so far is listed below. https://github.com/wiblok/Oak

How to get request information

Use the context object to get information about the request. A context object contains information about the request from the client. Used within Oak middleware functions to access data such as request headers, parameters, and body.

The sample code below is an example of understanding the context object in Oak. Receive a GET request, access request headers, query parameters, and return a response containing those values.

request.ts

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

const router = new Router();
router.get('/', (context) => {
  // get request headers
  const headers = context.request.headers;

  // get query parameters
  const queryParam = context.request.url.searchParams.get('param');

  const response = {
    headers: headers,
    queryParam: queryParam,
  };

  context.response.body = response;
});

const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());

app.listen({ port: 3000 });
console.log('Server is running on port 3000');

Below is a description of the provided source code.

  1. Import Application and Router from the oak module.
import { Application, Router } from 'https://deno.land/x/oak/mod.ts';
  1. Create an instance of Router.
const router = new Router();
  1. Define middleware when a GET request is sent to the root path /.
router.get('/', (context) => {
  // get request headers
  const headers = context.request.headers;

  // get query parameters
  const queryParam = context.request.url.searchParams.get('param');

  const response = {
    headers: headers,
    queryParam: queryParam,
  };

  // set the response body
  context.response.body = response;
});
  1. Create an instance of Application.
const app = new Application();
  1. Register Router as middleware.
app.use(router.routes());
app.use(router.allowedMethods());
  1. Make the server listen on the specified port number.
app.listen({ port: 3000 });
  1. Output to the console that the server has started.
console.log('Server is running on port 3000');

The above is the outline of the source code. This code receives a GET request to the root path /, retrieves the request headers and query parameters and returns them as a response. The server listens on port number 3000 and prints messages to the console after it starts.

curl http://localhost:3000

How to validate request information

This example validates that the name and age fields are required and age is numeric when a POST request is sent to the /users endpoint.

validate.ts

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

const router = new Router();

router.post("/users", async (context) => {
  const requestBody = await context.request.body().value;
  console.log(requestBody);
  if (
    !requestBody.name ||
    typeof requestBody.name !== "string" ||
    !requestBody.age ||
    typeof requestBody.age !== "number"
  ) {
    context.response.status = 400;
    context.response.body = { error: "Invalid request body" };
    return;
  }

  const { name, age } = requestBody;

  // What to do if validation succeeds
  context.response.body = { message: "User created successfully", name, age };
});

const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());

app.listen({ port: 3000 });
console.log("Server is running on port 3000");

Below is a description of the provided source code.

  1. Import Application and Router from the oak module.
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
  1. Create an instance of Router.
const router = new Router();
  1. Define middleware when a POST request is sent to the /users endpoint.
router.post("/users", async (context) => {
  // get request body
  const requestBody = await context.request.body().value;
  console.log(requestBody);
  
  // validation check
  if (
    !requestBody.name ||
    typeof requestBody.name !== "string" ||
    !requestBody.age ||
    typeof requestBody.age !== "number"
  ) {
    // return error response in case of validation error
    context.response.status = 400;
    context.response.body = { error: "Invalid request body" };
    return;
  }

  const { name, age } = requestBody;

  // What to do if validation succeeds
  context.response.body = { message: "User created successfully", name, age };
});
  1. Create an instance of Application.
const app = new Application();
  1. Register Router as middleware.
app.use(router.routes());
app.use(router.allowedMethods());
  1. Make the server listen on the specified port number.
app.listen({ port: 3000 });
  1. Output to the console that the server has started.
console.log("Server is running on port 3000");

The above is the outline of the source code. This code receives a POST request to the /users endpoint and validates the request body. If validation succeeds, return a success message and user information as a response. Returns an error response if validation fails. The server listens on port number 3000 and prints messages to the console after it starts.

# test a successful request
curl -X POST -H "Content-Type: application/json" -d '{"name":"John", "age": 25}' http://localhost:3000/users
# test requests with validation errors
curl -X POST -H "Content-Type: application/json" -d '{"name":"John"}' http://localhost:3000/users

summary

Using the context object allows you to:

  • You can access request data such as request headers and query parameters.
  • Get data for different parts of the request, such as request path parameters and body data.
  • Obtain authentication and authorization information related to requests, such as authentication tokens and session information.
  • Use middleware functions to validate and transform request data.

The context object allows you to perform various operations on the request data. The context object has many properties and methods that allow for a high degree of customization and control.