A incorporação de conteúdo do Looker através de iFrames é apenas um dos métodos que os programadores podem usar quando querem adicionar um painel de controlo, um Look ou uma exploração à respetiva aplicação Web. Este tutorial apresenta outro método para os programadores que querem adicionar uma visualização do Looker a uma app React. Este tutorial baseia-se num iniciador da app Create React e usa componentes de visualização do Looker.
Estes são os passos abordados neste tutorial:
- Obtenha o slug da consulta do Looker
- Crie uma aplicação React com componentes de visualização do Looker
- Crie um serviço auxiliar de back-end
- Inicie o servidor e a app React
Obtenha o slug da consulta a partir do Looker
Existem algumas ações que têm de ser realizadas no Looker, uma vez que a app React depende delas.
Obtenha um slug de consulta
Precisa do ID ou do slug da consulta que vai ser usado como uma propriedade do componente de visualização. Este artigo explica como pode obter o slug da consulta a partir de um URL de exploração.
Configure o CORS na sua instância do Looker
A partilha de recursos de origem cruzada (CORS) é controlada pela mesma lista de autorizações de domínios que a incorporação.
Isto está documentado mais detalhadamente na página de documentação Incorporação assinada.
- Navegue para Administração > Incorporação de plataformas na sua instância do Looker. Esta ação requer privilégios de administrador.
- A app React é executada por predefinição em
http://localhost:3000
. Ao adicionar este endereço à lista de autorizações de domínios incorporados, está a indicar ao Looker que permita pedidos da app e responda a esses pedidos com o mesmo endereço. Este passo é obrigatório, uma vez que a app vai fazer pedidos de API à instância do Looker. Caso contrário, não haverá comunicação entre o Looker e a app.
Crie a aplicação React
O front-end desta demonstração usa o Create React App para criar a aplicação React de página única. Execute os seguintes comandos na pasta raiz da demonstração (get-started-viz-components
) para criar a app e instalar as dependências:
npx create-react-app frontend-react cd frontend-react npm i
@looker/visualizations npm i @looker/components @looker/components-data
styled-components
Depois de executar estes comandos, a estrutura de pastas deve ter o seguinte aspeto:
Verifique o ficheiro package.json
e certifique-se de que react-dom
também está instalado. Caso contrário, instale-o executando npm i react-dom
.
O package.json
desta demonstração tem o seguinte aspeto:
{
"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"
]
}
}
Configure as variáveis de ambiente
Crie um ficheiro .env
no diretório raiz da app (./frontend-react
) e defina as seguintes variáveis:
REACT_APP_LOOKER_API_HOST=https://your-looker-instance.looker.com
REACT_APP_BACKEND_SERVER=http://localhost:3001/
REACT_APP_BACKEND_SERVER
é o endereço do serviço auxiliar de back-end que vamos usar para fazer uma chamada à API do Looker para extrair o token de acesso.
REACT_APP_LOOKER_API_HOST
é o endereço da instância do Looker que vai receber pedidos de API da app React.
Inicialize o SDK do lado do cliente
A app React usa o SDK para fazer pedidos de API ao servidor do Looker. Uma vez que isto é feito no front-end, pode usar o seguinte auxiliar para inicializar o 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)
Incorpore a visualização na app
Agora que tem o slug da consulta (no nosso exemplo, é Jlm4YHPeT3lLGA9UtHjZcA
) da visualização e o objeto sdk
foi instanciado, o passo seguinte é usar os componentes de visualização do Looker para incorporar e renderizar a visualização na app:
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
A parte frontal está pronta. Pode adicionar mais componentes, adicionar mais estilos à app, etc.
Crie um serviço auxiliar de back-end
O passo final é criar o serviço auxiliar de back-end que vai receber a chamada do front-end, usar o SDK do Looker-Node para autenticar o utilizador, extrair o respetivo token de acesso e, em seguida, enviá-lo de volta para o front-end.
Para simplificar, vamos criar um servidor Node com um ponto final. O servidor vai usar as dependências express
, cors
e @looker/sdk-node
. Pode executar os seguintes comandos a partir da pasta de raiz (get-started-viz-components
):
mkdir backend-node
cd backend-node
npm init -y
npm i express cors @looker/sdk-node
Para autenticar o SDK a partir do back-end, vamos usar um ficheiro looker.ini
. Pode encontrar mais detalhes sobre como preencher o ficheiro na página do SDK-Node. Depois de executar estes comandos, a estrutura de pastas deve ter o seguinte aspeto:
O elemento package.json
deve ter o seguinte aspeto:
{
"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"
}
}
Em seguida, adicionamos este código a um novo ficheiro 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}`)
})
Inicie o servidor e a app React
- Abra um terminal, navegue até à pasta
backend-node
e, em seguida, executenpm start
- Abra um segundo terminal, navegue para a pasta
frontend-react
e executenpm start
- Assim que o serviço auxiliar de back-end e a app React estiverem em funcionamento, pode abrir o navegador e aceder a
http://localhost:3000/
para ver a visualização incorporada na aplicação.