假設我們希望在每個 GraphQL 回應中包含唯一的請求識別碼。
我們可以透過向查詢類型添加 requestId 字段,然後將該字段解析為我們在每個請求的上下文中設置的某個唯一標識符來實現這一點。但這不是一個完美的解決方案,因為我們必須在客戶端的每個請求中包含該字段,並且它會稍微增加發送到伺服器的請求的大小。
有更好的方法!
我們可以建立一個小插件(中間件),將我們的自訂資料附加到回應正文的擴充欄位。
根據「建立 Apollo 伺服器外掛」文件頁面告訴我們的內容,我們的外掛程式應如下所示:
// extensionsPlugin.js export const extensionsPlugin = () => { return { requestDidStart: () => { return { willSendResponse(requestContext) { requestContext.response.body.singleResult = { ...requestContext.response.body.singleResult, extensions: { ...requestContext.response.body?.extensions, requestId: requestContext.contextValue.requestId }, }; }, } } } };
隨意使用console.log(requestContent.response)來了解資料的結構。
請記住,只有 body.singleResult 的擴充鍵可以開箱即用,因為它是 GraphQL 標準的一部分。我們無法將 requestId 直接加入到 body.singleResult。
現在我們只需實作它即可!
此範例使用 ulid 套件來產生緊湊且可按時間排序的 ID。
// main.js import { ulid } from 'ulid'; import { extensionsPlugin } from "./extensionsPlugin.js"; // ... const server = new ApolloServer({ // ... plugins: [extensionsPlugin()], // ... }) const { url } = await startStandaloneServer(server, { // ... context: async () => { // ... const requestId = ulid(); return { requestId, } }, // ... })
就是這樣!
為什麼它有效?上下文是為每個請求單獨建構的(上下文),並且始終可供處理該請求的所有解析器使用。最好在上下文中設定所有需要的變量,因為它是在觸發任何插件掛鉤之前創建的(例如:requestDidStart)。我們將 requestId 添加到我們的上下文中並使其在任何地方都可用,然後我們的插件從上下文中提取它並在發送回之前將其附加到響應正文。
知道我們還可以在我們的回覆中附加什麼內容嗎?請在評論中分享:)
以上是如何將額外資料附加到 Apollo Server 上的 GraphQL 回應的詳細內容。更多資訊請關注PHP中文網其他相關文章!