Skip to main content

前端开发

farrow-vite-react 项目模板中,已经包含了简单的示例代码,现在让我们来解读一下前端部分。

在运行 npm run dev 命令启动应用之后,应该可以看到文件 src/api/greet.ts,里面的代码大概如下:

/**
* This file was generated by farrow-api
* Don't modify it manually
*/
import { createApiPipelineWithUrl, ApiInvokeOptions } from 'farrow-api-client';
/**
* {@label GreetInput}
*/
export type GreetInput = {
/**
* @remarks The name for greeting
*/
name: string;
};
/**
* {@label GreetOutput}
*/
export type GreetOutput = {
/**
* @remarks The greeting came from server
*/
greet: string;
};
export const url = 'http://localhost:3003/api/greet';
export const apiPipeline = createApiPipelineWithUrl(url);
export const api = {
/**
* @remarks Greeting
*/
greet: (input: GreetInput, options?: ApiInvokeOptions) =>
apiPipeline.invoke(
{ type: 'Single', path: ['greet'], input },
options
) as Promise<GreetOutput>,
};

正如开头的注释部分所说的,这个文件是由 farrow-api 自动生成的,一般情况下不应该被手动修改。

farrow-api 会将服务端的 input schemaoutput schema 编译为 typescript 类型,并将 api service 编译为 http-client 的接口调用代码。

也就是说,前端相当于继承了服务端的类型定义和方法调用的代码。

src/app.tsx 文件中,我们可以像 import 普通模块一样,import 服务端生成的 greet.ts 文件。

import React, { useState, useEffect } from 'react';
import logo from './logo.svg';
import './App.css';
import { api as GreetApi } from './api/greet';

通过 api as GreetApi 起别名,我们可以引入多个生成的 client.ts,避免命名冲突。

然后,我们可以像调用普通方法一样,调用 GreetApi.greet(input),它在内部会通过 http 协议请求服务端接口,获取并返回指定类型的数据。

不需要开发者 as MyType 的方式去主动标记。

function App() {
const [greet, setGreet] = useState('');
useEffect(() => {
const task = async () => {
const result = await GreetApi.greet({
name: `Farrow + React + Vite`,
});
setGreet(result.greet);
};
task().catch((error) => {
console.log('error', error);
});
}, []);
if (!greet) return null;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>{greet}</p>
<p>
Edit <code>App.tsx</code> and save to test HMR updates.
</p>
<p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
{' | '}
<a
className="App-link"
href="https://github.com/Lucifier129/farrow"
target="_blank"
rel="noopener noreferrer"
>
Learn Farrow
</a>
{' | '}
<a
className="App-link"
href="https://vitejs.dev/guide/features.html"
target="_blank"
rel="noopener noreferrer"
>
Learn Vite
</a>
</p>
</header>
</div>
);
}
export default App;

每当服务端新增接口时,farrow 都会检测到变化,并重新生成最新的类型定义和接口调用的代码。

前端开发过程中,可以及时地看到服务端提供的类型是否与之前版本的兼容,减少前后端类型不同步导致 runtime 报错的情况。

接下来,我们尝试在服务端开发一个包含增删改查的 todo service