歡迎golang同胞!在本教程中,我們將研究如何在基於 Go 的程序中與 GraphQL 服務器進行交互。在本教程結束時,我們應該知道如何執行以下操作:
在本教程中,我們將專註於學習 GraphQL 的數據檢索方面,並且我們將使用內存中的數據源來支持它。這應該為我們在後續教程的基礎上建立壹個良好的基礎。
好的,所以在我們深入研究之前,我們應該真正了解 GraphQL 的基礎知識。作為開發人員,使用它對我們有什麽好處?
好吧,考慮使用每天處理數十萬甚至數百萬請求的系統。傳統上,我們會使用位於數據庫前面的系統 API,它會返回大量 JSON 響應,其中包含許多我們可能不壹定需要的冗余信息。
如果我們正在處理大規模的應用程序,發送冗余數據的成本可能會很高,並且由於有效負載大小會阻塞我們的網絡帶寬。
GraphQL基本上可以讓我們以減少噪音和描述數據,我們希望讓我們的檢索,從我們的API中檢索 只有 我們需要為我們當前的任務/視圖/不管。
這只是該技術為我們提供的眾多好處的壹個例子。希望在接下來的教程系列中,我們會提前看到更多這些好處。
需要註意的重要壹點是,GraphQL 不像我們傳統的 SQL 那樣是壹種查詢語言。它是位於我們 API 前面的抽象, 不 依賴於任何特定的數據庫或存儲引擎。
這真的很酷。我們可以建立壹個與現有服務商交互的 GraphQL 服務器,然後圍繞著這個新的 GraphQL 服務器構建,而不必擔心修改現有的 REST API。
讓我們看看 RESTful 方法與 GraphQL 方法有何不同。現在,假設我們正在構建壹個返回該站點上所有教程的服務,如果我們想要特定教程的信息,我們通常會創建壹個 API 端點,允許我們根據 ID 檢索特定教程:
如果給定壹個 valid ID,這將返回壹個響應,看起來像這樣:
現在,假設我們想創建壹個小部件,列出該作者撰寫的書籍 5 個帖子。我們可以點擊/author/:id端點以檢索該作者撰寫的所有帖子,然後進行後續調用以檢索前 5 個帖子中的每壹個。或者,我們可以制作壹個全新的端點來為我們返回這些數據。
這兩種解決方案聽起來都不是特別吸引人,因為它們會創建不需要的請求量或返回過多的數據,這突出了 RESTful 方法開始出現壹些裂縫的地方。
這就是 GraphQL 發揮作用的地方。使用 GraphQL,我們可以定義我們希望在查詢中返回的數據的確切結構。所以如果我們想要上面的信息,我們可以創建壹個看起來像這樣的查詢:
這將隨後返回我們的教程、該教程的作者和壹組表示該作者編寫的教程的教程 ID,而無需發送額外的 x 多個 REST 請求來獲取信息!那有多好?
好的,現在我們對 GraphQL 以及對它的用途有了更多的了解,讓我們在實踐中看看它。
我們將使用graphql-go/graphql實現在 Go 中創建壹個簡單的 GraphQL 服務器 。
讓我們首先使用go mod init以下方法初始化我們的項目:
接下來,讓我們創建壹個名為main.go. 我們將從簡單開始創建壹個非常簡單的 GraphQL 服務器,它具有壹個非常簡單的解析器:
現在,如果我們嘗試運行它,讓我們看看會發生什麽:
所以,如果壹切正常,那麽我們就可以設置壹個非常簡單的 GraphQL 服務器並對這個服務器進行非常簡單的查詢。
讓我們分解上面代碼中發生的事情,以便我們可以進壹步擴展它。在lines 14-21我們定義我們的Schema. 當我們對我們的 GraphQL API 進行查詢時,我們基本上定義了我們想要返回給我們的對象上的哪些字段,因此我們必須在我們的 Schema 重新定義這些字段。
在 上line 17,我們定義了壹個解析器函數,每當field請求此特定內容時就會觸發該解析器函數。現在,我們只是返回字符串 "world",但我們將實現從這裏查詢數據庫的能力。
讓我們看壹下main.go文件的第二部分。在line 30我們開始定義query請求領域hello。
然後我們創建壹個params結構,其中包含對我們定義的Schema以及我們的RequestString請求的引用 。
最後,在line 36我們執行請求並將請求的結果填充到r. 然後我們進行壹些錯誤處理,然後將響應編組為 JSON 並將其打印到我們的控制臺上。
現在我們已經啟動並運行了壹個非常簡單的 GraphQL 服務器,並且我們能夠對其進行查詢,讓我們更進壹步,構建壹個更復雜的示例。
我們將創建壹個 GraphQL 服務器,它返回壹系列內存中的教程及其作者,以及對這些特定教程的任何評論。
讓我們定義壹些struct代表 a Tutorial、 anAuthor和 a 的's Comment:
然後我們可以創建壹個非常簡單的populate()函數,它將返回壹個類型數組Tutorial:
這將為我們提供壹個簡單的教程列表,然後我們可以稍後解決。
我們將從使用 GraphQL 創建壹個新對象開始graphql.NewObject()。我們將使用 GraphQL 的嚴格類型定義 3 種不同的類型,它們將與structs我們已經定義的 3 種相匹配。
我們的Commentstruct 可以說是最簡單的,它只包含壹個 string Body,所以我們可以commentType很容易地將其表示為:
接下來,我們將處理該Author結構並將其定義為壹個新的 graphql.NewObject(). 這會稍微復雜壹些,因為它既有壹個 String字段,也有壹個Int值列表,這些值代表他們編寫的教程的 ID。
最後,讓我們定義我們的tutorialTypewhich 將封裝 an author和comment's的數組以及 anID和 a title:
現在我們已經定義了我們的Type系統,讓我們著手更新我們的 Schema 以反映這些新類型。我們將定義 2 個 distinct Field,第壹個將是我們的tutorial字段,它允許我們Tutorials 根據傳入查詢的 ID檢索個人。第二個將是壹個list字段,它將允許我們檢索Tutorials我們在內存中定義的完整數組。
所以我們已經創建了我們的類型並更新了我們的 GraphQL 模式,我們做得還不錯!
讓我們嘗試使用我們的新 GraphQL 服務器並處理我們提交的查詢。讓我們來嘗試我們的list架構改變query ,我們已經在我們得到main()的功能:
讓我們分解壹下。所以在我們的查詢中,我們有壹個特殊的root對象。然後我們在其中說我們想要該list對象上的字段。在返回的名單list,我們希望看到的id,title,comments和 author。
當我們運行它時,我們應該會看到以下輸出:
正如我們所見,我們的查詢以 JSON 格式返回了我們所有的教程,看起來非常像我們初始查詢的結構。
現在讓我們嘗試對我們的tutorial模式進行查詢:
再壹次,當我們運行它時,我們應該看到它已經成功地檢索了內存中的單獨教程ID=1:
完美,看起來我們已經讓list我們的tutorial模式和我們的模式都按預期工作了。
這就是我們將在這個初始教程中介紹的全部內容。我們已經成功地設置了壹個簡單的 GraphQL 服務器,該服務器由內存數據存儲支持。
在下壹個教程中,我們將研究 GraphQL 突變並更改我們的數據源以使用 SQL 數據庫