Embed SDK 소개

Looker의 Embed SDK는 웹 앱의 내장 대시보드, Look, Explore를 관리하기 위해 브라우저 기반 웹 애플리케이션의 코드에 추가할 수 있는 함수 라이브러리입니다. Embed SDK는 다음과 같은 방식으로 임베딩을 용이하게 해줍니다.

  • 수동으로 HTML 요소를 만들 필요 없이 삽입된 콘텐츠의 캡슐화 제공
  • 교차 프레임 통신이 없도록 지점 간 통신 제공 Embed SDK는 전용 메시지 채널을 사용하여 호스트 웹페이지와 삽입된 Looker 콘텐츠 간의 교차 도메인 메시지를 전달합니다.

Embed SDK가 없으면 dashboard:run:start 또는 page:changed와 같은 자바스크립트 이벤트를 사용하여 삽입된 Looker 콘텐츠의 이벤트를 호출하거나 응답할 수 있습니다. 이는 삽입된 자바스크립트 이벤트 문서 페이지에 설명되어 있습니다. 자바스크립트 이벤트로 Looker 콘텐츠를 삽입하는 개발자는 삽입된 콘텐츠를 저장할 HTML 요소를 만들고 웹 앱과 삽입된 콘텐츠 간의 통신을 위해 창 브로드캐스트 이벤트를 사용해야 합니다.

Looker Embed SDK는 Looker API 및 Looker API SDK와 다릅니다.

  • Looker Embed SDK는 웹 애플리케이션의 클라이언트 측 코드에 상주하며 Looker 삽입 컨텍스트와 콘텐츠를 관리합니다. (Embed SDK는 Looker API에 대한 액세스를 제공하지 않습니다.)
  • Looker API는 Looker 인스턴스와 함께 서버에 상주하며 Looker 서버에서 명령어를 실행합니다.
  • Looker API 클라이언트 SDK는 Looker API 함수에 쉽게 액세스할 수 있도록 브라우저 외의 애플리케이션 코드에 상주합니다.

Looker는 브라우저에서 이벤트를 웹 애플리케이션으로 전달하는 순서를 제어하지 않습니다. 즉, 여러 브라우저 또는 플랫폼에서 이벤트 순서가 보장되지 않습니다. 여러 브라우저의 이벤트 처리를 고려하여 자바스크립트를 적절히 작성해야 합니다.

간단한 예시

이 예시에서는 Looker 삽입 컨텍스트를 구성하여 ID가 dashboard인 DOM 요소에 삽입한 후 ID가 11인 Looker 삽입 컨텍스트에 대시보드를 표시합니다. dashboard:run:startdashboard:run:complete 이벤트는 임베딩 창의 UI 상태를 업데이트하는 데 사용되며 ID가 run인 버튼이 스크립팅되어 대시보드에 dashboard:run 메시지를 보냅니다.

LookerEmbedSDK.init('looker.example.com', '/auth')

const setupDashboard = (dashboard) => {
  document.querySelector('#run').addEventListener('click', () => {
    dashboard.send('dashboard:run')
  })
}

LookerEmbedSDK.createDashboardWithId(11)
  .appendTo('#dashboard')
  .on('dashboard:run:start',
      () => updateState('#dashboard-state', 'Running')
  )
  .on('dashboard:run:complete',
      () => updateState('#dashboard-state', 'Done')
  )
  .build()
  .connect()
  .then(setupDashboard)
  .catch((error: Error) => {
    console.error('An unexpected error occurred', error)
  })

더 자세한 예시는 Embed SDK 데모 문서 페이지를 참조하세요.

Looker Embed SDK 설정

Looker Embed SDK는 유연한 인터페이스 패턴을 사용합니다. Embed SDK를 설치하면 삽입된 콘텐츠를 구성하고 삽입된 콘텐츠에 연결합니다.

Embed SDK 설치

https://www.npmjs.com/package/@looker/embed-sdk에서 노드 패키지 관리자(NPM)를 통해 Looker의 Embed SDK 라이브러리를 가져올 수 있습니다. 그러나 샘플 코드 또는 데모를 보려면 대신 Looker Embed SDK 저장소를 사용해야 합니다.

Looker Embed SDK 저장소를 사용하여 Looker Embed SDK를 설치하려면 다음 안내를 따르세요.

  1. Node.js가 아직 설치되어 있지 않으면 설치합니다.
  2. /looker-open-source/embed-sdk 저장소를 다운로드하거나 클론합니다.
  3. 터미널 창에서 /embed-sdk 디렉터리로 이동하여 다음 명령어를 실행합니다.
npm install
npm start

삽입된 콘텐츠 구성

먼저 웹 서버의 주소와 인증을 수행할 서버의 엔드포인트(선택사항)로 SDK를 초기화합니다. 이는 삽입된 모든 콘텐츠에서 사용됩니다.

브라우저 클라이언트에서 Looker 서버에 연결하는 데 필요한 경우 포트 번호를 포함합니다. 예: looker.example.com:443

LookerEmbedSDK.init('looker.example.com', '/auth')

그런 다음 삽입된 콘텐츠가 매개변수 정의를 위한 일련의 단계를 통해 빌드됩니다. 이러한 매개변수 중 일부는 선택사항이며, 일부는 필수 항목입니다.

이 프로세스는 대시보드 id 또는 대시보드(서명된 삽입 문서 페이지에 설명된 프로세스에 의해 생성됨)를 참조하는 url로 빌더를 만드는 것으로 시작됩니다.

LookerEmbedSDK.createDashboardWithId(id)

또는

LookerEmbedSDK.createDashboardWithUrl(url)

그런 다음 빌더에 속성을 추가하여 설정을 완료합니다. 예를 들어 웹페이지에 Looker 삽입 UI를 삽입할 위치를 지정할 수 있습니다. 다음 호출은 Looker 삽입 UI를 ID 값이 dashboard인 HTML 요소 내에 배치합니다.

.appendTo('#dashboard')

다음과 같이 이벤트 핸들러를 추가할 수 있습니다.

.on('dashboard:run:start',
  () => updateState('#dashboard-state', 'Running')
)
.on('dashboard:run:complete',
  () => updateState('#dashboard-state', 'Done')
)

삽입된 요소를 빌드하여 완료합니다.

.build()

삽입된 콘텐츠에 연결

삽입된 요소에서 메시지를 송수신하려면 connect()를 호출해야 합니다. 그러면 지정된 요소의 통신 인터페이스로 확인되는 프로미스가 반환됩니다.

.connect()
.then(setupDashboard)
.catch(console.error)

SDK용 URL 빌드

Looker 서명된 삽입 URL의 기본 문서는 서명된 삽입 문서 페이지에 있습니다. SDK URL을 만들 때 유일한 차이점은 필터 및 sdk=2 매개변수와 같은 다른 매개변수와 함께 embed_domain 매개변수를 삽입 URL에 추가해야 한다는 점입니다. 이 매개변수를 사용하면 Looker에서 SDK가 있는지 확인하고 SDK에서 제공하는 추가 기능을 활용할 수 있습니다. 예를 들면 다음과 같습니다.

/embed/looks/4?embed_domain=https://mywebsite.com&sdk=2
                                                 ^^^^^^

이 매개변수는 서명된 삽입 URL의 일부이므로 SDK는 이 매개변수 자체를 추가할 수 없습니다.

인증 엔드포인트

삽입 보안 비밀은 신중하게 보호되어야 하므로 브라우저에서 서명된 삽입 URL을 만들 수 없습니다. 이 프로세스를 더 쉽고 안전하게 수행하려면 다음 단계를 따르세요.

  1. 웹 서버에서 URL 서명 함수를 구현합니다. 서버는 Looker 삽입 SSO 예시 GitHub 저장소에 문서화된 프로세스 중 하나를 사용하여 서명된 URL을 반환해야 합니다.
  2. 삽입 SDK의 서명 엔드포인트에 서명된 삽입 URL을 전달합니다. 엔드포인트 위치는 LookerEmbedSDK.init()authUrl 매개변수로 지정됩니다.

이 위치를 지정하면 삽입 요소가 ID만 사용하여 생성될 때마다 삽입 URL은 요소의 유형, 제공된 Looker 호스트, 제공된 매개변수를 사용하여 생성됩니다. 예를 들면 다음과 같습니다.

LookerEmbedSDK.init('looker.example.com', '/looker_auth')
LookerEmbedSDK.createcreateDashboardWithId(11)
  .build()

그러면 /looker_auth 엔드포인트가 호출되고 삽입된 콘텐츠를 만드는 데 사용할 수 있는 서명된 삽입 URL이 반환됩니다.

src=https://looker.example.com/embed/dashboards/11?sdk=2&embed_host=https://yourhost.example.com

고급 인증 구성

커스텀 요청 헤더와 CORS 지원을 허용하도록 인증 엔드포인트를 추가로 구성할 수 있습니다. 다음과 같이 옵션 객체를 init 메서드에 전달하면 됩니다.


LookerEmbedSDK.init('looker.example.com',
  {
    url: 'https://api.acme.com/looker/auth',
    headers: [{'name': 'Foo Header', 'value': 'Foo'}],
    params: [{'name': 'foo', 'value': 'bar'}],
    withCredentials: true // Needed for CORS requests to Auth endpoint include Http Only cookie headers
  })

노드 도우미

서명 도우미 메서드 createSignedUrl()server_utils/auth_utils.ts에 제공됩니다. 사용법은 다음과 같습니다.

import { createSignedUrl } from './auth_utils'

app.get('/looker_auth', function(req, res) {
  // TO DO: Add your code here to authenticate that the request is from a valid user
  const src = req.query.src;
  const host = 'https://looker.example.com'
  const secret = YOUR_EMBED_SECRET
  const user = authenticatedUser
  const url = createSignedUrl(src, user, host, secret);
  res.json({ url });
});

다음은 사용자 데이터 구조입니다.

interface LookerEmbedUser {
  external_user_id: string
  first_name?: string
  last_name?: string
  session_length: number
  force_logout_login?: boolean,
  permissions: LookerUserPermission[]
  models: string[]
  group_ids?: number[]
  external_group_id?: string
  user_attributes?: {[key: string]: any}
  access_filters: {}
}

Looker 3.10에서는 access_filters 매개변수가 삭제되었지만 삽입 URL에 빈 자리표시자가 있어야 합니다.

문제 해결

로깅

Embed SDK는 chatty를 기반으로 빌드됩니다. Chatty는 로깅에 디버그를 사용합니다. 다음 명령어를 사용하여 브라우저 콘솔에서 로깅을 사용 설정할 수 있습니다.

localStorage.debug = 'looker:chatty:*'
```none

Note that both the parent window and the embedded content have separate local storage, so you can enable logging on one, the other, or both. You can disable logging with this command:

```javascript
localStorage.debug = ''