Arktype
Arktype validation example
Form input handling and Arktype validation. The request input is validated on the client-side before being sent to the server where it is validated again.
Result
Code
1import { prefix, post, openapi, type VovkOutput, createStandardValidation, KnownAny } from 'vovk';
2import { type } from 'arktype';
3
4const withArk = createStandardValidation({
5 toJSONSchema: (model: type) => model.toJsonSchema(),
6});
7
8@prefix('users-arktype')
9export default class UserArktypeController {
10 @openapi({
11 summary: 'Update user (Arktype)',
12 description: 'Update user by ID with Arktype validation',
13 })
14 @post('{id}')
15 static updateUser = withArk({
16 body: type({
17 name: type('string').describe('User full name'),
18 age: type('0 < number < 120').describe('User age'),
19 email: type('string.email').describe('User email'),
20 }),
21 params: type({
22 id: type('string.uuid').describe('User ID'),
23 }),
24 query: type({
25 notify: type('"email" | "push" | "none"').describe('Notification type'),
26 }),
27 output: type({
28 success: type('boolean').describe('Success status'),
29 }),
30 async handle(req, { id }) {
31 const { name, age } = await req.json();
32 const notify = req.nextUrl.searchParams.get('notify');
33
34 // do something with the data
35 console.log(`Updating user ${id}:`, { name, age, notify });
36 return {
37 success: true,
38 } satisfies VovkOutput<typeof UserArktypeController.updateUser>;
39 },
40 });
41}
1import { prefix, post, openapi, type VovkOutput, createStandardValidation, KnownAny } from 'vovk';
2import { type } from 'arktype';
3
4const withArk = createStandardValidation({
5 toJSONSchema: (model: type) => model.toJsonSchema(),
6});
7
8@prefix('users-arktype')
9export default class UserArktypeController {
10 @openapi({
11 summary: 'Update user (Arktype)',
12 description: 'Update user by ID with Arktype validation',
13 })
14 @post('{id}')
15 static updateUser = withArk({
16 body: type({
17 name: type('string').describe('User full name'),
18 age: type('0 < number < 120').describe('User age'),
19 email: type('string.email').describe('User email'),
20 }),
21 params: type({
22 id: type('string.uuid').describe('User ID'),
23 }),
24 query: type({
25 notify: type('"email" | "push" | "none"').describe('Notification type'),
26 }),
27 output: type({
28 success: type('boolean').describe('Success status'),
29 }),
30 async handle(req, { id }) {
31 const { name, age } = await req.json();
32 const notify = req.nextUrl.searchParams.get('notify');
33
34 // do something with the data
35 console.log(`Updating user ${id}:`, { name, age, notify });
36 return {
37 success: true,
38 } satisfies VovkOutput<typeof UserArktypeController.updateUser>;
39 },
40 });
41}
1import { prefix, post, openapi, type VovkOutput, createStandardValidation, KnownAny } from 'vovk';
2import { type } from 'arktype';
3
4const withArk = createStandardValidation({
5 toJSONSchema: (model: type) => model.toJsonSchema(),
6});
7
8@prefix('users-arktype')
9export default class UserArktypeController {
10 @openapi({
11 summary: 'Update user (Arktype)',
12 description: 'Update user by ID with Arktype validation',
13 })
14 @post('{id}')
15 static updateUser = withArk({
16 body: type({
17 name: type('string').describe('User full name'),
18 age: type('0 < number < 120').describe('User age'),
19 email: type('string.email').describe('User email'),
20 }),
21 params: type({
22 id: type('string.uuid').describe('User ID'),
23 }),
24 query: type({
25 notify: type('"email" | "push" | "none"').describe('Notification type'),
26 }),
27 output: type({
28 success: type('boolean').describe('Success status'),
29 }),
30 async handle(req, { id }) {
31 const { name, age } = await req.json();
32 const notify = req.nextUrl.searchParams.get('notify');
33
34 // do something with the data
35 console.log(`Updating user ${id}:`, { name, age, notify });
36 return {
37 success: true,
38 } satisfies VovkOutput<typeof UserArktypeController.updateUser>;
39 },
40 });
41}
1import { prefix, post, openapi, type VovkOutput, createStandardValidation, KnownAny } from 'vovk';
2import { type } from 'arktype';
3
4const withArk = createStandardValidation({
5 toJSONSchema: (model: type) => model.toJsonSchema(),
6});
7
8@prefix('users-arktype')
9export default class UserArktypeController {
10 @openapi({
11 summary: 'Update user (Arktype)',
12 description: 'Update user by ID with Arktype validation',
13 })
14 @post('{id}')
15 static updateUser = withArk({
16 body: type({
17 name: type('string').describe('User full name'),
18 age: type('0 < number < 120').describe('User age'),
19 email: type('string.email').describe('User email'),
20 }),
21 params: type({
22 id: type('string.uuid').describe('User ID'),
23 }),
24 query: type({
25 notify: type('"email" | "push" | "none"').describe('Notification type'),
26 }),
27 output: type({
28 success: type('boolean').describe('Success status'),
29 }),
30 async handle(req, { id }) {
31 const { name, age } = await req.json();
32 const notify = req.nextUrl.searchParams.get('notify');
33
34 // do something with the data
35 console.log(`Updating user ${id}:`, { name, age, notify });
36 return {
37 success: true,
38 } satisfies VovkOutput<typeof UserArktypeController.updateUser>;
39 },
40 });
41}
1'use client';
2import { useState, type FormEvent } from 'react';
3import { UserArktypeRPC } from 'vovk-client';
4import type { VovkReturnType } from 'vovk';
5
6export default function ArktypeFormExample() {
7 const [response, setResponse] = useState<VovkReturnType<typeof UserArktypeRPC.updateUser> | null>(null);
8 const [error, setError] = useState<Error | null>(null);
9 const [name, setName] = useState('');
10 const [email, setEmail] = useState('');
11 const [age, setAge] = useState(30);
12 const [disableClientValidation, setDisableClientValidation] = useState(false);
13 const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
14 e.preventDefault();
15 try {
16 setResponse(
17 await UserArktypeRPC.updateUser({
18 body: { name, email, age },
19 query: { notify: 'push' },
20 params: { id: '5a279068-35d6-4d67-94e0-c21ef4052eea' },
21 disableClientValidation,
22 })
23 );
24 setError(null);
25 } catch (e) {
26 setError(e as Error);
27 setResponse(null);
28 }
29 };
30
31 return (
32 <form onSubmit={onSubmit}>
33 <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
34 <input type="text" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
35 <label>Age:</label>
36 <input type="number" placeholder="Age" value={age} onChange={(e) => setAge(e.target.valueAsNumber)} />
37 <label className="block mb-4">
38 <input
39 type="checkbox"
40 className="mr-2"
41 checked={disableClientValidation}
42 onChange={(e) => setDisableClientValidation(e.target.checked)}
43 />
44 Disable client-side validation
45 </label>
46 <button>Submit</button>
47
48 {response && (
49 <div className="text-left">
50 <h3>Response:</h3>
51 <pre>{JSON.stringify(response, null, 2)}</pre>
52 </div>
53 )}
54
55 {error && <div className="overflow-auto">❌ {String(error)}</div>}
56 </form>
57 );
58}
1'use client';
2import { useState, type FormEvent } from 'react';
3import { UserArktypeRPC } from 'vovk-client';
4import type { VovkReturnType } from 'vovk';
5
6export default function ArktypeFormExample() {
7 const [response, setResponse] = useState<VovkReturnType<typeof UserArktypeRPC.updateUser> | null>(null);
8 const [error, setError] = useState<Error | null>(null);
9 const [name, setName] = useState('');
10 const [email, setEmail] = useState('');
11 const [age, setAge] = useState(30);
12 const [disableClientValidation, setDisableClientValidation] = useState(false);
13 const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
14 e.preventDefault();
15 try {
16 setResponse(
17 await UserArktypeRPC.updateUser({
18 body: { name, email, age },
19 query: { notify: 'push' },
20 params: { id: '5a279068-35d6-4d67-94e0-c21ef4052eea' },
21 disableClientValidation,
22 })
23 );
24 setError(null);
25 } catch (e) {
26 setError(e as Error);
27 setResponse(null);
28 }
29 };
30
31 return (
32 <form onSubmit={onSubmit}>
33 <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
34 <input type="text" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
35 <label>Age:</label>
36 <input type="number" placeholder="Age" value={age} onChange={(e) => setAge(e.target.valueAsNumber)} />
37 <label className="block mb-4">
38 <input
39 type="checkbox"
40 className="mr-2"
41 checked={disableClientValidation}
42 onChange={(e) => setDisableClientValidation(e.target.checked)}
43 />
44 Disable client-side validation
45 </label>
46 <button>Submit</button>
47
48 {response && (
49 <div className="text-left">
50 <h3>Response:</h3>
51 <pre>{JSON.stringify(response, null, 2)}</pre>
52 </div>
53 )}
54
55 {error && <div className="overflow-auto">❌ {String(error)}</div>}
56 </form>
57 );
58}
1'use client';
2import { useState, type FormEvent } from 'react';
3import { UserArktypeRPC } from 'vovk-client';
4import type { VovkReturnType } from 'vovk';
5
6export default function ArktypeFormExample() {
7 const [response, setResponse] = useState<VovkReturnType<typeof UserArktypeRPC.updateUser> | null>(null);
8 const [error, setError] = useState<Error | null>(null);
9 const [name, setName] = useState('');
10 const [email, setEmail] = useState('');
11 const [age, setAge] = useState(30);
12 const [disableClientValidation, setDisableClientValidation] = useState(false);
13 const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
14 e.preventDefault();
15 try {
16 setResponse(
17 await UserArktypeRPC.updateUser({
18 body: { name, email, age },
19 query: { notify: 'push' },
20 params: { id: '5a279068-35d6-4d67-94e0-c21ef4052eea' },
21 disableClientValidation,
22 })
23 );
24 setError(null);
25 } catch (e) {
26 setError(e as Error);
27 setResponse(null);
28 }
29 };
30
31 return (
32 <form onSubmit={onSubmit}>
33 <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
34 <input type="text" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
35 <label>Age:</label>
36 <input type="number" placeholder="Age" value={age} onChange={(e) => setAge(e.target.valueAsNumber)} />
37 <label className="block mb-4">
38 <input
39 type="checkbox"
40 className="mr-2"
41 checked={disableClientValidation}
42 onChange={(e) => setDisableClientValidation(e.target.checked)}
43 />
44 Disable client-side validation
45 </label>
46 <button>Submit</button>
47
48 {response && (
49 <div className="text-left">
50 <h3>Response:</h3>
51 <pre>{JSON.stringify(response, null, 2)}</pre>
52 </div>
53 )}
54
55 {error && <div className="overflow-auto">❌ {String(error)}</div>}
56 </form>
57 );
58}
1'use client';
2import { useState, type FormEvent } from 'react';
3import { UserArktypeRPC } from 'vovk-client';
4import type { VovkReturnType } from 'vovk';
5
6export default function ArktypeFormExample() {
7 const [response, setResponse] = useState<VovkReturnType<typeof UserArktypeRPC.updateUser> | null>(null);
8 const [error, setError] = useState<Error | null>(null);
9 const [name, setName] = useState('');
10 const [email, setEmail] = useState('');
11 const [age, setAge] = useState(30);
12 const [disableClientValidation, setDisableClientValidation] = useState(false);
13 const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
14 e.preventDefault();
15 try {
16 setResponse(
17 await UserArktypeRPC.updateUser({
18 body: { name, email, age },
19 query: { notify: 'push' },
20 params: { id: '5a279068-35d6-4d67-94e0-c21ef4052eea' },
21 disableClientValidation,
22 })
23 );
24 setError(null);
25 } catch (e) {
26 setError(e as Error);
27 setResponse(null);
28 }
29 };
30
31 return (
32 <form onSubmit={onSubmit}>
33 <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
34 <input type="text" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
35 <label>Age:</label>
36 <input type="number" placeholder="Age" value={age} onChange={(e) => setAge(e.target.valueAsNumber)} />
37 <label className="block mb-4">
38 <input
39 type="checkbox"
40 className="mr-2"
41 checked={disableClientValidation}
42 onChange={(e) => setDisableClientValidation(e.target.checked)}
43 />
44 Disable client-side validation
45 </label>
46 <button>Submit</button>
47
48 {response && (
49 <div className="text-left">
50 <h3>Response:</h3>
51 <pre>{JSON.stringify(response, null, 2)}</pre>
52 </div>
53 )}
54
55 {error && <div className="overflow-auto">❌ {String(error)}</div>}
56 </form>
57 );
58}
Last updated on