GraphQL API 与 TypeScript:逐步教程
GraphQL 是一种 API 查询语言,它允许客户端只请求他们需要的数据。结合 TypeScript,静态类型检查有助于在开发阶段避免错误,并使代码更可预测。在本教程中,我们将使用 Apollo Server 和 TypeScript 创建一个完整的 GraphQL API。
我们将讲解:项目设置、schema 和类型定义、resolver 的实现、用于修改数据的 mutation,以及与数据库的集成(为简单起见使用 in-memory)。文章结束时,您将能够运行自己的 GraphQL 服务器。
1. 项目准备与依赖安装
首先,创建一个新的 Node.js 项目并安装必要的包。
mkdir graphql-typescript-tutorialcd graphql-typescript-tutorialnpm init -ynpm install apollo-server graphqlnpm install -D typescript @types/node ts-node nodemon创建 tsconfig.json 文件:
{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "rootDir": "./src", "outDir": "./dist", "strict": true, "esModuleInterop": true, "skipLibCheck": true }, "include": ["src/**/*"]}项目结构如下:
src/index.ts— 入口文件src/schema.ts— GraphQL schemasrc/resolvers.ts— resolverssrc/types.ts— TypeScript 类型
2. 定义 GraphQL 类型和 schema
GraphQL schema 描述了哪些数据可用以及如何查询它们。作为示例,我们将创建一个简单的用户和帖子管理系统。
创建 src/types.ts:
export interface User { id: number; name: string; email: string;}
export interface Post { id: number; title: string; content: string; authorId: number;}
export interface CreateUserInput { name: string; email: string;}
export interface CreatePostInput { title: string; content: string; authorId: number;}现在创建 src/schema.ts,其中包含 GraphQL 类型定义:
import { gql } from 'apollo-server';
export const typeDefs = gql` type User { id: ID! name: String! email: String! posts: [Post!]! }
type Post { id: ID! title: String! content: String! author: User! }
input CreateUserInput { name: String! email: String! }
input CreatePostInput { title: String! content: String! authorId: ID! }
type Query { users: [User!]! user(id: ID!): User posts: [Post!]! post(id: ID!): Post }
type Mutation { createUser(input: CreateUserInput!): User! createPost(input: CreatePostInput!): Post! }`;请注意:我们在 mutation 中使用了 input 类型——这是 GraphQL 中的标准做法。
3. 使用 TypeScript 实现 resolvers
Resolvers 是为 schema 中的每个字段返回数据的函数。创建 src/resolvers.ts:
import { User, Post, CreateUserInput, CreatePostInput } from './types';
// In-memory 数据库let users: User[] = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' },];
let posts: Post[] = [ { id: 1, title: 'GraphQL Basics', content: '...', authorId: 1 }, { id: 2, title: 'TypeScript Guide', content: '...', authorId: 2 },];
let nextUserId = 3;let nextPostId = 3;
export const resolvers = { Query: { users: (): User[] => users, user: (_: unknown, args: { id: string }): User | undefined => users.find(u => u.id === Number(args.id)), posts: (): Post[] => posts, post: (_: unknown,
```