TypeScript中的GraphQL:库与工具完全概览
GraphQL和TypeScript是创建现代API的理想组合。TypeScript添加了静态类型化,完美契合GraphQL严格的类型系统。本文将介绍在TypeScript中使用GraphQL的主要库和工具,包括安装、代码示例和最佳实践。
为什么选择TypeScript用于GraphQL?
GraphQL查询和响应具有严格的结构,而TypeScript允许在编译阶段检查此结构。这消除了与错误数据类型相关的一整类错误。主要优势:
- 类型安全 — 从GraphQL schema自动生成类型
- 自动补全 — IDE提示查询的字段和类型
- 重构 — schema的更改会自动更新所有客户端查询
- 错误最小化 — 类型错误在代码执行前即可发现
服务端主要库
1. TypeGraphQL
TypeGraphQL — 最流行的用于在TypeScript中创建GraphQL API的库。它使用装饰器来定义schema和解析器。
安装:
npm install type-graphql graphql reflect-metadata类型和解析器声明示例:
import { ObjectType, Field, Int, Resolver, Query, Arg } from "type-graphql";
@ObjectType()class User { @Field(() => Int) id: number;
@Field() name: string;
@Field({ nullable: true }) email?: string;}
@Resolver(User)class UserResolver { @Query(() => User, { nullable: true }) async user(@Arg("id", () => Int) id: number): Promise<User | null> { // 从数据库获取用户的逻辑 return { id, name: "John", email: "john@example.com" }; }}构建schema:
import { buildSchema } from "type-graphql";
const schema = await buildSchema({ resolvers: [UserResolver], emitSchemaFile: true,});2. GraphQL Yoga
GraphQL Yoga — 一个通用的GraphQL服务器,与TypeScript配合良好。基于Express,但支持任何平台。
安装:
npm install graphql-yoga graphql服务器示例:
import { createYoga, createSchema } from "graphql-yoga";import { createServer } from "node:http";
const schema = createSchema({ typeDefs: ` type Query { hello: String user(id: Int!): User } type User { id: Int! name: String } `, resolvers: { Query: { hello: () => "Hello, GraphQL!", user: (_, { id }) => ({ id, name: "Alice" }), }, },});
const yoga = createYoga({ schema });const server = createServer(yoga);server.listen(4000, () => console.log("Server running on http://localhost:4000/graphql"));客户端库
3. Apollo Client(支持TypeScript)
Apollo Client — 用于处理GraphQL的强大客户端。与TypeScript结合,它提供了查询的完整类型化。
安装:
npm install @apollo/client graphql类型化查询示例:
import { gql, useQuery } from "@apollo/client";
const GET_USER = gql` query GetUser($id: Int!) { user(id: $id) { id name email } }`;
interface UserData { user: { id: number; name: string; email?: string; };}
function UserProfile({ userId }: { userId: number }) { const { loading, data } = useQuery<UserData>(GET_USER, { variables: { id: userId }, });
if (loading) return <p>Loading...</p>; return <p>{data?.user.name}</p>;}