【超详细】如何使用TypeScript和GraphQL开发应用

简介: GraphQL是一个专为构建灵活的API而生的强大的查询语言。它允许您为数据定义类型系统,因此在执行查询时,它仅返回所需的数据。

GraphQL是一个专为构建灵活的API而生的强大的查询语言。它允许您为数据定义类型系统,因此在执行查询时,它仅返回所需的数据。


与TypeScript一起使用时,GraphQL可以为开发人员提供更好的体验,因为它们都是类型语言。 TypeScript是JavaScript的类型化超集,可通过添加类型对其进行扩展。 因此,一起使用这些技术肯定会帮助您构建可预测的强类型API。


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


先决条件


本教程假定您有使用TypeScript的经验,尤其是对TypeScript类和装饰器。 GraphQL的知识将派上用场,但不是强制性的。

在本指南中,我们将使用TypeGraphQL

,这是一个使用Node.js和TypeScript构建GraphQL API的现代框架。

为什么将TypeScript与GraphQL一起使用


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


多年来,TypeScript已被证明是用于大型代码库的有价值的语言。 TypeScript通过其类型来提高代码质量,从而增加代码的健壮性,可理解性和可预测性。

GraphQL解决了API过度获取或获取不足的问题。 GraphQL 可以通过一次请求就获取你应用所需的所有数据。 通过这种方式,GraphQL使您的查询变得灵活,并且您的API可读且易于学习。


TypeScript和GraphQL都依靠类型使代码易于理解。但是,只能使用buildSchema方法或扩展名为.gql的文件在GraphQL模式中定义GraphQL类型。 GraphQL解析器不支持GraphQL类型,因为解析器只是常规的JavaScript函数,而不是GraphQL代码。


TypeScript解决了这个问题,因为正如我们前面提到的那样,它是JavaScript的超集。因此,它可以在GraphQL解析器上设置类型。这就是为什么将TypeScript与GraphQL一起使用才有意义的原因。


GraphQL处理GraphQL模式的类型,而TypeScript设置GraphQL解析器上的类型。但是,由于要处理多种语言,因此使用Node.js,GraphQL和TypeScript构建强类型的API可能很难维护。


TypeGraphQL打算解决保持模式与解析器之间一致性的问题。 TypeGraphQL允许您使用TypeScript类和装饰器来为API创建架构,类型和解析器。它使用TypeScript构建整个GraphQL API。

[%ET8H8_{K52GCDS1S1Y1I6.png

到目前为止,我们已经了解了为什么将TypeScript与GraphQL搭配一起使用,以及为什么TypeGraphQL在构建和维护使用TypeScript版GraphQL API时很方便。

事不宜迟,让我们深入练习部分,并使用TypeGraphQL构建GraphQL API。


安装


在使用TypeScript和GraphQL之前,我们首先得创建一个Node.js的应用,打开你的终端界面,执行以下命令:

yarn init

或者使用npm包管理器

npm init

然后需要你为项目设定一些信息,不需要填的一路回车就好,最后会在项目目录生成package.json文件。

fantingshengdeMacBook-Pro:graphql-typescript fantingsheng$ yarn init
yarn init v1.12.3
question name (graphql-typescript):
question version (1.0.0):
question description: for study
question entry point (index.js):
question repository url: https://github.com/fantingsheng/graphql-typescript
question author: Timfan
question license (MIT):
question private:
success Saved package.json
✨  Done in 223.35s.


接下来安装一些需要的依赖

yarn add express apollo-server-express graphql reflect-metadata type-graphql class-validator


或者

npm install express apollo-server-express graphql reflect-metadata type-graphql class-validator


我们先下载好这些安装包,然后再解释它们分别是干什么的。另外还要安装它们的类型定义,以便支持TypeScript的使用。

yarn add -D ts-node typescript @types/express @types/node nodemon


或者

npm install -D ts-node typescript @types/express @types/node nodemon

注意:我们安装nodemon是为了在代码更新的时候热重载

下面是每个依赖库的作用解释:

  • express是一个极简的Node版web框架
  • apollo-server-express是一个允许我们在Apollo GraphQL服务中使用express的中间件
  • reflect-metadata使得TypeScript装饰器可以在当一个类已经定义的时候为它添加一个类和成员。它是TypeGraphQL的一个依赖。
  • class-validator允许TypeGraphQL基于验证的情况下使用装饰器和非装饰器

接下来,为项目搭建结构

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


这里有四个文件需要说明下:

  • 应用的入口文件index.ts
  • schemas目录包含了该项目的GraphQL Schema
  • resolvers目录包含了所有API的实现
  • tsconfig.json告诉TypeScript如何去编译代码

与此同时,我们需要在package.json文件中添加服务的执行命令:

"scripts": {
  "start": "nodemon --exec ts-node src/index.ts"
}

该script命令通过使用nodemon去开启服务,即使代码临时修改,也会重启生效。

为tsconfig.json文件增加配置

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}

以上这两个属性都要设置为true,以便我们可以在项目中使用TypeScript的装饰器。

我们现在可以为API创建一个GraphQL Schema了。


创建GraphQL Schema


TypeGraphQL使得你可以通过TypeScript的类和装饰器创建一个schema,它仅仅是语法糖而已,最终还是会生成GraphQL代码。这个稍后再说,先创建一个schema

  • schema/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<Todo> {
  @Field() title: string
  @Field() description: string
}


乍一看这语法好像有点奇怪,其实没什么,仅仅是因为增加了TypeScript的装饰器和类的概念在里面


这里的@ObjectType()是由TypeGraphQL提供,为了创建新的对象和schema而存在。Todo类反应了Todo对象的结构,TodoInput定义了我们往Todo里面增加的期望数据

结构。

如下是相同功能的GraphQL代码。

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

可以看到逻辑完全一样,唯一的不同是没有使用TypeScript。


创建GraphQL Resolver


不像GraphQL,TypeGraphQL将query和mutation语句写在了resolver的里面,当被调用的时候方法名作为唯一入口。

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(),
      title,
      description,
      status: false
    }
    await this.todos.push(todo)
    return todo;
  }
}


这里我们使用resolver装饰器创建一个新的返回Todo的GraphQL resolver。然后,创建一个GraphQL query去查询所有的Todo类型的数据。

之后,我们再定义一个mutation query往Todo类型的数组里增加一组新的数据。

让我们把代码转化成GraphQL形式

type Mutation {
  addTodo(todoInput: TodoInput!): Todo!
}
type Query {
  getTodos: [Todo!]
}

到这里,我们就可以通过创建好的schema和resolver来搭建服务了。


搭建服务


  • 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();


我们导入TodoResolver,通过在buildSchema方法里以resolver参数传入,这样来创建一个新的GraphQL Schema。


然后通过schema对象来创建一个ApolloServer

设置属性emitSchemaFile: true来允许TypeGraphQL在打包阶段生成一个schema.gql文件。


通过以下命令来启动应用

yarn start


或者

npm start


在浏览器中访问http://localhost:4000/graphql

4L)Y@5$N6IC4P175SVJ]P]I.png

在项目根目录下生成了一个schema.gql文件

# -----------------------------------------------
# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!
# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!
# -----------------------------------------------
type Mutation {
  addTodo(todoInput: TodoInput!): Todo!
}
type Query {
  getTodos: [Todo!]
}
type Todo {
  description: String!
  id: Float!
  status: Boolean!
  title: String!
}
input TodoInput {
  description: String!
  title: String!
}

然后添加以下代码到GraphQL运行器中创建一个新的Todo

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

_}4ZM6NX{~N9C8BNTZJ]SMO.png

然后使用以下GraphQL query查询新的Todo

{
  getTodos {
    title
    description
    status
  }
}

)LM9SXRCLN5~1]TL$K``0JH.png

好了,我们的功能完成了。

我们已经实现了使用TypeScript构建GraphQL API。


完整代码


https://github.com/fantingsheng/graphql-typescript

参考:




目录
相关文章
|
1月前
|
存储 人工智能 开发框架
Eliza:TypeScript 版开源 AI Agent 开发框架,快速搭建智能、个性的 Agents 系统
Eliza 是一个开源的多代理模拟框架,支持多平台连接、多模型集成,能够快速构建智能、高效的AI系统。
205 8
Eliza:TypeScript 版开源 AI Agent 开发框架,快速搭建智能、个性的 Agents 系统
|
4月前
|
JavaScript 前端开发 安全
TypeScript的优势与实践:提升JavaScript开发效率
【10月更文挑战第8天】TypeScript的优势与实践:提升JavaScript开发效率
|
4月前
|
JavaScript 前端开发 IDE
深入理解TypeScript:提升JavaScript开发的利器
【10月更文挑战第8天】 深入理解TypeScript:提升JavaScript开发的利器
48 0
|
2月前
|
数据采集 JavaScript 前端开发
异步请求在TypeScript网络爬虫中的应用
异步请求在TypeScript网络爬虫中的应用
|
3月前
|
传感器 JavaScript 前端开发
利用TypeScript提升代码质量和开发效率
TypeScript作为JavaScript的超集,通过引入静态类型系统和面向对象特性,显著提升了代码质量和开发效率。本文介绍了TypeScript的基本概念、优势及最佳实践,包括基础类型注解、接口与类的使用、类型推断、高级类型、装饰器应用及现代工具的集成,帮助开发者构建更健壮的应用程序。
|
3月前
|
JavaScript 前端开发 安全
JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择
本文深入探讨了JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择。JavaScript以其灵活性和广泛的生态支持著称,而TypeScript通过引入静态类型系统,提高了代码的可靠性和可维护性,特别适合大型项目。文章还讨论了结合使用两种语言的优势,以及如何根据项目需求和技术背景做出最佳选择。
103 4
|
3月前
|
机器学习/深度学习 人工智能 JavaScript
JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景
本文探讨了JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景。JavaScript将注重性能优化、跨平台开发、AI融合及WebAssembly整合;TypeScript则强调与框架整合、强类型检查、前端工程化及WebAssembly的深度结合。两者结合发展,特别是在Vue 3.0中完全采用TypeScript编写,预示着未来的Web开发将更加高效、可靠。
102 4
|
3月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
66 2
|
3月前
|
JavaScript 前端开发 安全
掌握TypeScript:提升JavaScript开发质量
本文介绍了TypeScript如何通过其静态类型系统、面向对象特性及对现代JavaScript特性的支持,提升JavaScript开发的质量,包括减少错误、增强代码可维护性和利用类型推断等功能,适用于大型项目开发。
|
4月前
|
JavaScript 前端开发 IDE
利用TypeScript增强JavaScript开发
【10月更文挑战第5天】TypeScript作为JavaScript的超集,通过添加静态类型系统和对ES6+特性的支持,解决了大型项目中常见的类型错误和代码维护难题。本文介绍TypeScript的核心优势,包括静态类型检查、现代JS特性支持及更好的IDE支持,并探讨如何逐步将其集成到现有项目中,提升开发效率和代码质量。通过使用DefinitelyTyped库和装饰器等功能,开发者可以更轻松地编写可靠且可维护的代码。希望本文能帮助你更好地理解和应用TypeScript。