Servite 支持一体化的 API 调用,意思就是可以在前端直接 import API 函数,调用时会自动转换成 HTTP 请求。这个方式有以下好处:
在前面我们已经介绍过如何定义 API 路由了,但想要实现一体化调用,你需要改为从 servite/server
中导出 apiHandler
方法来定义接口:
// <root>/src/server/api/todo.get.ts
import { apiHandler } from 'servite/server';
export default apiHandler(async (args, event) => {
// ...
return {
code: 0,
msg: 'ok',
data: 'This is ok',
};
});
接着就可以在前端代码中直接 import 该文件来进行调用了:
// <root>/src/pages/page.tsx
import { useState, useEffect } from 'react';
import getTodo from '../server/api/todo.get';
export default function Page() {
const [res, setRes] = useState();
useEffect(() => {
(async () => {
// 此调用会被自动转换成发起请求:GET /api/todo
const res = await getTodo();
setRes(res);
})();
}, []);
// ...
}
一体化 API 调用相关 的配置项可以看这里。
结合 Typescript,定义好接口的入参类型和返回结果类型,能让一体化调用达到更好的开发体验:
// <root>/src/server/api/todo.get.ts
import { apiHandler } from 'servite/server';
export enum Bar {
Great,
Cool,
}
// 定义入参类型
export interface Args {
foo: string;
bar: Bar;
}
// 定义响应类型
export interface Result {
code: number;
msg: string;
data: string;
}
// 通过泛型来约束函数类型
export default apiHandler<Args, Result>(async (args: Args, event) => {
// ...
return {
code: 0,
msg: 'ok',
data: 'This is ok',
};
});
在前端 import 相关的类型:
// <root>/src/pages/page.tsx
import { useState, useEffect } from 'react';
import getTodo, { Result, Bar } from '../server/api/todo.get';
export default function Page() {
// 使用 Result 作为 useState 的泛型
const [res, setRes] = useState<Result>();
useEffect(() => {
(async () => {
// 此调用会被自动转换成发起请求:GET /api/todo?foo=xxx&bar=0
const res = await getTodo({
foo: 'xxx',
bar: Bar.Great,
});
setRes(res);
})();
}, []);
// ...
}