Validation support for incoming parameters based on type. #182
-
I'm using the following test code:
Running this on cloudflare workers, now how should I validate the incoming value for
that it should always be a +ve int and is there a default/built-in support for this? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
Hey there! The short answer is: you shouldn't. Params are always strings (given that they come from a string), and you have zero control over enforcement of what someone sends to that url. This is what middleware is for. If you want to validate the id, verify it's an int, and then put it back in the request as request.id = Number(request.params.id), then you could do something like this: type RequestWithID = {
id: number
} & IRequest
// define middleware
const withId = request => {
if (!request.params.id?.match(/^\d+$/)) {
return error(400, 'id should be a number.')
}
request.id = Number(request.params.id)
}
// use middleware (version 1)
router.get<RequestWithID>('todos:id', withId, ({ id }) => {
// id typed as number
})
// use middleware (version 2)
router.get('todos/:id', withId, (request: RequestWithID) => {
// request.id typed as number
}) |
Beta Was this translation helpful? Give feedback.
-
Correct, I thought it would be beneficial if there will be a library/module similar to
import { OpenAPIRouter } from "@cloudflare/itty-router-openapi";
import { TodoListById } from "./todoList";
const router = OpenAPIRouter({
schema: {
info: {
title: "Worker OpenAPI Example",
version: "1.0",
},
},
});
// router.get("/api/todos/", TodoList);
router.get("/api/todos/:id", TodoListById);
// Redirect root request to the /docs page
router.original.get("/", (request) =>
Response.redirect(`${request.url}docs`, 302)
);
// 404 for everything else
router.all("*", () => new Response("Not Found.", { status: 404 }));
export default {
fetch: router.handle,
}; and import {
Bool,
DateOnly,
Int,
OpenAPIRoute,
Path,
Query,
Str,
} from "@cloudflare/itty-router-openapi";
const Todo = {
id: new Int({ required: true, example: "1" }),
message: new Str({ required: true, example: "New Todo" })
};
const todosData = [
{ id: 1, message: 'Pet the puppy' },
{ id: 2, message: 'Pet the kitty' },
]
export class TodoListById extends OpenAPIRoute {
static schema = {
tags: ["Todos"],
summary: "List Todos",
parameters: {
// parameter key needs to be the same name as the route path
id: Path(Int, {
description: "Todo number",
default: 0,
required: true
})
},
responses: {
"200": {
schema: {
todos: [Todo],
},
},
},
};
async handle(
request,
env,
context,
data
) {
// Retrieve the validated parameters
// const { page, isCompleted } = data;
const { id } = data;
console.log(id)
const todo = todosData.find(t => t.id === id)
return todo
}
} Please lmk if a similar approach is possible with |
Beta Was this translation helpful? Give feedback.
-
Definitely not built-in! If you want more strict contract enforcement, definitely recommend using a wrapper library like |
Beta Was this translation helpful? Give feedback.
Definitely not built-in! If you want more strict contract enforcement, definitely recommend using a wrapper library like
@cloudflare/itty-router-openapi
! :)