開始使用 Looker 示意圖元件

開發人員想在網頁應用程式中新增資訊主頁、Look 或「探索」時,可以使用 iframe 嵌入 Looker 內容,這只是其中一種方法。本教學課程將為開發人員介紹另一種方法,協助他們在 React 應用程式中加入 Looker 視覺化效果。本教學課程以 Create React App 啟動器為基礎,並使用 Looker 視覺化元件

本教學課程涵蓋的步驟如下:

  1. 從 Looker 取得查詢代碼
  2. 使用 Looker 視覺化元件建立 React 應用程式
  3. 建立後端輔助服務
  4. 啟動伺服器和 React 應用程式

從 Looker 取得查詢 slug

由於 React 應用程式依附於 Looker,因此必須在 Looker 中完成幾件事。

取得查詢 Slug

您需要查詢 ID 或 slug,做為視覺化元件的屬性。本文說明如何從「探索」網址取得查詢 Slug

在 Looker 執行個體中設定 CORS

跨源資源共享 (CORS) 與嵌入功能受同一個網域允許清單控管。

如需詳細說明,請參閱「已簽署的嵌入」說明文件頁面。

  1. 在 Looker 執行個體中,依序前往「管理」>「平台嵌入」。這項操作需要管理員權限。
  2. React 應用程式預設會在 http://localhost:3000 執行。將這個地址新增至「內嵌網域允許清單」,即表示允許 Looker 接收來自該應用程式的要求,並使用相同地址回應這些要求。這是必要步驟,因為應用程式會向 Looker 執行個體發出 API 要求,否則 Looker 和應用程式之間無法通訊。

建立 React 應用程式

這個示範應用程式的前端使用 Create React App 建立單頁 React 應用程式。在試用版 (get-started-viz-components) 的根資料夾中執行下列指令,建立應用程式並安裝依附元件:

npx create-react-app frontend-react cd frontend-react npm i
@looker/visualizations npm i @looker/components @looker/components-data
styled-components

執行這些指令後,資料夾結構應如下所示:

名為「Frontend react」的資料夾,內含 Node 模組、Public 和 src 資料夾,以及 call .gitignore、package-lock.json 和 package.json 檔案。

檢查 package.json 檔案,確認已安裝 react-dom,否則請執行 npm i react-dom 安裝。

這個範例的 package.json 如下所示:

{
  "name": "frontend-react",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@looker/components": "^4.0.3",
    "@looker/components-data": "^1.0.0",
    "@looker/sdk": "^22.16.0",
    "@looker/sdk-rtl": "^21.4.0",
    "@looker/visualizations": "^1.1.1",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^12.1.0",
    "@testing-library/user-event": "^12.4.0",
    "i": "^0.3.7",
    "npm": "^8.19.2",
    "react": "^16.14.0",
    "react-dom": "^16.14.0",
    "react-scripts": "5.0.1",
    "styled-components": "^5.3.6",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

設定環境變數

在應用程式的根目錄 (./frontend-react) 中建立 .env 檔案,並設定下列變數:

REACT_APP_LOOKER_API_HOST=https://your-looker-instance.looker.com
REACT_APP_BACKEND_SERVER=http://localhost:3001/

REACT_APP_BACKEND_SERVER 是後端輔助服務的位址,我們會使用這個服務向 Looker 發出 API 呼叫,以擷取存取權杖。

REACT_APP_LOOKER_API_HOST 是 Looker 執行個體的位址,該執行個體會接收來自 React 應用程式的 API 要求。

初始化用戶端 SDK

React 應用程式會使用 SDK 向 Looker 伺服器發出 API 請求。由於這項作業是在前端完成,因此您可以使用下列輔助程式初始化 sdk

import { Looker40SDK } from '@looker/sdk'
import {
  AuthToken,
  AuthSession,
  BrowserTransport,
  DefaultSettings,
} from '@looker/sdk-rtl'

class SDKSession extends AuthSession {
  // This is a placeholder for the fetchToken function.
  // It is modified to make it useful later.
  async fetchToken() {
    return fetch('')
  }

  activeToken = new AuthToken()
  constructor(settings, transport) {
    super(settings, transport || new BrowserTransport(settings))
  }

  // This function checks to see if the user is already authenticated
  isAuthenticated() {
    const token = this.activeToken
    if (!(token && token.access_token)) return false
    return token.isActive()
  }

  // This function gets the current token or fetches a new one if necessary
  async getToken() {
    if (!this.isAuthenticated()) {
      const token = await this.fetchToken()
      const res = await token.json()
      this.activeToken.setToken(res.user_token)
    }
    return this.activeToken
  }

  // This function authenticates a user, which involves getting a new token
  // It returns a modified object with a new authorization header.
  async authenticate(props) {
    const token = await this.getToken()
    if (token && token.access_token) {
      props.mode = 'cors'
      delete props.credentials
      props.headers = {
        ...props.headers,
        Authorization: `Bearer ${this.activeToken.access_token}`,
      }
    }
    return props
  }
}

// This class sets the fetchToken to use the 'real' address of the backend server.
class SDKSessionEmbed extends SDKSession {
  async fetchToken() {
    return fetch(`${process.env.REACT_APP_BACKEND_SERVER}`)
  }
}

// This creates a new session with the 'real' address of the backend server.
const session = new SDKSessionEmbed({
  ...DefaultSettings,
  base_url: process.env.REACT_APP_LOOKER_API_HOST,
})

// This exports the SDK with the authenticated session
export const sdk = new Looker40SDK(session)

將視覺化效果嵌入應用程式

現在您已取得視覺化內容的查詢 Slug (在本例中為 Jlm4YHPeT3lLGA9UtHjZcA),且 sdk 物件已例項化,下一步是使用 Looker 視覺化元件,將視覺化內容嵌入並算繪至應用程式:

import { sdk } from '../src/helpers/CorsSession'
import { Query, Visualization } from '@looker/visualizations'
import { DataProvider } from '@looker/components-data'
import { ComponentsProvider } from '@looker/components'

function App() {
  return (
    <>
      <h1>Get started with Looker visualization components</h1>
      <ComponentsProvider>
        <DataProvider sdk={sdk}>
          {/* Change this query slug to match your query slug */}
          <Query query="Jlm4YHPeT3lLGA9UtHjZcA">
            <Visualization />
          </Query>
        </DataProvider>
      </ComponentsProvider>
    </>
  )
}

export default App

前端已準備就緒。您可以新增更多元件、為應用程式新增更多樣式等。

建立後端輔助服務

最後一個步驟是建構後端輔助服務,接收前端的呼叫、使用 Looker-Node SDK 驗證使用者、擷取存取權杖,然後傳回前端。

為簡化作業,我們將建立一個具有單一端點的 Node 伺服器。伺服器會使用 expresscors@looker/sdk-node 依附元件。您可以從根資料夾 (get-started-viz-components) 開始執行下列指令:

mkdir backend-node
cd backend-node
npm init -y
npm i express cors @looker/sdk-node

如要從後端驗證 SDK,請使用 looker.ini 檔案。如要進一步瞭解如何填入檔案,請參閱 SDK-Node 頁面。執行這些指令後,資料夾結構應如下所示:

名為 backend-node 的資料夾,內含名為 node_modules 的資料夾,以及 looker.ini、package-lock.json、package.json 和 server.js 檔案。

package.json 應如下所示:

{
  "name": "looker-embed-backend",
  "version": "1.0.0",
  "description": "Backend helper service for getting started with Looker Viz components",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "author": "Looker",
  "license": "Apache-2.0",
  "dependencies": {
    "@looker/sdk-node": "^22.16.0",
    "cors": "^2.8.5",
    "express": "^4.18.2"
  }
}

接著,我們會在新的 server.js 檔案中加入這段程式碼:

const cors = require('cors')
const express = require('express')
const { LookerNodeSDK } = require('@looker/sdk-node')

const port = 3001
const app = express()
// The following init40 method will authenticate using
// the looker.ini file
const sdk = LookerNodeSDK.init40()

app.use(
  cors({
    origin: '*',
  })
)
app.use(express.json())

app.get('/', async (req, res) => {
  const userId = await sdk.ok(sdk.me('id'))
  const accessToken = await sdk.login_user(userId.id)
  const user = {
    user_token: accessToken.value,
    token_last_refreshed: Date.now(),
  }
  res.json({ ...user })
})

app.listen(port, async () => {
  console.log(`Backend Server listening on port ${port}`)
})

啟動伺服器和 React 應用程式

  • 開啟終端機並前往 backend-node 資料夾,然後執行 npm start
  • 開啟第二個終端機,然後前往 frontend-react 資料夾並執行 npm start
  • 後端輔助服務和 React 應用程式啟動並執行後,您就可以開啟瀏覽器並前往 http://localhost:3000/,查看嵌入應用程式的視覺化內容。

在 GitHub 中查看程式碼