教你用Node.js與Express建立一個GraphQL服務器
前言
在這篇文章中,我們將對使用Node.js和Express建立GraphQL服務器的整個過程進行演練。我們將使用 Express 的中間件庫express-graphql 來協(xié)助我們完成這一過程。
如果你還不熟悉GraphQL以及我們使用它的目的,請務必查看這篇文章,我們將深入了解GraphQL是什么以及為什么我們應該在我們的應用程序中使用它。
如果你已經(jīng)熟悉它了,你可能想看看這篇文章,在這篇文章中我們用React實現(xiàn)了Apollo客戶端來連接到我們現(xiàn)在要創(chuàng)建的服務器。
包含這篇文章中的代碼的資源庫可以在這里找到。
還有一個包含使用該服務器的前端的資源庫,可以在這里找到。
所以,不用多說了,讓我們開始吧。
GraphQL服務器配置設(shè)置
首先,我們可能想先創(chuàng)建一個新的目錄,通過以下命令設(shè)置npm npm init命令,然后創(chuàng)建我們的 server.js文件,該文件將承載我們的GraphQL服務器。
一旦我們完成了這些,我們就需要安裝以下庫:
- express
- express-graphql
- graphql
- cors
server.js文件看起來應該是這樣的:
const app = require("express")(); const cors = require('cors'); const { graphqlHTTP } = require("express-graphql"); const { buildSchema } = require("graphql"); const schema = buildSchema(''); const root = { }; app.use(cors()); app.use( "/graphql", graphqlHTTP({ schema, rootValue: root, graphiql: true, }) ); app.listen(8080, () => { console.log('GraphQL server running on port 8080'); });
讓我們來看看配置過程的每一步,這樣我們就能更好地了解實際發(fā)生的情況:
- 首先導入express并調(diào)用其導出的主函數(shù),這樣我們就可以通過app變量來設(shè)置我們的應用服務器了
- 導入cors庫的主函數(shù),以幫助我們解決在不同域(localhost與不同端口)上運行服務器的問題
- 從Express-graphql庫中導入graphqlHTTP方法,幫助我們進行配置
- 從graphql庫中導入buildSchema方法來定義數(shù)據(jù)模式(我們允許客戶訪問哪些數(shù)據(jù))。
- 現(xiàn)在定義一個空的數(shù)據(jù)模式
- 現(xiàn)在定義一個空的根,但這將被用來定義我們的 調(diào)解器或者說我們選擇如何處理數(shù)據(jù),以便將其發(fā)送到客戶端。
- 設(shè)置 CORS,不需要額外的配置
- 定義我們將用于**"/graphql "**端點的配置,它將利用我們之前定義的模式、根解析器對象,以及我們將用于測試和與我們的數(shù)據(jù)進行可視化交互的游樂場。
為了啟動服務器,你所需要做的就是執(zhí)行 node server.js命令。然后你可以在你的瀏覽器中檢查 "localhost:8080",在那里你就可以看到GraphiQL游樂場的運行,這是一種與你的數(shù)據(jù)/架構(gòu)進行交互的可視化方式。
它看起來應該是這樣的。
在瀏覽器中運行的GraphiQL
定義模式
現(xiàn)在我們已經(jīng)把GraphQL設(shè)置好了,讓我們看看用一些數(shù)據(jù)來填充我們的GraphQL模式。
為了簡單起見,我們將使用一些更基本的模型,并在這些模型之間定義一個基本關(guān)系。我們將有一個作者模型和一個圖書模型,它們將有以下模式:
書籍模式:
作者模式
正如你從所附圖片中看到的,我們將有2個基本模型,分別有3個和4個字段,在這里我們也定義了一對多的關(guān)系。這意味著一個作者可以寫很多書,而一本書只能有一個作者。
這就是我們?nèi)绾卧诖a中定義這些模型模式:
const schema = buildSchema( ` type Query { authors: [Author] books: [Book] } type Author { id: String firstName: String! lastName: String! books: [Book] } type Book { id: String title: String! author: Author } ` );
我們還必須定義我們的父查詢類型,它承載了所有檢索數(shù)據(jù)的查詢。在定義了父查詢之后,我們將不得不為作者和書的模型定義模式。
你可以注意到一些字段類型后面的"!"符號,這表示一個字段是不可置空的。方括號("[]")圍繞著一個類型,意味著它是一個數(shù)組。
嘲弄我們的數(shù)據(jù)
我們現(xiàn)在已經(jīng)定義了模式,但還缺少兩樣東西:數(shù)據(jù)和解析器來解析查詢的數(shù)據(jù)。
首先,讓我們根據(jù)之前定義的模式來模擬我們的數(shù)據(jù):
const mockedAuthors = [ { id: '1', firstName: "Mike", lastName: "Ross", }, { id: '2', firstName: "John", lastName: "Miles", books: [ { id: '1', title: "Book 1", author: { id: '2', firstName: "John", lastName: "Miles", }, }, { id: '2', title: "Book 2", author: { id: '2', firstName: "John", lastName: "Miles", }, }, ], }, ]; const mockedBooks = { '1': { title: "Book 1", author: mockedAuthors["2"], }, '2': { title: "Book 2", author: mockedAuthors["2"], }, };
正如你可能注意到的,"Mike Ross "還沒有寫任何書,這不是一個問題,因為作者模式不需要在其數(shù)組內(nèi)有任何書。此外,根本不需要定義一個書的數(shù)組,因為模式不需要它。然而,我們可以通過改變作者的書籍字段的類型來改變這種情況。[書籍]!這就要求至少有一個數(shù)組,不管是不是空的。
定義解析器
現(xiàn)在我們已經(jīng)定義了模式和數(shù)據(jù),我們可以通過定義解析器來完成,我們將使用這些解析器來實際處理如何將數(shù)據(jù)傳遞給客戶端。
現(xiàn)在,我們只需要兩個解析器:
- 一個用于解析作者的數(shù)據(jù)
- 一個用于解析圖書數(shù)據(jù)
我們將在根中這樣定義解析器:
const root = { authors: () => mockedAuthors, books: () => mockedBooks, };
正如你在上面的代碼片段中所看到的,定義解析器的過程是非常直接的。會有一個作為查詢名稱的屬性,這意味著通過具體查詢 "author",都是小寫字母,你會得到 "mockedAuthors "數(shù)據(jù)。
注意,我們還將函數(shù)作為值傳遞給屬性,這一點很關(guān)鍵。
現(xiàn)在讓我們測試一下所有的東西,這樣我們就可以確保它按預期工作:
正如你所看到的,這一切都像預期的那樣工作正常。我們使用GraphQL的特定術(shù)語,提到我們正在做一個查詢,使用 "query "關(guān)鍵字,后面是我們希望查詢的屬性/類型/條目。在這種情況下,我們希望查詢作者類型的所有屬性,但只查詢書籍類型的id和標題;我們跳過了作者字段。
因為我們已經(jīng)模擬了數(shù)據(jù),以包括書籍中的作者,我們可能會做像這樣的循環(huán)查詢。
所以,你有了它。你可以看到設(shè)置GraphQL服務器并為其定義模式和解析器是多么容易。通過定義類型,你不僅有驗證的地方,而且你還可能從你所選擇的游樂場訪問文檔。
GraphiQL提供了一個右上方的小Docs菜單,它可以跳出來,向你展示在模式中定義的所有類型的文檔。
GraphiQL中的GraphQL自我文檔化模式
現(xiàn)在我們已經(jīng)建立了使用查詢檢索數(shù)據(jù)的工作流程,我們還將看看如何使用突變來修改已有的數(shù)據(jù)。
定義突變
當我們使用查詢來檢索數(shù)據(jù)時,我們使用突變來創(chuàng)建、修改或刪除現(xiàn)有數(shù)據(jù)。
假設(shè)我們要創(chuàng)建一個新的作者條目,我們要做的就是定義一個新的父 "突變"類型,該類型將擁有我們在整個系統(tǒng)中可能使用的突變字段。在那之后,我們必須為它定義解析器,然后就可以了。這將是我們需要做的所有事情。
下面的代碼片段應該說明最終的server.js文件具有創(chuàng)建一個新的作者條目的能力:
const app = require("express")(); const cors = require('cors'); const { graphqlHTTP } = require("express-graphql"); const { buildSchema } = require("graphql"); const schema = buildSchema( ` type Query { authors: [Author] books: [Book] } type Mutation { createAuthor( firstName: String!, lastName: String! ): Author } type Author { id: String firstName: String! lastName: String! books: [Book] } type Book { id: String title: String! author: Author } ` ); const mockedAuthors = [ { id: '1', firstName: "Mike", lastName: "Ross", }, { id: '2', firstName: "John", lastName: "Miles", books: [ { id: '1', title: "Book 1", author: { id: '2', firstName: "John", lastName: "Miles", }, }, { id: '2', title: "Book 2", author: { id: '2', firstName: "John", lastName: "Miles", }, }, ], }, ]; const mockedBooks = { '1': { title: "Book 1", author: mockedAuthors["2"], }, '2': { title: "Book 2", author: mockedAuthors["2"], }, }; const root = { authors: () => mockedAuthors, books: () => mockedBooks, createAuthor: ({ firstName, lastName }) => { const id = String(mockedAuthors.length + 1); const createdAuthor = { id, firstName, lastName }; mockedAuthors.push(createdAuthor); return createdAuthor; } }; app.use(cors()); app.use( "/graphql", graphqlHTTP({ schema, rootValue: root, graphiql: true, }) ); app.listen(8080);
所以,你有了它。你應該有一個工作的GraphQL服務器,你可以與之互動,以檢索和修改或刪除數(shù)據(jù)。
你可能會選擇開始研究將解析器和模式類型分離到單獨的目錄和文件中,并在server.js文件中聚合它們,還有更多;在考慮擴展GraphQL應用程序時,選擇是無窮無盡的。畢竟,這是它被建立的原因之一。
我希望你喜歡閱讀這篇文章,并希望它能幫助你了解使用Node.js和Express設(shè)置GraphQL服務器的基本原理。
總結(jié)
到此這篇關(guān)于用Node.js與Express建立一個GraphQL服務器的文章就介紹到這了,更多相關(guān)Node.js和Express建立GraphQL服務器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Node做中轉(zhuǎn)服務器轉(zhuǎn)發(fā)接口
這篇文章主要介紹了Node做中轉(zhuǎn)服務器轉(zhuǎn)發(fā)接口的相關(guān)資料,需要的朋友可以參考下2017-10-10Nodejs使用exceljs實現(xiàn)excel導入導出
在日常開發(fā)中,我們常需在后臺管理系統(tǒng)中實現(xiàn)數(shù)據(jù)的導入與導出功能,以便與?Excel?文件進行交互,本文將使用使用exceljs實現(xiàn)excel導入導出功能,需要的可以參考下2024-03-03NPM命令運行報錯:npm?v10.2.4?is?known?not?to?run?on?Node.js
這篇文章主要給大家介紹了關(guān)于NPM命令運行報錯:npm?v10.2.4?is?known?not?to?run?on?Node.js?v14.21.1的解決辦法,文中將解決辦法介紹的非常詳細,需要的朋友可以參考下2024-01-01