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。

到目前为止,我们已经了解了为什么将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

在项目根目录下生成了一个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" }) {titledescriptionstatus}
}

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

{getTodos {titledescriptionstatus}
}

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

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

完整代码

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

References

[1] TypeGraphQL Docs: https://typegraphql.com/docs/introduction.html
[2] TypeScript Decorators Docs: https://www.typescriptlang.org/docs/handbook/decorators.html
[3] TypeScript Classes Docs: https://www.typescriptlang.org/docs/handbook/classes.html
[4] TypeGraphQL Examples: https://typegraphql.com/docs/examples.html
[5] GraphQL Docs: https://graphql.org/learn/

【超详细教程】如何使用TypeScript和GraphQL开发应用相关推荐

  1. 手把手从零开始搭建k8s集群超详细教程

    本教程根据B站课程云原生Java架构师的第一课K8s+Docker+KubeSphere+DevOps同步所做笔记教程 k8s集群搭建超详细教程 1. 基本环境搭建 1. 创建私有网络 2. 创建服务 ...

  2. 安装64位Oracle 10g超详细教程

    安装64位Oracle 10g超详细教程 1. 安装准备阶段 1.1 安装Oracle环境 经过上一篇博文的过程,已经完成了对Linux系统的安装,本例使用X-Manager来实现与Linux系统的连 ...

  3. mysql超详细教程_MySQL8.0.23安装超详细教程

    前言 最近在做一个人脸识别的项目,需要用数据库保存学生信息与前段交互. MySQL的优点 1.mysql性能卓越,服务稳定,很少出现异常宕机. 2.mysql开放源代码且无版权制约,自主性及使用成本低 ...

  4. WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码

    转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...

  5. 二进制安装部署 4 kubernetes集群---超详细教程

    二进制安装部署kubernetes集群---超详细教程 前言:本篇博客是博主踩过无数坑,反复查阅资料,一步步搭建完成后整理的个人心得,分享给大家~~~ 本文所需的安装包,都上传在我的网盘中,需要的可以 ...

  6. 【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结...

    [超详细教程]使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结 原文 http://www.cnblogs.com/liuxianan/ ...

  7. mysql 8.0.22_最新版MySQL 8.0.22下载安装超详细教程(Windows 64位)

    前言 前几天下载安装了最新版的MySQL 8.0.22,遇到了不少问题,参考了一些方法,最终得以解决.今天将自己的安装过程记录下来,希望对各位有所帮助. 一.MySQL 8.0.22官网下载 点击进入 ...

  8. post修改服务器数据源,postgresql安装及配置超详细教程

    1. 安装 根据业务需求选择版本,官网下载 初始化数据库 执行完初始化任务之后,postgresql 会自动创建和生成两个用户和一个数据库: linux 系统用户 postgres:管理数据库的系统用 ...

  9. 微服务Springcloud超详细教程+实战(二)

    微服务Springcloud超详细教程+实战(二) -------------------------------------- 远程调用方式 无论是微服务还是分布式服务(都是SOA,都是面向服务编程 ...

  10. rtl8811au黑苹果10.15_荣耀MagicBook I5黑苹果折腾记(超详细教程与排坑)

    本文主要介绍如何安装Win10 + Mac OS双系统,以及安装过程中可能遇到的一些坑. 本人的机型是:MagicBook I5-8250U MX150独显 8GB+256GB (VLT-W50),更 ...

最新文章

  1. Jenkins 2.16.3默认没有Launch agent via Java Web Start,如何配置使用
  2. this和prototype
  3. 怎样保护计算机连接线,一根网线把电脑烧了:雷雨天如何保护家电?
  4. Azure运维系列 4:安装和使用Azure PowerShell管理云
  5. findbugs 接口文档_Java代码审查工具findbugs的使用总结
  6. dw注册页面html,在 Dreamweaver 中生成注册页 - Dreamweaver 用户指南
  7. zotero自动安装word插件失败
  8. mshtml组件引用的问题 (转)
  9. ajax errorthrown属性,【技术】error:function (XMLHttpRequest, textStatus, errorThrown)
  10. 2023 第一届“躺平杯”信息技术与网络安全入门赛
  11. 2019年5月9日-面试收获
  12. (转)业务知识_电子商务知识
  13. js 取得 Unix时间戳(Unix timestamp)
  14. openfoam CourantNo.H
  15. 说不清心里对于这个孩子是什么样的感情
  16. oracle间歇性,oracle生产环境间歇性宕机ORA-04030
  17. [搞笑]MM买裤子 超强的
  18. 无人机飞控处理器DFU方式刷机方法(STM32单片机)
  19. 推荐几款工具,提升十倍工作效率
  20. php 开源图片管理系统,PicCMS 图片管理系统

热门文章

  1. java input是什么意思_java中的【...】表示什么意思
  2. 1062 最简分数(PAT乙级 C++)
  3. pat 乙级 1002 写出这个数(C++)
  4. 485通讯转换器产品功能特点介绍
  5. zigbee协议技术无线模块对智能家居市场前景分析
  6. Java面向对象(19)--抽象类与抽象方法abstract
  7. 计算机二级web题目(5)--js(Javascript)基础
  8. C语言课程设计报告输出杨辉三角,C语言学习:在屏幕上输出杨辉三角
  9. 一天一个C++程序(六)
  10. python 类中定义列表_Python-从类定义中的列表理解访问类变量