GraphQL(二):Apollo GraphQL Server應用

閱讀時間約 21 分鐘

※ 什麼是Apollo GraphQL Server?

Apollo GraphQL Server 是一個將GraphQL的標準轉化為實際可用的工具和框架,可以在Node.js 常用的中介軟體像是 Express 或 Fastify 所建立的伺服器中,輕鬆加入和設定 Apollo GraphQL Server 來處理 GraphQL 請求。它是一個強大的 GraphQL 引擎,可以連接資料庫、RESTful API 或其他 GraphQL 服務,作為服務的整合介面。Apollo GraphQL Server 提供了許多實用的功能和工具,使開發者能夠輕鬆建立和管理 GraphQL API,並與各種資料源連接。

Apollo GraphQL Server 的主要特點包括:

  1. 強型別語言:可以明確定義資料型態,型別錯誤會被直接阻擋,並且可以自動產生文件,使程式即文檔。
  2. 減少資訊短缺或過度獲取:類似 SQL 語言的方式,使用者可以精確自定查詢條件及回傳內容,避免過多或過少的數據傳輸。
  3. 高相容性:無論是前端使用、與 REST API 混搭開發,還是通過微服務架構統一資料交換接口,都能讓開發更具彈性。
raw-image


※ 下載Apollo GraphQL Server

npm install apollo-server graphql

★ 新版Apollo GraphQL Server:

raw-image


raw-image

※ Apollo GraphQL Server依賴GraphQL的原因主要有以下幾點:

  1. 核心功能:Apollo Server是專門為GraphQL設計的伺服器,它依賴GraphQL來定義數據結構和查詢語言。
  2. 解析器函數:GraphQL伺服器使用解析器函數來處理查詢,Apollo Server利用這些解析器函數,從不同的數據源(如資料庫、REST API等)獲取數據。
  3. 高效查詢:GraphQL允許客戶端查詢所需的精確欄位,減少了不必要的數據傳輸,提升了性能。
  4. 自動文件化:GraphQL的模式(schema)自帶文件化功能,Apollo Server利用這一特性來提供自動生成的API文檔。

這些特性使得Apollo GraphQL Server能夠高效地處理和管理GraphQL查詢,並提供強大的數據訪問能力。

※ Apollo GraphQL Server透過Nodejs Express來建立自己的應用伺服器,原因有三個:

  1. 流行性和兼容性:Express是最受歡迎的Node.js網絡框架之一,跟很多其他流行的程式庫都能很好地搭配使用。
  2. 中介層支持:用Express可以很方便地使用Node.js的中介層來處理一些常見問題,比如速率限制、安全性和身份驗證。
  3. 靈活性:透過apollo-server-express,可以同時提供REST和GraphQL服務。
  4. 簡單設置:把Apollo Server當作中介層應用在Express HTTP實例中,設置起來相對簡單。
raw-image


※ Apollo GraphQL Server 提供了一些工具和功能來輔助 GraphQL 的使用。以下是一些主要的輔助工具和功能:

  1. Apollo Studio:這是一個圖形化介面,可以更方便地管理和監控 GraphQL 服務。它提供查詢性能分析、錯誤追蹤和使用情況報告等功能。
  2. Apollo Client:這是一個用來與 GraphQL 服務互動的 JavaScript 客戶端。它簡化了查詢、變更和訂閱的過程,並提供快取機制來提升性能。
  3. Apollo Server:這是一個用來建構 GraphQL API 的伺服器框架。它與 Express、Koa 等 Node.js 框架相容,並提供許多中間件和外掛來擴展功能。
  4. Apollo Federation:這是一個用來建構分佈式 GraphQL 架構的工具。它允許你將多個 GraphQL 服務合併成一個統一的 GraphQL 閘道,達到簡化認證機制、提升查詢優化和快取性能。
raw-image


※ Apollo Server 時所需的依賴和工具:主要包括:

  • @apollo/server:這是 Apollo Server 本身的主要套件。它負責將 HTTP 請求和回應轉換為 GraphQL 操作,並在可擴展的環境中運行這些操作,支持外掛和其他功能。
  • graphql:也稱為 graphql-js,是實現核心 GraphQL 解析和執行算法的套件。這個套件是 Apollo Server 的對等依賴項。
raw-image


※ 在 Apollo Server 中,typeDefs 和 resolvers 是兩個非常重要的參數,它們共同定義了你的 GraphQL API 的結構和行為。

typeDefs :用來定義 GraphQL schema ,目的是描述數據結構和查詢操作。

例如:

這段代碼展示了如何使用 typeDefs 來定義 GraphQL schema,包括查詢、變更和輸入/輸出類型。

const typeDefs = gql`
type User {
id: ID!
email(text: String): String
name: String
}

type Query {
user: User
}

input UpdateUserInputType {
id: ID!
name: String
}

type UpdateUserPayload {
payload: User
status: String
message:String
errors: [String]
}

type Mutation {
updateUser(input: UpdateUserInputType): UpdateUserPayload

}
`


resolvers :是用來處理實際查詢的函數。每個 resolver 函數負責填充 schema 中對應字段的數據。它可以從數據庫、第三方 API 或其他來源獲取數據。

例如:

這段代碼展示了如何使用 resolvers 來處理查詢和變更操作。

const resolvers = {
Query: {
user: (root, args, context, info) => {
return context.database.user
},
},
Mutation: {
updateUser: (root, args, context, info) => {
const {auth} = context
if (!auth) {
return {
status: 401,
message: "unauthorization"
}
}
const {id, name} = args.input
if (parseInt(id, 10) === user.id) {
user['name'] = name
}
return {
payload: user,
status: 200,
message: "Success",
errors: null
}
}
},
User: {
email: (parent, args, context, info) => {
const {text} = args
if (user.email.indexOf(text) >= 0) {
return parent.email + text
}
return null
}
}

}
raw-image


※ 在 Apollo Server 中,typeDefs 負責定義所有的 GraphQL 類型,包括查詢(Query)和變更(Mutation)。這些類型定義了你的 GraphQL API 的結構和操作。通常,typeDefs 會搭配 Apollo GraphQL Server 提供的 gql 標籤模板字面量來撰寫。

※ 使用 gql 標籤模板字面量(tagged template literal)來定義 typeDefs 是一種常見的做法。主要原因:

  1. 語法標示:使用 gql 標籤模板字面量可以讓編輯器識別出這段代碼是 GraphQL schema。編輯器可對代碼進行不同顏色標示,以提高代碼的可讀性和編寫效率。
  2. 語法檢查:gql 標籤模板字面量會在編譯時對 GraphQL schema 進行語法檢查,及早發現並修正語法錯誤。
  3. 可讀性:使用 gql 標籤模板字面量將 GraphQL schema 與其他 JavaScript 代碼區分開來,方便閱讀。
  4. 模板字面量:JavaScript 的模板字面量允許在字符串中嵌入變量和表達式,這對於動態生成 GraphQL schema 非常有用。
raw-image


※ Apollo GraphQL Server完整的請求處理過程:

  1. 接收請求Apollo Server 接收到這個查詢請求。
  2. 解析查詢伺服器解析查詢,確定需要哪些數據和操作。
  3. 執行解析器函數伺服器調用對應的解析器函數(resolvers)來處理查詢或變更。 解析器函數負責從數據庫或其他數據源獲取所需的數據,並將結果返回給伺服器。
  4. 生成回應伺服器將獲取到的 數據組裝成 GraphQL 回應,並返回給客戶端。
raw-image


※ 當你在 Apollo GraphQL Server 中加入 updateUser 這樣的變更操作時,必須在 typeDefs 中定義對應的 Mutation 類型,並在解析器中實現具體的變更邏輯。這樣,伺服器才能正確處理和響應這個變更請求。

以下這段程式碼展示了如何定義一個變更操作 updateUser,包括輸入類型 UpdateUserInputType 和返回類型 UpdateUserPayload。這樣的設計可以讓客戶端發送變更請求來更新使用者數據,並獲取操作的結果和相關訊息

raw-image



※ 在 Apollo GraphQL Server 中,添加 Mutation 和 updateUser  解析器函數的主要目的是處理客戶端發送的變更請求,並更新伺服器上的數據。

在這個範例中:

const resolvers = {
Mutation: {
updateUser: (root, args, context, info) => {
const { auth } = context;
if (!auth) {
return {
status: 401,
message: "unauthorization",
};
}
const { id, name } = args.input;
if (parseInt(id, 10) === user.id) {
user['name'] = name;
}
return {
payload: user,
status: 200,
message: "Success",
errors: null,
};
},
},
};
  1. 處理變更請求當客戶端發送 updateUser 變更請求時,伺服器會調用 updateUser 解析器。
  2. 驗證和授權:解析器檢查 context 中的 auth 狀態,如果未授權則返回 401 狀態。
  3. 更新數據:解析器函數根據輸入的 id 和 name 更新對應的使用者數據。
  4. 返回結果:解析器函數返回更新後的使用者數據、操作狀態和相關訊息。
raw-image


※ 在 Apollo GraphQL Server 中,updateUser: (root, args, context, info) 是一個解析器函數,用於處理 updateUser 變更操作。

解析這個函數的參數:

  1. root這個參數通常是上一層解析器函數的返回結果。如果沒有上一層解析器函數,這個參數通常是 null 或 undefined一個。例如,如果你查詢 user,返回一個 User 對象,那麼在 User 類型的解析器函數中,root 就是這個 User 對象。
  2. args(arguments參數)包含客戶端傳遞給這個變更操作的參數。在這個例子中,args.input 包含了 UpdateUserInputType 類型的數據。
  3. context包含請求的上下文信息,例如認證狀態、數據庫連接等。在這個例子中,我們使用 context.auth 來檢查用戶是否已經授權。
  4. info包含查詢的執行信息和 schema 詳細信息,通常用於進階的查詢處理。
raw-image


※ 在 Apollo GraphQL Server 中,應用程序的最後一步就是確保伺服器在特定的網絡端口上運行,啟動伺服器並讓它開始接收和處理來自客戶端的請求。

raw-image


※ Apollo GraphQL Server 的基本架構可以分為以下幾個步驟:

  1. 引用 apollo-server:首先需要安裝並引用 apollo-server 套件。
  2. 定義 Schema:使用 GraphQL 定義 Schema,描述數據結構和查詢方式。
  3. 定義 Resolvers:定義 Resolvers 來處理查詢和變更,這些函數負責從數據源中獲取數據。
  4. 創建伺服器實例:使用 ApolloServer 創建伺服器實例,並將 Schema 和 Resolvers 傳遞給伺服器。
  5. 指定端口並啟動伺服器:指定伺服器運行的端口,然後啟動伺服器。

※ 展示Apollo GraphQL Server 的基本架構(簡易版):

const { ApolloServer, gql } = require('apollo-server');

// 定義 schema

const typeDefs = gql`

type Query {

hello: String

}

`;

// 定義 resolvers

const resolvers = {

Query: {

hello: () => 'Hello world!',

},

};

// 創建伺服器實例

const server = new ApolloServer({ typeDefs, resolvers });

// 指定端口並啟動伺服器

server.listen({ port: 4000 }).then(({ url }) => {

console.log(`🚀 Server ready at ${url}`);

});

※ 展示Apollo GraphQL Server 的基本架構(複雜版):

const { ApolloServer, gql } = require('apollo-server');

// 模擬的資料庫
const database = {
user: {
id: 1,
name: 'Whien',
email: 'sal9561@gmail.com',
friends: ['Bob', 'Tom'],
work_state: 1,
created_at: new Date(),
updated_at: new Date()
}
};

// 模擬的使用者資料
const user = {
id: 1,
name: 'Whien',
email: 'sal9561@gmail.com',
friends: ['Bob', 'Tom'],
work_state: 1,
created_at: new Date(),
updated_at: new Date()
};

// 定義 GraphQL schema
const typeDefs = gql`
type User {
id: ID!
email(text: String): String
name: String
}

type Query {
user: User
}

input UpdateUserInputType {
id: ID!
name: String
}

type UpdateUserPayload {
payload: User
status: String
message: String
errors: [String]
}

type Mutation {
updateUser(input: UpdateUserInputType): UpdateUserPayload
}
`;

// 定義 resolvers
const resolvers = {
Query: {
user: (root, args, context, info) => {
return context.database.user;
},
},
Mutation: {
updateUser: (root, args, context, info) => {
const { auth } = context;
if (!auth) {
return {
status: 401,
message: "unauthorization"
};
}
const { id, name } = args.input;
if (parseInt(id, 10) === user.id) {
user['name'] = name;
}
return {
payload: user,
status: 200,
message: "Success",
errors: null
};
}
},
User: {
email: (parent, args, context, info) => {
const { text } = args;
if (user.email.indexOf(text) >= 0) {
return parent.email + text;
}
return null;
}
}
};

// 創建 Apollo 伺服器實例
const server = new ApolloServer({
typeDefs,
resolvers,
context: () => {
return {
auth: false,
database
};
}
});

// 指定端口並啟動伺服器
server.listen(8891, () => {
console.log('Apollo GraphQL Server run on port 8891');
});



    全端網頁開發專業知識分享
    留言0
    查看全部
    發表第一個留言支持創作者!
    ※ REST API 和 Apollo GraphQL Server 的區別: 資料獲取方式: REST API:每個資源都有一個固定的 URL,並且通過 HTTP 方法(如 GET、POST、PUT、DELETE)來操作這些資源。伺服器決定返回的資料結構。 GraphQL:使用單一的端點(通
    ※ 什麼是GraphQL? GraphQL 是由 Facebook 於 2015 年開發的一種 API 查詢語言。客戶端(前端)只會接收到所需的數據,減少了不必要的數據傳輸和多次請求的需要,提高了應用程序的性能和效率。GraphQL 支持查詢、變更和即時更新操作,解決了傳統 REST API 中的
    ※ Express串接MySQL相關套件介紹 ★ Express 資料庫設定套件,mysqljs和 mysql2比較 相同點:都是讓 Node.js 能使用 MySQL 的套件 (package)。安裝之後我們就能在 Node.js application 裡使用 SQL 指令,操作 SQL
    ※ 設定首頁路由兩種寫法: ● res.send() // 設定首頁路由 app.get('/', (req, res) => { res.send('hello world') }) 說明: 功能:res.send() 用於發送 HTTP 回應消息。它可以發送字符串、Buffer、對
    ※ Schema Design 小測驗 ● 測驗一:電商平台是後端開發最基本的例子 幫電商平台設計一個SQL Database Schema,需要保存商品資料、顧客資料、訂單資料… 輔助設計Schema的工具: https://drawsql.app 優點: 網頁版,方便使用。 功能
    ※ Schema 設計 ● 什麼是Schema? Schema 是用來描述資料庫內的表格結構、欄位格式以及表格之間的關聯。它定義了資料庫的邏輯結構,確保資料的組織和存取方式一致。 思考點:資料以什麼「形式」保存在資料庫? 資料在資料庫中以多種形式保存,主要包括以下幾種: 表格 (Table
    ※ REST API 和 Apollo GraphQL Server 的區別: 資料獲取方式: REST API:每個資源都有一個固定的 URL,並且通過 HTTP 方法(如 GET、POST、PUT、DELETE)來操作這些資源。伺服器決定返回的資料結構。 GraphQL:使用單一的端點(通
    ※ 什麼是GraphQL? GraphQL 是由 Facebook 於 2015 年開發的一種 API 查詢語言。客戶端(前端)只會接收到所需的數據,減少了不必要的數據傳輸和多次請求的需要,提高了應用程序的性能和效率。GraphQL 支持查詢、變更和即時更新操作,解決了傳統 REST API 中的
    ※ Express串接MySQL相關套件介紹 ★ Express 資料庫設定套件,mysqljs和 mysql2比較 相同點:都是讓 Node.js 能使用 MySQL 的套件 (package)。安裝之後我們就能在 Node.js application 裡使用 SQL 指令,操作 SQL
    ※ 設定首頁路由兩種寫法: ● res.send() // 設定首頁路由 app.get('/', (req, res) => { res.send('hello world') }) 說明: 功能:res.send() 用於發送 HTTP 回應消息。它可以發送字符串、Buffer、對
    ※ Schema Design 小測驗 ● 測驗一:電商平台是後端開發最基本的例子 幫電商平台設計一個SQL Database Schema,需要保存商品資料、顧客資料、訂單資料… 輔助設計Schema的工具: https://drawsql.app 優點: 網頁版,方便使用。 功能
    ※ Schema 設計 ● 什麼是Schema? Schema 是用來描述資料庫內的表格結構、欄位格式以及表格之間的關聯。它定義了資料庫的邏輯結構,確保資料的組織和存取方式一致。 思考點:資料以什麼「形式」保存在資料庫? 資料在資料庫中以多種形式保存,主要包括以下幾種: 表格 (Table
    你可能也想看
    Google News 追蹤
    Thumbnail
    這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
    Thumbnail
    11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
    Thumbnail
    Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
    Thumbnail
    這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
    Thumbnail
    在這篇教學文章中,我們將展示如何使用 Node.js 建立一個簡單的伺服器,並解決常見的跨來源資源共享(CORS)問題,確保伺服器能夠接收並處理來自不同來源的資料。
    Thumbnail
    ※ 什麼是Web API API 就是後端開出來讓前端來用的介面,讓前端與後端可以溝通。 API流程: 終端使用者用任何一種裝置進入瀏覽器。 瀏覽器透過 API 向後端發出請求,請求查詢或修改資料。 後端透過 API 收到前端的請求後,取得資料並回應給前端。 前端渲染畫面,終端使用者
    Thumbnail
    ※ 原本狀態:伺服器渲染 這是 MVC 架構下的 request / response 示意圖,在這張圖呈現的架構裡,畫面和資料都由同一個架構處理。 伺服器渲染流程: 瀏覽器針對特定網址送出請求。 路由器解析請求後,轉接給對應的 controller。 controller 按照要求,透過
    ※ 補充說明: ※ npm 常用指令: ◦ npm init–y:快速初始化一個新的 Node.js 並建立一個 package.json 文件的命令。 ◦ npm info 套件名稱 version:快速查詢指定 npm 套件的最新版本號。 ◦ npm install套件名稱:用來安裝
    Thumbnail
    雲端已經成為App開發的核心,而Amazon的AWS(Amazon Web Services是開發者常用的平台,可以幫助開發者建立、整合和擴展App。
    Thumbnail
    支援Go所有的類型儲存,且可以用原生SQL敘述與跨資料庫查詢。 映射關係 table->struct record->object field->attribute 安裝 go get github.com/astaxie/beego/orm​ go get github.com
    ※ Express 專案步驟筆記清單 Node.js 環境建置核對 新增專案資料夾 設定 package.json npm init -y 設定程式入口為 app.js 安裝 Express:npm install express 設定主程式 app.js 建構應用程式伺服器 設定
    Thumbnail
    gRPC是一款跨平台、高性能的RPC框架,他可以在任何環境下執行,主要用於後端為服務開發。在用戶端應用程式中,可以像本地物件那樣呼叫遠端伺服器的方法,因此可以創建出分散式應用。 使用 到https://github.com/protocolbuffers/protobuf/releases下
    Thumbnail
    Request內容 package main import ( "fmt" "log" "net/http" "strings" ) func request(w http.ResponseWriter, r *http.Request) { //這些資訊是輸出到伺服器端的列印訊息
    Thumbnail
    這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
    Thumbnail
    11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
    Thumbnail
    Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
    Thumbnail
    這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
    Thumbnail
    在這篇教學文章中,我們將展示如何使用 Node.js 建立一個簡單的伺服器,並解決常見的跨來源資源共享(CORS)問題,確保伺服器能夠接收並處理來自不同來源的資料。
    Thumbnail
    ※ 什麼是Web API API 就是後端開出來讓前端來用的介面,讓前端與後端可以溝通。 API流程: 終端使用者用任何一種裝置進入瀏覽器。 瀏覽器透過 API 向後端發出請求,請求查詢或修改資料。 後端透過 API 收到前端的請求後,取得資料並回應給前端。 前端渲染畫面,終端使用者
    Thumbnail
    ※ 原本狀態:伺服器渲染 這是 MVC 架構下的 request / response 示意圖,在這張圖呈現的架構裡,畫面和資料都由同一個架構處理。 伺服器渲染流程: 瀏覽器針對特定網址送出請求。 路由器解析請求後,轉接給對應的 controller。 controller 按照要求,透過
    ※ 補充說明: ※ npm 常用指令: ◦ npm init–y:快速初始化一個新的 Node.js 並建立一個 package.json 文件的命令。 ◦ npm info 套件名稱 version:快速查詢指定 npm 套件的最新版本號。 ◦ npm install套件名稱:用來安裝
    Thumbnail
    雲端已經成為App開發的核心,而Amazon的AWS(Amazon Web Services是開發者常用的平台,可以幫助開發者建立、整合和擴展App。
    Thumbnail
    支援Go所有的類型儲存,且可以用原生SQL敘述與跨資料庫查詢。 映射關係 table->struct record->object field->attribute 安裝 go get github.com/astaxie/beego/orm​ go get github.com
    ※ Express 專案步驟筆記清單 Node.js 環境建置核對 新增專案資料夾 設定 package.json npm init -y 設定程式入口為 app.js 安裝 Express:npm install express 設定主程式 app.js 建構應用程式伺服器 設定
    Thumbnail
    gRPC是一款跨平台、高性能的RPC框架,他可以在任何環境下執行,主要用於後端為服務開發。在用戶端應用程式中,可以像本地物件那樣呼叫遠端伺服器的方法,因此可以創建出分散式應用。 使用 到https://github.com/protocolbuffers/protobuf/releases下
    Thumbnail
    Request內容 package main import ( "fmt" "log" "net/http" "strings" ) func request(w http.ResponseWriter, r *http.Request) { //這些資訊是輸出到伺服器端的列印訊息