Comienza a usar los componentes de visualización de Looker

La incorporación de contenido de Looker con iframes es solo uno de los métodos que los desarrolladores pueden usar cuando quieran agregar un panel, una Vista o una Exploración a su aplicación web. En este instructivo, se presenta otro método para desarrolladores que quieren agregar una visualización de Looker a una app de React. Este instructivo se basa en un activador Crear app de React y usa componentes de visualización de Looker.

Estos son los pasos que se abordan en este instructivo:

  1. Obtén el slug de consulta de Looker
  2. Crea una aplicación de React con los componentes de visualización de Looker
  3. Crea un servicio de asistencia de backend
  4. Inicia el servidor y la app de React

Obtén el slug de consulta de Looker

Hay algunas cosas que se deben hacer en Looker, ya que la app de React depende de ellas.

Obtén un slug de consulta

Necesitas el ID de consulta o slug que se usará como propiedad del componente de visualización. En este artículo, se explica cómo obtener el slug de búsqueda de una URL de Explorar. Puedes encontrar otro ejemplo en la documentación de Looker.

Configura CORS en tu instancia de Looker

El uso compartido de recursos entre dominios (CORS) está controlado por la misma lista de entidades permitidas del dominio que la incorporación.

Esto se documenta con más detalle en la página de documentación Incorporación firmada.

  1. Ve a Administrador > Incorporación de plataformas en tu instancia de Looker. Esto requiere privilegios de administrador.
  2. La app de React se ejecuta de forma predeterminada en http://localhost:3000. Cuando agregas esta dirección a la lista de entidades permitidas del dominio incorporado, le indicas a Looker que permita las solicitudes de la app y las responda con la misma dirección. Este paso es obligatorio, ya que la app enviará solicitudes a la API a la instancia de Looker; de lo contrario, no habrá comunicación entre Looker y la app.

Crea la aplicación de React

El frontend de esta demostración usa la opción Crear app de React para crear la app de React de una sola página. Ejecuta los siguientes comandos en la carpeta raíz de la demostración (get-started-viz-components) para crear la app y, luego, instalar las dependencias:

npx create-react-app frontend-react cd frontend-react npm i
@looker/visualizations npm i @looker/components @looker/components-data
styled-components

Después de ejecutar estos comandos, la estructura de las carpetas debería verse así:

Una carpeta llamada Frontend reacciona, que contiene las carpetas Node, Modules, Public y src, y los archivos llaman a .gitignore, package-lock.json y package.json.

Verifica el archivo package.json y asegúrate de que react-dom también esté instalado. De lo contrario, ejecuta npm i react-dom para instalarlo.

El package.json de esta demostración se ve así:

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

Configura las variables de entorno

Crea un archivo .env en el directorio raíz de la app (./frontend-react) y configura las siguientes variables:

REACT_APP_LOOKER_API_HOST=https://your-looker-instance.looker.com
REACT_APP_BACKEND_SERVER=http://localhost:3001/

REACT_APP_BACKEND_SERVER es la dirección del servicio auxiliar de backend que usaremos para realizar una llamada a la API a Looker y extraer el token de acceso.

REACT_APP_LOOKER_API_HOST es la dirección de la instancia de Looker que recibirá las solicitudes a la API de la app de React.

Inicializa el SDK del cliente

La app de React usará el SDK para realizar solicitudes a la API al servidor de Looker. Como esto se hace en el frontend, puedes usar el siguiente ayudante para inicializar 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)

Incorpora la visualización en la app

Ahora que tienes el slug de consulta (en nuestro ejemplo es Jlm4YHPeT3lLGA9UtHjZcA) de la visualización y se creó una instancia del objeto sdk, el siguiente paso es usar los componentes de visualización de Looker para incorporar y renderizar la visualización en la 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

El frontend está listo. Puedes agregar más componentes, darle más estilo a la app, etcétera.

Crea un servicio auxiliar de backend

El último paso es compilar el servicio auxiliar de backend que recibirá la llamada del frontend, usar el SDK de Looker-Node para autenticar al usuario, extraer su token de acceso y, luego, enviarlo de vuelta al frontend.

Para simplificar, vamos a compilar un servidor de nodo con un extremo. El servidor usará dependencias express, cors y @looker/sdk-node. Puedes ejecutar los siguientes comandos a partir de la carpeta raíz (get-started-viz-components):

mkdir backend-node
cd backend-node
npm init -y
npm i express cors @looker/sdk-node

Para autenticar el SDK desde el backend, usaremos un archivo looker.ini. Puedes encontrar más detalles sobre cómo propagar el archivo en la página SDK-Node. Después de ejecutar estos comandos, la estructura de las carpetas debería verse así:

Una carpeta llamada backend-node, que contiene una carpeta llamada node_modules y los archivos looker.ini, package-lock.json, package.json y server.js.

package.json debería verse de la siguiente manera:

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

A continuación, agregaremos este código a un nuevo archivo 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}`)
})

Inicia el servidor y la app de React

  • Abre una terminal, navega a la carpeta backend-node y, luego, ejecuta npm start
  • Abre una segunda terminal, navega a la carpeta frontend-react y ejecuta npm start
  • Una vez que el servicio auxiliar de backend y la app de React estén en funcionamiento, puedes abrir el navegador y dirigirte a http://localhost:3000/ para ver la visualización incorporada en la aplicación.

Consultar el código en GitHub