如何使用 Next.js API 路由構建 GraphQL 服務器

已發表: 2022-03-10
快速總結↬本指南將教您 Next.js API 路由的基礎知識。 我們將首先解釋它們是什麼以及為什麼 API 路由與 REST 或 GraphQL API 相比有用。 然後,我們將指導您逐步完成教程,了解如何使用 Next.js 和 Github API 構建您的第一個 GraphQL 服務器。

Next.js 為您提供最佳的開發人員體驗,其中包含生產所需的所有功能。 它提供了一個使用 Next.js API 路由構建 API 的簡單解決方案。

在本指南中,我們將首先了解什麼是 API 路由,然後創建一個使用 Next.js API 路由從 Github API 檢索數據的 GraphQL 服務器。

要充分利用本教程,您至少需要對 GraphQL 有基本的了解。 了解 Apollo Server 會有所幫助,但不是強制性的。 本教程將使那些想要將他們的 React 或 Next.js 技能擴展到服務器端並能夠使用 Next.js 和 GraphQL 構建他們的第一個全棧應用程序的人受益。

所以,讓我們潛入吧。

什麼是 Next.js API 路由?

Next.js 是一個框架,可以在客戶端或/和服務器上渲染 React 應用程序。 從版本 9 開始,Next.js 現在可用於使用 Node.js、Express、GrapQL 等構建 API。 Next.js 使用文件系統將文件夾pages/api中的文件視為 API 端點。 這意味著,現在,您將能夠通過 URL https://localhost:3000/api/your-file-name訪問您的 API 端點。

如果你來自 React 並且從未使用過 Next.js,這可能會讓人感到困惑,因為 Next.js 是一個 React 框架。 正如我們已經知道的那樣,React 用於構建前端應用程序。 那麼為什麼將 Next.js 用於後端應用程序和 API 呢?

嗯,Next.js 可以在客戶端和服務器端使用,因為它是用 React、Node.js、Babel 和 Webpack 構建的,顯然它也應該可以在服務器端使用。 Next.js 依賴於服務器來啟用 API 路由,並允許您使用您最喜歡的後端語言,即使它在技術上是一個 React 框架。 希望你做對了。

到目前為止,我們已經了解了 API 路由是什麼。 然而,真正的問題仍然存在:為什麼要使用 Next.js 來構建 GraphQL 服務器? 為什麼不使用 GraphQL 或 Node.js 來實現呢? 因此,讓我們在下一節將 Next.js API 路由與用於構建 API 的現有解決方案進行比較。

Next.js API 路由與 REST 和 GraphQL

GraphQL 和 REST 是構建 API 的好方法。 它們非常受歡迎,現在幾乎每個開發人員都在使用它們。 那麼,為什麼要使用 React 框架來構建 API? 好吧,快速回答是 Next.js API 路由有不同的用途,因為 API 路由允許您通過添加後端來擴展 Next.js 應用程序。

構建 API 有更好的解決方案,例如 Node.js、Express、GraphQL 等,因為它們專注於後端。 在我看來,API Routes 應該與客戶端相結合,以使用 Next.js 構建一個全棧應用程序。 使用 API Routes 構建一個簡單的 API 就像沒有充分利用 Next.js 的強大功能,因為它是一個 React 框架,使您能夠立即向其添加後端。

當您需要向現有的 Next App 添加身份驗證時,請考慮用例。 您可以使用 API Routes 向您的應用程序添加身份驗證,而不是使用 Node.js 或 GraphQL 從頭構建身份驗證部分,並且它仍然可以在端點https://localhost:3000/api/your-file-name上使用https://localhost:3000/api/your-file-name 。 API 路由不會增加您的客戶端捆綁包大小,因為它們只是服務器端捆綁包。

但是,Next.js API 路由只能在同源內訪問,因為 API 路由沒有指定跨域資源共享 (CORS) 標頭。 您仍然可以通過將 CORS 添加到 API 來調整默認行為——但這是一個額外的設置。 如果您使用next export靜態生成您的下一個應用程序 - 您將無法在您的應用程序中使用 API 路由。

到目前為止,我們已經了解了 API 路由何時可能是比同類解決方案更好的解決方案。 現在,讓我們動手並開始構建我們的 GraphQL 服務器。

跳躍後更多! 繼續往下看↓

配置

要使用 Next.js 啟動一個新應用,我們將使用 Create Next App。 也可以使用 Webpack 手動設置新應用。 非常歡迎您這樣做。 話雖如此,打開您的命令行界面並運行以下命令:

 npx create-next-app next-graphql-server

Next.js 為 API 路由提供了一個入門模板。 您可以通過執行以下命令來使用它:

 npx create-next-app --example api-routes api-routes-app

在本教程中,我們希望從頭開始做所有事情,這就是為什麼我們使用 Create Next App 來啟動一個新應用程序,而不是使用 starter 模板。 現在,按如下方式構建項目:

 ├── pages | ├── api | | ├── graphql.js | | ├── resolvers | | | └── index.js | | └── schemas | | └── index.js | └── index.js ├── package.json └── yarn.lock

正如我們之前所說, api文件夾是我們的 API 或服務器所在的位置。 由於我們將使用 GraphQL,我們需要一個解析器和一個模式來創建一個 GraphQL 服務器。 服務器的端點可以通過路徑/api/graphql訪問,該路徑是 GraphQL 服務器的入口點。

通過這一步,我們現在可以為我們的服務器創建 GraphQL Schema。

創建 GraphQL 模式

快速回顧一下,GraphQL 模式定義了數據圖的形狀。

接下來,我們需要安裝apollo-server-micro以在 Next.js 中使用 Apollo Server。

 yarn add apollo-server-micro

對於npm

 npm install apollo-server-micro

現在,讓我們創建一個新的 GraphQL 模式。

api/schemas/index.js

 import { gql } from "apollo-server-micro"; export const typeDefs = gql` type User { id: ID login: String avatar_url: String } type Query { getUsers: [User] getUser(name: String!): User! }`

在這裡,我們定義了一個描述 Github 用戶形狀的User類型。 它需要一個id類型的ID 、一個login和一個 String 類型的avatar_url 。 然後,我們在getUsers查詢中使用必須返回用戶數組的類型。 接下來,我們依靠getUser查詢來獲取單個用戶。 它需要接收用戶的名稱才能檢索它。

創建此 GraphQL Schema 後,我們現在可以更新解析器文件並創建函數來執行上述這些查詢。

創建 GraphQL 解析器

GraphQL 解析器是一組函數,可讓您從 GraphQL 查詢生成響應。

要從 Github API 請求數據,我們需要安裝axios庫。 因此,打開 CLI 並執行以下命令:

 yarn add axios

或者在使用npm

npm install axios

安裝庫後,現在讓我們在解析器文件中添加一些有意義的代碼。

api/resolvers/index.js

 import axios from "axios"; export const resolvers = { Query: { getUsers: async () => { try { const users = await axios.get("https://api.github.com/users"); return users.data.map(({ id, login, avatar_url }) => ({ id, login, avatar_url })); } catch (error) { throw error; } }, getUser: async (_, args) => { try { const user = await axios.get( `https://api.github.com/users/${args.name}` ); return { id: user.data.id, login: user.data.login, avatar_url: user.data.avatar_url }; } catch (error) { throw error; } } } };

正如您在此處看到的,我們將之前在 GraphQL Schema 上定義的查詢名稱與解析器函數相匹配。 getUsers函數使我們能夠從 API 中檢索所有用戶,然後返回需要鏡像User類型的用戶數組。 接下來,我們使用getUser方法在作為參數傳入的名稱的幫助下獲取單個用戶。

有了這個,我們現在有了一個 GraphQL Schema 和一個 GraphQL 解析器——是時候將它們組合起來並構建 GraphQL 服務器了。

創建 GraphQL 服務器

GraphQL 服務器將您的數據公開為 GraphQL API。 它使客戶應用程序能夠準確地詢問他們需要的數據,僅此而已。

api/graphql.js

 import { ApolloServer } from "apollo-server-micro"; import { typeDefs } from "./schemas"; import { resolvers } from "./resolvers"; const apolloServer = new ApolloServer({ typeDefs, resolvers }); export const config = { api: { bodyParser: false } }; export default apolloServer.createHandler({ path: "/api/graphql" });

導入ApolloServer後,我們使用它創建一個新實例,然後傳入 schema 和解析器來創建一個 GraphQL 服務器。 接下來,我們需要告訴 Next.js 不要解析傳入的請求,讓 GraphQL 為我們處理。 最後,我們使用apolloServer創建一個新的處理程序,這意味著路徑/api/graphql將作為我們 GraphQL 服務器的入口點。

與常規的 Apollo Server 不同,Next.js 為我們處理服務器的啟動,因為它依賴於服務器端渲染。 這就是為什麼在這裡,我們不必自己啟動 GraphQL 服務器。

偉大的! 通過這一步,我們現在可以測試 GraphQL 服務器是否正常工作。

測試 GraphQL 服務器

瀏覽到項目的根目錄後,在 CLI 上打開它,然後執行以下命令:

 yarn dev

或者對於npm

 npm run dev

現在,訪問https://localhost:3000/api/graphql並在下面添加 GraphQL 查詢以從 Github 檢索所有用戶。

 { getUsers { id login avatar_url } }
獲取所有用戶
獲取所有用戶。 (大預覽)

讓我們檢查一下我們是否可以使用此查詢獲取單個用戶。

 query($name: String!){ getUser(name:$name){ login id avatar_url } }
獲取用戶
獲取用戶。 (大預覽)

偉大的! 我們的服務器按預期工作。 我們已經使用 Next.js API Routes 構建了一個 GraphQL 服務器。

結論

在本教程中,我們首先解釋了 Next.js API 路由是什麼,然後使用 Next.js 構建了一個 GraphQL 服務器。 將後端添加到 Next.js 應用程序的能力是一個非常好的功能。 它允許我們使用真正的後端擴展我們的應用程序。 您甚至可以更進一步,連接數據庫以使用 API 路由構建完整的 API。 Next.js 無疑使使用 API 路由構建全棧應用程序變得更加容易。

您可以在 CodeSandbox 上預覽完成的項目。

謝謝閱讀!

更多資源

這些有用的資源將使您超出本教程的範圍。

  • 介紹 API 路由 (Next.js 9)
  • Next.js API 路由
  • API 路由中間件