Automatic Validation
Frourio provides some automatic conversions and small validation on path parameters, URL queries and request bodies.
Path Parameter
The type can be specified by appending @string
or @number
to path parameters, and the default in frourio is string
.
When the type is specified as number
, frourio automatically converts string to number and validates that it is not NaN.
When the type is not specified, there is a difference in the behavior of Frourio and Aspida.
Frourio interprets the type as string
as mentioned above, but Aspida interprets it as string | number
.
This is due to the information loss that occurs as path parameters are passed through an URL.
Unless there are special circumstances, you should specify their types.
Example
API Definition
import { Task } from '$/types';
export type Methods = {
get: {
resBody: Task;
};
};
Controller
import { defineController } from './$relay';
import { findTask } from '$/service/tasks';
export default defineController(() => ({
get: async ({ params }) => {
const task = await findTask(params.taskId);
return task ? { status: 200, body: task } : { status: 404 };
},
}));
Results
$ curl http://localhost:8080/api/tasks
[{"id":0,"label":"sample task","done":false}]
$ curl http://localhost:8080/api/tasks/0
{"id":0,"label":"sample task","done":false}
$ curl http://localhost:8080/api/tasks/1 -i
HTTP/1.1 404 Not Found
$ curl http://localhost:8080/api/tasks/abc -i
HTTP/1.1 400 Bad Request
URL Query
When the URL query specified as ...
- required
- Frourio automatically validates that it exists.
- If it isn't and it is specified as array, frourio sets an empty array
[]
.
number
- Frourio automatically converts string to number and validates that it is not NaN.
boolean
- Frourio automatically converts string (
'true'
or'false'
) to boolean.
- Frourio automatically converts string (
And if its key ends in square brackets (e.g. foo[]
), frourio automatically removes the brackets (e.g.
foo
).
Example
API Definition
import { Task } from '$/types';
export type Methods = {
get: {
query?: {
limit: number;
};
resBody: Task[];
};
};
Controller
import { defineController } from './$relay';
import { getTasks } from '$/service/tasks';
export default defineController(() => ({
get: async ({ query }) => ({
status: 200,
body: (await getTasks()).slice(0, query?.limit),
}),
}));
Results
$ curl http://localhost:8080/api/tasks
[{"id":0,"label":"sample task 0","done":false},{"id":1,"label":"sample task 1","done":false},{"id":1,"label":"sample task 2","done":false}]
$ curl http://localhost:8080/api/tasks?limit=1
[{"id":0,"label":"sample task 0","done":false}]
$ curl http://localhost:8080/api/tasks?limit=abc -i
HTTP/1.1 400 Bad Request
Request body
When the reqFormat
is specified as FormData
, frourio automatically converts and validates it.
- If it is array, converts it to array (and if it doesn't exists, set an empty array).
- Extracts file or value.
- If some values are specified as optional and they are empty, remove them.