Comece a usar os componentes de visualização do Looker

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:

  1. Obtenha o slug da consulta do Looker
  2. Crie uma aplicação React com componentes de visualização do Looker
  3. Crie um serviço auxiliar de back-end
  4. 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.

  1. Navegue para Administração > Incorporação de plataformas na sua instância do Looker. Esta ação requer privilégios de administrador.
  2. 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:

Uma pasta denominada Frontend react, que contém as pastas Node modules, Public e src, e os ficheiros .gitignore, package-lock.json e package.json.

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:

Uma pasta denominada backend-node, que contém uma pasta denominada node_modules e os ficheiros looker.ini, package-lock.json, package.json e server.js.

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, execute npm start
  • Abra um segundo terminal, navegue para a pasta frontend-react e execute npm 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.

Veja o código no GitHub