引言:API 不仅仅是请求,更是对话
曾几何时,在单体应用时代,开发者用 PHP 或 Java 编写后端,前端只是简单地调用现成的 URL。一切都很简单,但速度很慢。如今,TypeScript 生态系统制定了新规则:我们不仅希望交换数据,更希望安全、严格且带有自动补全地进行。正是在这里,三大巨头登场了:REST、GraphQL 和 gRPC。
在本文中,我们不会复述文档。我们将从 TypeScript 实践者的角度审视每种协议:查看真实的代码示例,比较性能,并了解哪种工具适合您的项目。如果您正在使用 TypeScript 并希望提升您的 API 技能,那么您来对地方了。
TypeScript 中的 REST API:经典永不过时
REST(表述性状态转移)是事实上的标准。简单、HTTP 方法(GET、POST、PUT、DELETE)和资源。但在 TypeScript 中,REST 以新的方式展现:我们获得了请求和响应的严格类型化。
类型化 REST 客户端的样子
让我们编写一个最小但可用的 TypeScript REST API 客户端。无需多余的库——仅使用 fetch 和类型。
// 响应类型interface User { id: number; name: string; email: string;}
interface ApiResponse<T> { data: T; status: number; message: string;}
// 类型化客户端class RestClient { private baseUrl: string;
constructor(baseUrl: string) { this.baseUrl = baseUrl; }
async get<T>(endpoint: string): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'GET', headers: { 'Content-Type': 'application/json' }, });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data: T = await response.json(); return { data, status: response.status, message: 'Success', }; }
async post<T, U>(endpoint: string, body: U): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data: T = await response.json(); return { data, status: response.status, message: 'Created', }; }}
// 使用示例const client = new RestClient('https://jsonplaceholder.typicode.com');
async function fetchUser() { const response = await client.get<User>('/users/1'); console.log(response.data.name); // 自动补全生效!}
fetchUser();如您所见,TypeScript REST API 让我们在每个阶段都能控制类型。字段名错误?TypeScript 会在编译阶段捕获它。
何时选择 REST
- 简单 — REST 易于理解和维护。
- 缓存 — HTTP 缓存开箱即用。
- CRUD 应用 — 博客、商店、管理后台。
缺点:对于复杂的嵌套查询,您要么获取大量数据(过度获取),要么进行 N 次请求(N+1 问题)。
TypeScript 中的 GraphQL:灵活与精确
GraphQL 是一种由 Facebook 创建的查询语言。其主要特点是:您自己决定获取哪些字段。TypeScript GraphQL 是一个强大的组合,在客户端和服务器端都提供完整的类型安全。
编写带类型化的 GraphQL 查询
作为示例,我们使用 graphql-request 库——一个轻量级的 TypeScript 客户端。
import { request, gql } from 'grap