【超详细教程】如何使用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 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
乍一看這語法好像有點奇怪,其實沒什么,僅僅是因為增加了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
我們導入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开发应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在客户端终止一个已经发出的HTTP请
- 下一篇: 教你如何创建一款属于自己的VSCode主