Introdução aos componentes de visualização do Looker

A incorporação de conteúdo do Looker usando iframes é apenas um dos métodos que os desenvolvedores podem usar para adicionar um painel, um Look ou uma Análise ao aplicativo da Web. Este tutorial apresenta outro método para desenvolvedores que querem adicionar uma visualização do Looker a um app React. Ele é baseado em um starter do Create React App e usa componentes de visualização do Looker.

Estas são as etapas abordadas neste tutorial:

  1. Conseguir o slug da consulta no Looker
  2. Criar um aplicativo React com componentes de visualização do Looker
  3. Criar um serviço auxiliar de back-end
  4. Iniciar o servidor e o app React

Conseguir o slug da consulta do Looker

Há algumas coisas que precisam ser feitas no Looker, já que o app React depende delas.

Conseguir um slug de consulta

Você precisa do ID da consulta ou do slug que será usado como propriedade do componente de visualização. Este artigo explica como conseguir o slug da consulta de um URL da seção "Explorar". Outro exemplo pode ser encontrado na documentação do Looker.

Configurar o CORS na sua instância do Looker

O compartilhamento de recursos entre origens (CORS) é controlado pela mesma lista de permissões de domínio que a incorporação.

Isso é documentado com mais detalhes na página de documentação Incorporação assinada.

  1. Acesse Administrador > Incorporação da plataforma na sua instância do Looker. Isso exige privilégios de administrador.
  2. O app React é executado por padrão em http://localhost:3000. Ao adicionar esse endereço à Lista de permissões do domínio incorporado, você está informando ao Looker para permitir solicitações do app e respondê-las usando o mesmo endereço. Essa etapa é obrigatória porque o app vai fazer solicitações de API à instância do Looker. Caso contrário, não haverá comunicação entre o Looker e o app.

Criar o aplicativo React

O front-end desta demonstração usa o Create React App para criar o aplicativo React de página única. Execute os comandos abaixo na pasta raiz da demonstração (get-started-viz-components) para criar o 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 esses comandos, sua estrutura de pastas terá a seguinte aparência:

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

Verifique o arquivo package.json e confirme se o react-dom também está instalado. Caso contrário, instale-o executando npm i react-dom.

O package.json desta demonstração tem esta aparência:

{
  "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"
    ]
  }
}

Configurar as variáveis de ambiente

Crie um arquivo .env no diretório raiz do 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 usaremos para fazer uma chamada de API ao Looker para extrair o token de acesso.

REACT_APP_LOOKER_API_HOST é o endereço da instância do Looker que vai receber solicitações de API do app React.

Inicializar o SDK do lado do cliente

O app React vai usar o SDK para fazer solicitações de API ao servidor do Looker. Como isso é feito no front-end, você 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)

Incorporar a visualização ao app

Agora que você tem o slug da consulta (Jlm4YHPeT3lLGA9UtHjZcA no nosso exemplo) da visualização e o objeto sdk foi instanciado, a próxima etapa é usar os componentes de visualização do Looker para incorporar e renderizar a visualização no 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

O front-end está pronto. Você pode adicionar mais componentes, adicionar mais estilo ao app etc.

Criar um serviço auxiliar de back-end

A etapa final é criar o serviço auxiliar de back-end que vai receber a chamada do front-end. Usar o SDK do nó do Looker para autenticar o usuário, extrair o token de acesso e enviar de volta ao front-end.

Para simplificar, vamos criar um servidor Node com um endpoint. O servidor vai usar as dependências express, cors e @looker/sdk-node. É possível executar os seguintes comandos a partir da pasta 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 no back-end, vamos usar um arquivo looker.ini. Saiba mais sobre como preencher o arquivo na página do SDK-Node. Depois de executar esses comandos, a estrutura de pastas vai ficar assim:

Uma pasta chamada &quot;backend-node&quot;, que contém uma pasta chamada &quot;node_modules&quot; e os arquivos looker.ini, package-lock.json, package.json e server.js.

A package.json vai ficar assim:

{
  "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, adicionaremos este código a um novo arquivo 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}`)
})

Iniciar o servidor e o aplicativo React

  • Abra um terminal, navegue até a pasta backend-node e execute npm start.
  • Abra um segundo terminal, navegue até a pasta frontend-react e execute npm start.
  • Depois que o serviço auxiliar de back-end e o app de reação estiverem em execução, abra o navegador e acesse http://localhost:3000/ para conferir a visualização incorporada ao aplicativo.

Conferir o código no GitHub