본문 바로가기
WIKI 기술 지식 베이스

Search 시작하기

원문 보기 위키 갱신

Backstage에 검색(Search) 기능을 추가하고 구성하는 방법을 설명하는 가이드예요.

출처: 문서

본문

:::info 이 문서는 새 Backstage 앱에서 기본값인 새 프론트엔드 시스템을 위해 작성됐어요. Backstage 앱이 여전히 이전 프론트엔드 시스템을 사용한다면 이 가이드의 이전 프론트엔드 시스템 버전을 읽으세요. :::

Search는 Backstage의 플러그인으로 동작하므로, Search를 사용하려면 Backstage를 사용해야 해요.

아직 Backstage를 설정하지 않았다면 여기에서 시작하세요.

프론트엔드에 Search 추가하기

Backstage 루트 디렉터리에서

yarn --cwd packages/app add @backstage/plugin-search @backstage/plugin-search-react

설치가 완료되면 검색 플러그인은 기본 기능 탐색(feature discovery)을 통해 앱에서 자동으로 사용할 수 있게 돼요. /search에 검색 페이지를 제공하고, 사이드바에 검색 네비게이션 항목을 제공하며, 사이드바에서 접근할 수 있는 검색 모달도 제공해요. 더 자세한 내용과 대체 설치 방법은 플러그인 설치 문서를 참고하세요.

검색 페이지 구성하기

검색 페이지는 app-config.yaml을 통해 구성할 수 있어요. 예를 들어 검색 결과 추적을 비활성화하려면 다음과 같이 해요.

app-config.yaml

app:  extensions:    - page:search:        config:          noTrack: true

검색 결과 목록 항목

검색 페이지는 설치된 플러그인이 제공하는 검색 결과 목록 항목 확장을 자동으로 발견하고 사용해요. 예를 들어 catalog 플러그인은 CatalogSearchResultListItem을 제공하고, TechDocs 플러그인은 TechDocsSearchResultListItem을 제공해요. 이들은 각각의 플러그인이 설치되면 자동으로 등록돼요.

@backstage/plugin-search-react/alpha의 SearchResultListItemBlueprint를 사용해 추가 검색 결과 목록 항목 확장을 설치할 수도 있어요.

검색 필터

마찬가지로 검색 필터 확장도 자동으로 발견돼요. @backstage/plugin-search-react/alpha의 SearchFilterBlueprint 또는 SearchFilterResultTypeBlueprint를 사용해 사용자 지정 필터를 추가할 수 있어요.

백엔드에 Search 추가하기

백엔드 앱에 다음 플러그인들을 추가해요.

Backstage 루트 디렉터리에서

yarn --cwd packages/backend add @backstage/plugin-search-backend @backstage/plugin-search-backend-module-pg @backstage/plugin-search-backend-module-catalog @backstage/plugin-search-backend-module-techdocs

그런 다음 다음 줄들을 추가해요.

packages/backend/src/index.ts

const backend = createBackend();// Other plugins...// search pluginbackend.add(import('@backstage/plugin-search-backend'));// search enginesbackend.add(import('@backstage/plugin-search-backend-module-pg'));// search collatorsbackend.add(import('@backstage/plugin-search-backend-module-catalog'));backend.add(import('@backstage/plugin-search-backend-module-techdocs'));backend.start();

위 설정으로 Search는 Lunr 인메모리 검색 엔진을 사용하지만, 데이터베이스로 Postgres를 설정했다면 Postgres를 검색 엔진으로 사용해요. 자세한 내용은 Search 엔진 문서를 참고하세요.

위 설정은 Catalog와 TechDocs 두 개의 콜레이터도 설정해 주며, 이 두 위치의 콘텐츠를 인덱싱해서 쉽게 검색할 수 있게 해줘요. 자세한 내용은 콜레이터 문서를 참고하세요.

Search 사용자 지정하기

프론트엔드

검색 플러그인은 블루프린트(blueprint)를 통해 검색 경험을 사용자 지정할 수 있는 확장 지점을 제공해요. 사용자 지정 검색 결과 목록 항목, 필터, 결과 유형 필터를 추가할 수 있어요.

예를 들어 사용자 지정 검색 결과 목록 항목을 만들려면 @backstage/plugin-search-react/alpha의 SearchResultListItemBlueprint를 사용해요.

import { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha';export const MySearchResultListItem = SearchResultListItemBlueprint.make({  name: 'my-result-item',  params: {    predicate: result => result.type === 'my-custom-type',    component: async () => {      const { MyResultItem } = await import('./components/MyResultItem');      return MyResultItem;    },  },});

이것을 프론트엔드 모듈로 감싸고 createApp에 전달해 앱에 설치해요.

packages/app/src/search/searchModule.ts

import { createFrontendModule } from '@backstage/frontend-plugin-api';import { MySearchResultListItem } from './MySearchResultListItem';export const searchCustomizations = createFrontendModule({  pluginId: 'search',  extensions: [MySearchResultListItem],});

packages/app/src/App.tsx

import { createApp } from '@backstage/frontend-defaults';import { searchCustomizations } from './search/searchModule';const app = createApp({  features: [searchCustomizations],});export default app.createRoot();

Search 프론트엔드를 더 고급으로 사용자 지정하려면 'Search API를 직접 구현하는 방법'이나 '검색 결과 하이라이팅 스타일을 사용자 지정하는 방법' 같은 how-to 가이드도 참고하세요.

백엔드

Backstage Search는 그 자체가 검색 엔진은 아니에요. 대신 Backstage 인스턴스와 선택한 검색 엔진 사이의 인터페이스를 제공해요. 현재는 인메모리 검색 엔진인 Lunr와 Elasticsearch 두 가지만 지원해요. 이들을 Backstage 인스턴스에서 구성하는 방법에 대한 자세한 내용은 Search 엔진 문서를 참고하세요.

Backstage Search는 무엇이든 검색하는 데 사용할 수 있어요! Catalog 같은 플러그인은 인덱싱할 문서를 제공하는 기본 콜레이터(예: DefaultCatalogCollator)를 제공하며, IndexBuilder에 원하는 만큼 콜레이터를 등록할 수 있어요.

const indexBuilder = new IndexBuilder({ logger: env.logger, searchEngine });const every10MinutesSchedule = env.scheduler.createScheduledTaskRunner({  frequency: { minutes: 10 },  timeout: { minutes: 15 },  initialDelay: { seconds: 3 },});const everyHourSchedule = env.scheduler.createScheduledTaskRunner({  frequency: { hours: 1 },  timeout: { minutes: 90 },  initialDelay: { seconds: 3 },});indexBuilder.addCollator({  schedule: every10MinutesSchedule,  factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {    discovery: env.discovery,    tokenManager: env.tokenManager,  }),});indexBuilder.addCollator({  schedule: everyHourSchedule,  factory: new MyCustomCollatorFactory(),});

Backstage Search는 예약(schedule)에 따라 인덱스를 구축하고 유지해요. 주어진 문서 유형에 대해 인덱스가 다시 구축되는 빈도를 변경할 수 있어요. 문서가 더 자주 또는 덜 자주 업데이트된다면 이렇게 하고 싶을 수 있어요. 이는 schedule 값에 전달할 예약된 SchedulerServiceTaskRunner를 구성해 처리할 수 있어요.

const every10MinutesSchedule = env.scheduler.createScheduledTaskRunner({  frequency: { minutes: 10 },  timeout: { minutes: 15 },  initialDelay: { seconds: 3 },});indexBuilder.addCollator({  schedule: every10MinutesSchedule,  factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {    discovery: env.discovery,    tokenManager: env.tokenManager,  }),});

:::note 인메모리 Lunr 검색 엔진을 사용한다면, 여러 검색 백엔드 노드를 실행할 때 일관성을 보장하기 위해 다음처럼 비분산(non-distributed) SchedulerServiceTaskRunner를 구현하고 싶을 거예요(또는 검색 플러그인이 SQLite 같은 비분산 데이터베이스를 사용하도록 구성할 수도 있어요). :::

import {  SchedulerServiceTaskRunner,  SchedulerServiceTaskInvocationDefinition,} from '@backstage/backend-plugin-api';const schedule: SchedulerServiceTaskRunner = {  run: async (task: SchedulerServiceTaskInvocationDefinition) => {    const startRefresh = async () => {      while (!task.signal?.aborted) {        try {          await task.fn(task.signal);        } catch {          // ignore intentionally        }        await new Promise(resolve => setTimeout(resolve, 600 * 1000));      }    };    startRefresh();  },};indexBuilder.addCollator({  schedule,  factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {    discovery: env.discovery,    tokenManager: env.tokenManager,  }),});

Search 백엔드를 더 고급으로 사용자 지정하려면 'Software Catalog 또는 TechDocs 인덱스의 필드를 사용자 지정하는 방법' 같은 how-to 가이드도 참고하세요.

더 알아보기 (Learn more)