• 安装Api生成主程序需要的依赖

pnpm add -D fs-extra uuid adm-zip
  • scripts下新建generate-api.js文件,这是生成Api的主程序

const http = require('http');
const fs = require('fs');
const fse = require('fs-extra');
const uuid = require('uuid');
const os = require('os');
const AdmZip = require('adm-zip');

const sourceUrl = "http://localhost:8080/ts.zip";
const tmpFilePath = os.tmpdir() + '/' + uuid.v4() + '.zip';
const generatePath = "src/__generated";

console.log("Downloading " + sourceUrl + "...");

const tmpFile = fs.createWriteStream(tmpFilePath);

const request = http.get(sourceUrl, (response) => {
    response.pipe(tmpFile);
    tmpFile.on("finish", () => {
        tmpFile.close();
        console.log("File save success: ", tmpFilePath);

        // Remove generatePath if it exists
        if (fs.existsSync(generatePath)) {
            console.log("Removing existing generatePath...");
            fse.removeSync(generatePath);
            console.log("Existing generatePath removed.");
        }

        // Unzip the file using adm-zip
        console.log("Unzipping the file...");
        const zip = new AdmZip(tmpFilePath);
        zip.extractAllTo(generatePath, true);
        console.log("File unzipped successfully.");

        // Remove the temporary file
        console.log("Removing temporary file...");
        fs.unlink(tmpFilePath, (err) => {
            if (err) {
                console.error("Error while removing temporary file:", err);
            } else {
                console.log("Temporary file removed.");
            }
        });
    });
});
  • package.jsonscripts中,新增运行api生成主程序的入口

"api": "node scripts/generate-api.js"
  • pnpm api启动Api生成

pnpm api
  • src/common下,新建ApiInstance.ts。这是一个使用api的入口

import { Api } from "../__generated";

const BASE_URL = "http://localhost:8080";

export const api = new Api(async({uri, method, headers, body}) => {
    const tenant = (window as any).__tenant as string | undefined;
    const response = await fetch(`${BASE_URL}${uri}`, {
        method,
        body: body !== undefined ? JSON.stringify(body) : undefined,
        headers: {
            'content-type': 'application/json;charset=UTF-8',
            ...headers,
            ...(tenant !== undefined && tenant !== "" ? {tenant} : {})
        }
    });
    if (response.status !== 200) {
        throw response.json();
    }
    const text = await response.text();
    if (text.length === 0) {
        return null;
    }
    return JSON.parse(text);
});
  • 在需要使用api的地方,导入api

import { BookDto } from '@/__generated/model/dto';
import { useImmer } from 'use-immer';
import { api } from '@/common/ApiInstance';

const [books, booksUpdater] = useImmer<BookDto['BookService/DEFAULT_FETCHER'][]>([]);

useEffect(() => {
  api.bookService
    .findBooks({ pageSize: 10 })
    .then(({ content: books }) => {
      booksUpdater(() => books);
    });
}, []);