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.
- Import
Application
andRouter
from theoak
module.
import { Application, Router } from 'https://deno.land/x/oak/mod.ts';
- Create an instance of
Router
.
const router = new Router();
- 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;
});
- Create an instance of
Application
.
const app = new Application();
- Register
Router
as middleware.
app.use(router.routes());
app.use(router.allowedMethods());
- Make the server listen on the specified port number.
app.listen({ port: 3000 });
- 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.
- Import
Application
andRouter
from theoak
module.
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
- Create an instance of
Router
.
const router = new Router();
- 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 };
});
- Create an instance of
Application
.
const app = new Application();
- Register
Router
as middleware.
app.use(router.routes());
app.use(router.allowedMethods());
- Make the server listen on the specified port number.
app.listen({ port: 3000 });
- 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.