当开发者想要向其 Web 应用添加信息中心、探索或 Look 时,使用 iframe 嵌入 Looker 内容只是其中一种方法。本教程介绍了另一种方法,供想要将 Looker 可视化图表添加到 React 应用中的开发者使用。本教程基于 Create React App 起始项目,并使用 Looker 可视化组件。
本教程将介绍以下步骤:
从 Looker 获取查询 slug
由于 React 应用依赖于这些设置,因此必须在 Looker 中完成一些操作。
获取查询 slug
您需要查询 ID 或 Slug,它们将用作可视化组件的属性。本文介绍了如何从探索网址中获取查询标记。如需查看另一个示例,请参阅 Looker 文档。
在 Looker 实例中配置 CORS
跨域资源共享 (CORS) 与嵌入服务由同一网域许可名单控制。
如需了解详情,请参阅签名嵌入文档页面。
- 在您的 Looker 实例中,依次前往管理 > 平台嵌入。这需要管理员权限。
- 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
运行这些命令后,您的文件夹结构应如下所示:
检查 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
是将接收来自 React 应用的 API 请求的 Looker 实例的地址。
初始化客户端 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 服务器。服务器将使用 express
、cors
和 @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 页面。运行这些命令后,您的文件夹结构应如下所示:
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/
,查看嵌入到应用中的可视化结果。