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

Incorporar conteúdo do Looker usando iframes é apenas um dos métodos que os desenvolvedores podem usar para adicionar um dashboard, 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 em um aplicativo React. Este tutorial se baseia em uma ativação do Create React e usa componentes de visualização do Looker.

Estas são as etapas abordadas neste tutorial:

  1. Extrair o slug de consulta do 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

Acessar o slug de consulta do Looker

Como o app React depende delas, algumas coisas precisam ser feitas no Looker.

Acessar 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 de consulta de um URL de exploração. Outro exemplo pode ser encontrado na documentação do Looker.

Configurar o CORS na 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á esta aparência:

Uma pasta chamada "Frontend reação", contendo as pastas "Módulos de nó", "Público" e "src", e os arquivos com as chamadas ".gitignore", "package-lock.json" e "package.json".

Verifique o arquivo package.json e confira se react-dom também está instalado. Caso contrário, execute npm i react-dom para instalá-lo.

O package.json dessa demonstração vai ficar assim:

{
  "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 será usado para fazer uma chamada de API ao Looker e extrair o token de acesso.

REACT_APP_LOOKER_API_HOST é o endereço da instância do Looker que receberá as 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 de consulta (no nosso exemplo é Jlm4YHPeT3lLGA9UtHjZcA) 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. Confira mais detalhes sobre como preencher o arquivo na página do nó do SDK. Depois de executar esses comandos, sua estrutura de pastas terá esta aparência:

Uma pasta chamada backend-node, contendo uma pasta chamada node_modules e os arquivos looker.ini, package-lock.json, package.json e server.js.

O 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.
  • Quando 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