【超详细教程】如何使用TypeScript和GraphQL开发应用
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 Schemaresolvers
目录包含了所有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开发应用相关推荐
- 手把手从零开始搭建k8s集群超详细教程
本教程根据B站课程云原生Java架构师的第一课K8s+Docker+KubeSphere+DevOps同步所做笔记教程 k8s集群搭建超详细教程 1. 基本环境搭建 1. 创建私有网络 2. 创建服务 ...
- 安装64位Oracle 10g超详细教程
安装64位Oracle 10g超详细教程 1. 安装准备阶段 1.1 安装Oracle环境 经过上一篇博文的过程,已经完成了对Linux系统的安装,本例使用X-Manager来实现与Linux系统的连 ...
- mysql超详细教程_MySQL8.0.23安装超详细教程
前言 最近在做一个人脸识别的项目,需要用数据库保存学生信息与前段交互. MySQL的优点 1.mysql性能卓越,服务稳定,很少出现异常宕机. 2.mysql开放源代码且无版权制约,自主性及使用成本低 ...
- WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码
转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...
- 二进制安装部署 4 kubernetes集群---超详细教程
二进制安装部署kubernetes集群---超详细教程 前言:本篇博客是博主踩过无数坑,反复查阅资料,一步步搭建完成后整理的个人心得,分享给大家~~~ 本文所需的安装包,都上传在我的网盘中,需要的可以 ...
- 【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结...
[超详细教程]使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结 原文 http://www.cnblogs.com/liuxianan/ ...
- mysql 8.0.22_最新版MySQL 8.0.22下载安装超详细教程(Windows 64位)
前言 前几天下载安装了最新版的MySQL 8.0.22,遇到了不少问题,参考了一些方法,最终得以解决.今天将自己的安装过程记录下来,希望对各位有所帮助. 一.MySQL 8.0.22官网下载 点击进入 ...
- post修改服务器数据源,postgresql安装及配置超详细教程
1. 安装 根据业务需求选择版本,官网下载 初始化数据库 执行完初始化任务之后,postgresql 会自动创建和生成两个用户和一个数据库: linux 系统用户 postgres:管理数据库的系统用 ...
- 微服务Springcloud超详细教程+实战(二)
微服务Springcloud超详细教程+实战(二) -------------------------------------- 远程调用方式 无论是微服务还是分布式服务(都是SOA,都是面向服务编程 ...
- rtl8811au黑苹果10.15_荣耀MagicBook I5黑苹果折腾记(超详细教程与排坑)
本文主要介绍如何安装Win10 + Mac OS双系统,以及安装过程中可能遇到的一些坑. 本人的机型是:MagicBook I5-8250U MX150独显 8GB+256GB (VLT-W50),更 ...
最新文章
- Jenkins 2.16.3默认没有Launch agent via Java Web Start,如何配置使用
- this和prototype
- 怎样保护计算机连接线,一根网线把电脑烧了:雷雨天如何保护家电?
- Azure运维系列 4:安装和使用Azure PowerShell管理云
- findbugs 接口文档_Java代码审查工具findbugs的使用总结
- dw注册页面html,在 Dreamweaver 中生成注册页 - Dreamweaver 用户指南
- zotero自动安装word插件失败
- mshtml组件引用的问题 (转)
- ajax errorthrown属性,【技术】error:function (XMLHttpRequest, textStatus, errorThrown)
- 2023 第一届“躺平杯”信息技术与网络安全入门赛
- 2019年5月9日-面试收获
- (转)业务知识_电子商务知识
- js 取得 Unix时间戳(Unix timestamp)
- openfoam CourantNo.H
- 说不清心里对于这个孩子是什么样的感情
- oracle间歇性,oracle生产环境间歇性宕机ORA-04030
- [搞笑]MM买裤子 超强的
- 无人机飞控处理器DFU方式刷机方法(STM32单片机)
- 推荐几款工具,提升十倍工作效率
- php 开源图片管理系统,PicCMS 图片管理系统
热门文章
- java input是什么意思_java中的【...】表示什么意思
- 1062 最简分数(PAT乙级 C++)
- pat 乙级 1002 写出这个数(C++)
- 485通讯转换器产品功能特点介绍
- zigbee协议技术无线模块对智能家居市场前景分析
- Java面向对象(19)--抽象类与抽象方法abstract
- 计算机二级web题目(5)--js(Javascript)基础
- C语言课程设计报告输出杨辉三角,C语言学习:在屏幕上输出杨辉三角
- 一天一个C++程序(六)
- python 类中定义列表_Python-从类定义中的列表理解访问类变量