发布于 2026-01-06 8 阅读
0

如何在 GraphQL 中使用 TypeScript

如何在 GraphQL 中使用 TypeScript

GraphQL 是一种强大的查询语言,可用于构建灵活的 API。它允许您为数据定义类型系统,因此在执行查询时,它只会返回您需要的数据。

GraphQL 与 TypeScript 结合使用可以提供更佳的开发者体验,因为它们都是类型语言。TypeScript 是 JavaScript 的类型化超集,它通过添加类型扩展了 JavaScript。因此,结合使用这两种技术无疑有助于构建可预测且强类型的 API。

在本教程中,我将首先解释为什么要结合这些技术,然后向您展示如何使用 TypeGraphQL 从头开始​​构建 API,从而将 TypeScript 与 GraphQL 结合使用。

先决条件

本教程假设您已具备一定的 TypeScript 使用经验,特别是 TypeScript 类和装饰器方面的经验。了解 GraphQL 会有所帮助,但并非必需。

在本指南中,我们将使用TypeGraphQL,这是一个使用 Node.js 和 TypeScript 构建 GraphQL API 的现代框架。

为什么要将 TypeScript 与 GraphQL 结合使用

TypeScript 是一种由微软开发和维护的流行编程语言。它是 JavaScript 的超集,使用静态类型检查来保证代码的可预测性。

多年来,TypeScript 已被证明是大型代码库的理想语言。TypeScript 通过其类型系统提升代码质量,从而带来诸多优势,例如代码的健壮性、可理解性和可预测性。

GraphQL 解决了 API 数据获取过多或过少的问题。它为所有请求提供了一个统一的端点,通过一个Post方法精确获取所需数据,不多不少。这样,GraphQL 使查询更加灵活,API 也更易读易学。

TypeScript 和 GraphQL 都依赖类型来使代码更易于理解。然而,GraphQL 类型只能在 GraphQL schema 中使用 `type` 方法buildSchema或带有 `.py` 扩展名的文件来定义.gql。GraphQL 类型在 GraphQL 解析器中不受支持,因为解析器只是普通的 JavaScript 函数,而不是 GraphQL 代码。TypeScript 解决了这个问题,因为正如我们前面提到的,它是 JavaScript 的超集。因此,它可以为 GraphQL 解析器设置类型。这就是为什么将 TypeScript 与 GraphQL 结合使用是合理的。

GraphQL 负责处理 GraphQL schema 的类型,而 TypeScript 则负责设置 GraphQL 解析器的类型。然而,由于需要处理多种语言,使用 Node.js、GraphQL 和 TypeScript 构建强类型 API 的维护可能会面临挑战。

TypeGraphQL 旨在解决模式和解析器之间的一致性问题。它允许你使用 TypeScript 类和装饰器来创建 API 的模式、类型和解析器。它使用 TypeScript 构建整个 GraphQL API。

https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1600278411563_illustration.png

插图

到目前为止,我们已经了解了为什么将 TypeScript 与 GraphQL 结合使用会很有用,以及为什么 TypeGraphQL 对于构建和维护使用 TypeScript 的 GraphQL API 非常方便。

事不宜迟,让我们直接进入实践部分,使用 TypeGraphQL 构建 GraphQL API。

设置

要使用 TypeScript 和 GraphQL,我们首先需要创建一个新的 Node.js 应用程序。

打开命令行界面 (CLI) 并运行以下命令:

yarn init
Enter fullscreen mode Exit fullscreen mode

或者为了npm

npm init
Enter fullscreen mode Exit fullscreen mode

您需要回答几个配置问题,系统会生成一个package.json文件。接下来,安装本教程所需的依赖项。

yarn add express apollo-server-express graphql reflect-metadata type-graphql class-validator
Enter fullscreen mode Exit fullscreen mode

为了npm

npm install express apollo-server-express graphql reflect-metadata type-graphql class-validator
Enter fullscreen mode Exit fullscreen mode

稍后我们会详细介绍这些包及其功能。现在,让我们先安装它们的类型,以便 TypeScript 能够识别这些库。

yarn add -D @types/express @types/node nodemon
Enter fullscreen mode Exit fullscreen mode

或者

npm install -D @types/express @types/node nodemon
Enter fullscreen mode Exit fullscreen mode

请注意,我们nodemon还安装了实时重新加载功能,以便在发生更改时自动更新。

以下是每个已安装库的功能:

  • express是一个极简的 Node.js Web 框架
  • apollo-server-express是一个允许express在 Apollo GraphQL 服务器中使用的中间件。
  • reflect-metadata它允许 TypeScript 装饰器在定义类时增强类及其成员的功能。它是 TypeGraphQL 的一个依赖项。
  • class-validator允许 TypeGraphQL 使用基于装饰器和非装饰器的验证。

接下来,我们需要按如下方式构建项目:

src
| ├── resolvers
| |  └── todoResolver.ts
| └── schemas
| |  └── Todo.ts
| └── index.ts
├── tsconfig.json
├── package.json
└── yarn.lock
Enter fullscreen mode Exit fullscreen mode

这里,有四个文件需要重点标注:

  • 服务器的入口点(index.ts)。
  • schemas包含项目 GraphQL Schema 的文件夹
  • resolvers存放 API 解析器的文件夹
  • tsconfig.json文件告诉 TypeScript 如何编译代码。

完成这些步骤后,我们现在可以在package.json文件中添加启动服务器的脚本。

"scripts": {
  "start": "nodemon --exec ts-node src/index.ts"
}
Enter fullscreen mode Exit fullscreen mode

此脚本将启动服务器nodemon。每当我们的代码更新时,它都会重新启动。

现在让我们来配置一下tsconfig.json

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}
Enter fullscreen mode Exit fullscreen mode

这两个属性应该设置为 true,true才能在项目中使用 TypeScript 装饰器。

现在我们可以为 API 构建 GraphQL Schema 了。

构建 GraphQL Schema

TypeGraphQL 允许你使用 TypeScript 类和装饰器构建模式。它只是语法糖,因为 TypeGraphQL 底层仍然会生成常规的 GraphQL 代码。我们稍后会看到生成的代码——现在,让我们先创建模式。

  • schemas/Todo.ts
import { Field, ObjectType, InputType } from type-graphql

@ObjectType() export class Todo {
  @Field() id: number
  @Field() title: string
  @Field() description: string
  @Field() status: boolean
}

@InputType() export class TodoInput implements Partial {
  @Field() title: string
  @Field() description: string
}
Enter fullscreen mode Exit fullscreen mode

乍一看语法可能有点奇怪,但其实很容易理解。它只是TypeScript的装饰器和类而已。

这里,@ObjectType()TypeGraphQL 提供的功能允许创建新的对象或模式。该类Todo反映了 Todo 对象的结构,并TodoInput定义了添加新 Todo 所需的数据。

现在,让我们用 GraphQL 编写相同的代码。

type Todo {
  id: ID!
  title: String!
  description: String!
  status: Boolean!
}

input TodoInput {
  title: String!
  description: String!
}
Enter fullscreen mode Exit fullscreen mode

如你所见,逻辑是一样的。唯一的区别在于,这里我们没有使用 TypeScript。

现在我们准备创建 GraphQL 解析器了。

创建 GraphQL 解析器

与 GraphQL 不同,TypeGraphQL 将 GraphQL 查询或变更操作放在解析器中。函数名称将用作查询或修改数据的端点。

  • resolvers/todoResolver.ts
import { Query, Resolver, Mutation, Arg } from type-graphql;
import { Todo, TodoInput } from ../schemas/Todo;

@Resolver((of) => Todo) export class TodoResolver { 
    private todos: Todo[] = []

    @Query((returns) => [Todo], { nullable: true })
    async getTodos(): Promise<Todo[]> {
        return await this.todos
    }

    @Mutation((returns) => Todo)
    async addTodo(
        @Arg('todoInput') { title, description }: TodoInput
    ): Promise<Todo> {
        const todo = {
            id: Math.random(), // not really unique
            title,
            description,
            status: false,
        }

        await this.todos.push(todo)
        return todo
    }
}
Enter fullscreen mode Exit fullscreen mode

这里,我们使用Resolver装饰器创建一个新的 GraphQL 解析器,该解析器返回一个 Todo 对象。接下来,我们构建一个 GraphQL 查询来获取所有 Todo 对象。

之后,我们定义一个变更查询,该查询需要一个参数title和一个值,description以便在数据数组中添加一个新的待办事项。

顺便说一下,这里不需要使用 async/await,因为这段代码不会花费太多时间完成。但我还是把它写在这里,以备你在实际处理服务器时参考。

现在让我们把代码转换成 GraphQL。

type Mutation {
  addTodo(todoInput: TodoInput!): Todo!
}

type Query {
  getTodos: [Todo!]
}
Enter fullscreen mode Exit fullscreen mode

有了这些,我们就可以构建使用我们刚刚创建的模式和解析器的服务器了。

创建服务器

  • src/index.ts
import reflect-metadata;
import { ApolloServer } from apollo-server-express;
import * as Express from express import { buildSchema } from type-graphql;
import { TodoResolver } from ./resolvers/todoResolver;

async function main() { const schema = await buildSchema({ resolvers: [TodoResolver], emitSchemaFile: true, })

    const app = Express()

    const server = new ApolloServer({
        schema,
    })

    server.applyMiddleware({ app })

    app.listen(4000, () =>
        console.log('Server is running on http://localhost:4000/graphql')
    )

}

main()
Enter fullscreen mode Exit fullscreen mode

如您所见,我们导入了 `Todo` 库TodoResolver,它需要作为解析器传递给该buildSchema方法。这样,TypeGraphQL 就可以基于 `Todo` 解析器构建一个新的 GraphQL Schema。

接下来,我们将该schema对象(其中包含 GraphQL schema 和解析器)传递给 Apollo 以创建服务器。

设置该属性emitSchemaFile: true允许 TypeGraphQLschema.gql在构建时生成文件。

我们来检查一下应用是否正常运行。运行以下命令:

yarn start
Enter fullscreen mode Exit fullscreen mode

或者

npm start
Enter fullscreen mode Exit fullscreen mode

访问http://localhost:4000/graphql,然后将下面的代码块添加到 GraphQL Playground 中以创建一个新的待办事项。

mutation {
  addTodo(todoInput: { title: "Todo 1", description: "This is my todo" }) {
    title
    description
    status
  }
}
Enter fullscreen mode Exit fullscreen mode

Todo 对象应该已成功创建!

https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1599926790317_add-todo.PNG

待办事项已创建

现在使用以下 GraphQL 查询来查询新创建的待办事项。

{
  getTodos {
    title
    description
    status
  }
}
Enter fullscreen mode Exit fullscreen mode

你应该看到所有待办事项都已返回。

https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1599926830468_all-todos.PNG

所有待办事项

太棒了!我们的应用看起来不错。

我们现在已经完成了使用 TypeScript 构建 GraphQL API 的工作。

你可以在这个GitHub 仓库中找到最终项目。

感谢阅读

TakeShape 中的 GraphQL

TakeShape 提供灵活的 GraphQL API,让您轻松管理内容。通过 API Explorer,您可以立即查看内容模型更改对 API 的影响。您无需自行构建任何后端,一切都已为您设置完毕。TakeShape 会自动生成安全的 GraphQL API,用于公开您的所有内容和服务。

下一步

请查看以下资源,深入了解本教程的内容:

文章来源:https://dev.to/takeshape/how-to-use-typescript-with-graphql-3k98