【超详细教程】如何使用TypeScript和GraphQL开发应用
GraphQL是一個專為構(gòu)建靈活的API而生的強大的查詢語言。它允許您為數(shù)據(jù)定義類型系統(tǒng),因此在執(zhí)行查詢時,它僅返回所需的數(shù)據(jù)。
與TypeScript一起使用時,GraphQL可以為開發(fā)人員提供更好的體驗,因為它們都是類型語言。TypeScript是JavaScript的類型化超集,可通過添加類型對其進行擴展。因此,一起使用這些技術(shù)肯定會幫助您構(gòu)建可預(yù)測的強類型API。
在本教程中,我將首先解釋為什么要結(jié)合這些技術(shù),然后通過使用TypeGraphQL從頭構(gòu)建API來展示如何將TypeScript與GraphQL結(jié)合使用。
先決條件
本教程假定您有使用TypeScript的經(jīng)驗,尤其是對TypeScript類和裝飾器。GraphQL的知識將派上用場,但不是強制性的。
在本指南中,我們將使用TypeGraphQL
,這是一個使用Node.js和TypeScript構(gòu)建GraphQL API的現(xiàn)代框架。
為什么將TypeScript與GraphQL一起使用
TypeScript是由Microsoft開發(fā)和維護的一種流行編程語言。它是JavaScript的超集,它使用靜態(tài)類型檢查使代碼可預(yù)測。
多年來,TypeScript已被證明是用于大型代碼庫的有價值的語言。TypeScript通過其類型來提高代碼質(zhì)量,從而增加代碼的健壯性,可理解性和可預(yù)測性。
GraphQL解決了API過度獲取或獲取不足的問題。GraphQL 可以通過一次請求就獲取你應(yīng)用所需的所有數(shù)據(jù)。通過這種方式,GraphQL使您的查詢變得靈活,并且您的API可讀且易于學(xué)習(xí)。
TypeScript和GraphQL都依靠類型使代碼易于理解。但是,只能使用buildSchema方法或擴展名為.gql的文件在GraphQL模式中定義GraphQL類型。GraphQL解析器不支持GraphQL類型,因為解析器只是常規(guī)的JavaScript函數(shù),而不是GraphQL代碼。TypeScript解決了這個問題,因為正如我們前面提到的那樣,它是JavaScript的超集。因此,它可以在GraphQL解析器上設(shè)置類型。這就是為什么將TypeScript與GraphQL一起使用才有意義的原因。
GraphQL處理GraphQL模式的類型,而TypeScript設(shè)置GraphQL解析器上的類型。但是,由于要處理多種語言,因此使用Node.js,GraphQL和TypeScript構(gòu)建強類型的API可能很難維護。
TypeGraphQL打算解決保持模式與解析器之間一致性的問題。TypeGraphQL允許您使用TypeScript類和裝飾器來為API創(chuàng)建架構(gòu),類型和解析器。它使用TypeScript構(gòu)建整個GraphQL API。
到目前為止,我們已經(jīng)了解了為什么將TypeScript與GraphQL搭配一起使用,以及為什么TypeGraphQL在構(gòu)建和維護使用TypeScript版GraphQL API時很方便。
事不宜遲,讓我們深入練習(xí)部分,并使用TypeGraphQL構(gòu)建GraphQL API。
安裝
在使用TypeScript和GraphQL之前,我們首先得創(chuàng)建一個Node.js的應(yīng)用,打開你的終端界面,執(zhí)行以下命令:
yarn?init或者使用npm包管理器
npm?init然后需要你為項目設(shè)定一些信息,不需要填的一路回車就好,最后會在項目目錄生成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服務(wù)中使用express的中間件
reflect-metadata使得TypeScript裝飾器可以在當(dāng)一個類已經(jīng)定義的時候為它添加一個類和成員。它是TypeGraphQL的一個依賴。
class-validator允許TypeGraphQL基于驗證的情況下使用裝飾器和非裝飾器
接下來,為項目搭建結(jié)構(gòu)
src |?├──?resolvers |?|??└──?todoResolver.ts |?└──?schemas |?|??└──?Todo.ts |?└──?index.ts ├──?tsconfig.json ├──?package.json └──?yarn.lock這里有四個文件需要說明下:
應(yīng)用的入口文件index.ts
schemas目錄包含了該項目的GraphQL Schema
resolvers目錄包含了所有API的實現(xiàn)
tsconfig.json告訴TypeScript如何去編譯代碼
與此同時,我們需要在package.json文件中添加服務(wù)的執(zhí)行命令:
"scripts":?{"start":?"nodemon?--exec?ts-node?src/index.ts" }該script命令通過使用nodemon去開啟服務(wù),即使代碼臨時修改,也會重啟生效。
為tsconfig.json文件增加配置
{"compilerOptions":?{"emitDecoratorMetadata":?true,"experimentalDecorators":?true} }以上這兩個屬性都要設(shè)置為true,以便我們可以在項目中使用TypeScript的裝飾器。
我們現(xiàn)在可以為API創(chuàng)建一個GraphQL Schema了。
創(chuàng)建GraphQL Schema
TypeGraphQL使得你可以通過TypeScript的類和裝飾器創(chuàng)建一個schema,它僅僅是語法糖而已,最終還是會生成GraphQL代碼。這個稍后再說,先創(chuàng)建一個schema
schema/Todo.ts
乍一看這語法好像有點奇怪,其實沒什么,僅僅是因為增加了TypeScript的裝飾器和類的概念在里面
這里的@ObjectType()是由TypeGraphQL提供,為了創(chuàng)建新的對象和schema而存在。Todo類反應(yīng)了Todo對象的結(jié)構(gòu),TodoInput定義了我們往Todo里面增加的期望數(shù)據(jù)
結(jié)構(gòu)。
如下是相同功能的GraphQL代碼。
type?Todo?{id:?ID!title:?String!description:?String!status:?Boolean! }input?TodoInput?{title:?String!description:?String! }可以看到邏輯完全一樣,唯一的不同是沒有使用TypeScript。
創(chuàng)建GraphQL Resolver
不像GraphQL,TypeGraphQL將query和mutation語句寫在了resolver的里面,當(dāng)被調(diào)用的時候方法名作為唯一入口。
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裝飾器創(chuàng)建一個新的返回Todo的GraphQL resolver。然后,創(chuàng)建一個GraphQL query去查詢所有的Todo類型的數(shù)據(jù)。
之后,我們再定義一個mutation query往Todo類型的數(shù)組里增加一組新的數(shù)據(jù)。
讓我們把代碼轉(zhuǎn)化成GraphQL形式
type?Mutation?{addTodo(todoInput:?TodoInput!):?Todo! }type?Query?{getTodos:?[Todo!] }到這里,我們就可以通過創(chuàng)建好的schema和resolver來搭建服務(wù)了。
搭建服務(wù)
src/index.ts
我們導(dǎo)入TodoResolver,通過在buildSchema方法里以resolver參數(shù)傳入,這樣來創(chuàng)建一個新的GraphQL Schema。
然后通過schema對象來創(chuàng)建一個ApolloServer
設(shè)置屬性emitSchemaFile: true來允許TypeGraphQL在打包階段生成一個schema.gql文件。
通過以下命令來啟動應(yīng)用
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運行器中創(chuàng)建一個新的Todo
mutation?{addTodo(todoInput:?{?title:?"Todo?1",?description:?"This?is?my?todo"?})?{titledescriptionstatus} }然后使用以下GraphQL query查詢新的Todo
{getTodos?{titledescriptionstatus} }好了,我們的功能完成了。
我們已經(jīng)實現(xiàn)了使用TypeScript構(gòu)建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/
總結(jié)
以上是生活随笔為你收集整理的【超详细教程】如何使用TypeScript和GraphQL开发应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在客户端终止一个已经发出的HTTP请
- 下一篇: 【利好工具】JavaScript及时运行