사용법
사용법 (옛 프론트엔드 시스템)
이 문서는 여전히 옛 프론트엔드 시스템을 사용하는 Backstage 앱을 위한 것이에요.
출처: 문서
본문
info
이 문서는 여전히 옛 프론트엔드 시스템을 사용하는 Backstage 앱을 위한 것입니다. 앱이 새 프론트엔드 시스템을 사용한다면 대신 현재 가이드를 읽으세요.
Notifications Backend
notifications 백엔드 플러그인은 알림을 만들고, 로그인한 사용자별로 알림을 나열하며, 매개변수를 기반으로 검색하는 API를 제공해요.
플러그인은 영속성을 위해 관계형 데이터베이스를 사용해요. 이 맥락에서 특정 사항은 도입되지 않아요.
processors를 위한 선택적 추가 모듈을 제외하면 app-config에 추가 구성이 필요 없어요.
Notifications Frontend
알림의 수신자는 카탈로그의 엔티티, 예를 들면 User나 Group 종류여야 해요.
그 외에는 프론트엔드 notifications 플러그인에 특정 구성이 필요 없어요.
모든 매개변수화는 NotificationsSidebarItem 같은 컴포넌트 속성을 통해 이루어지며, 이를 프론트엔드의 활성 왼쪽 메뉴 항목으로 사용할 수 있어요.
packages/app/src/components/Root/Root.tsx에서 특정 필요에 따라 <NotificationsSidebarItem />의 속성을 조정하세요.
사용법
새 알림은 백엔드 플러그인 또는 REST API를 통한 외부 서비스가 보낼 수 있어요.
Backend
기술적으로 가능한지와 무관하게, 백엔드 플러그인은 notifications REST API에 직접 접근하는 것을 피해야 해요. 대신 @backstage/plugin-notifications-node와 통합해 새 알림을 send(생성)해야 해요.
이 방식의 이유는 API 요청에서 인증의 전파, 그리고 향후 유지보수성과 하위 호환성의 개선을 포함해요.
import { notificationService } from '@backstage/plugin-notifications-node';export const myPlugin = createBackendPlugin({ pluginId: 'myPlugin', register(env) { env.registerInit({ deps: { // ... notificationService: notificationService, }, async init({ // ... notificationService, }) { httpRouter.use( await createRouter({ // ... notificationService, }), ); }, }); },});
새 알림을 발행하려면:
await notificationService.send({ recipients /* of the broadcast or entity type */, payload /* actual message */,});
자세한 내용은 API 문서를 참고하세요.
외부 서비스
알림의 발신자가 Backstage 백엔드 플러그인일 때는 위에서 설명한 대로 @backstage/plugin-notifications-node를 통한 통합을 사용하는 것이 필수예요.
발신자가 Backstage 외부의 서비스라면, 인증이 제대로 구성되었다면 HTTP POST 요청을 API에 직접 보낼 수 있어요. 더 자세한 내용은 service-to-service auth 문서를 참고하세요. 가장 간단한 설정 옵션인 Static Tokens 섹션에 주목하세요.
브로드캐스트 알림을 만드는 예시 요청은 이렇게 생겼을 거예요.
curl -X POST https://[BACKSTAGE_BACKEND]/api/notifications -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_B...OKEN" -d '{"recipients":{"type":"broadcast"},"payload": {"title": "Title of broadcast message","link": "http://foo.com/bar","severity": "high","topic": "The topic"}}'
Scaffolder 템플릿
scaffolder 템플릿이 실행될 때 알림을 보내도록 @backstage/plugin-scaffolder-backend-module-notifications를 사용할 수 있어요. 모듈을 설치하려면 백엔드 플러그인에 추가하세요.
yarn workspace backend add @backstage/plugin-scaffolder-backend-module-notifications
그런 다음 모듈을 백엔드에 추가하세요.
const backend = createBackend();// ...backend.add( import('@backstage/plugin-scaffolder-backend-module-notifications'),);
이제 템플릿에서 steps의 일부로 notification:send 액션을 사용할 수 있어요.
steps: - id: notify name: Notify action: notification:send input: recipients: entity entityRefs: - component:default/backstage title: 'Template executed' info: 'Your template has been executed' severity: 'info' link: https://backstage.io
Signals
notifications와 signals의 함께 사용은 선택 사항이지만 일반적으로 사용자 경험과 성능을 향상시켜요.
알림이 생성되면, 구독한 리스너에게 알리기 위해 범용 메시지 버스에 새 신호가 발행돼요.
프론트엔드는 notifications 채널에서 이 공지를 받기 위해 영구 연결(WebSocket)을 유지해요. 업데이트되거나 생성된 알림의 구체적인 세부 사항은 성능상의 이유로 payload가 신호에 포함되는 새 알림을 제외하고, notifications API에 대한 요청으로 조회해야 해요.
프론트엔드 플러그인에서 notifications의 신호를 구독하려면:
import { useSignal } from '@backstage/plugin-signals-react';const { lastSignal } = useSignal<NotificationSignal>('notifications');React.useEffect(() => { /* ... */}, [lastSignal, notificationsApi]);
자신의 플러그인에서 signals 사용하기
자신의 플러그인에서 signals를 사용해 백엔드에서 프론트엔드로 거의 실시간으로 데이터를 전달할 수 있어요.
자신의 프론트엔드 플러그인에서 signals를 사용하려면 @backstage/plugin-notifications-common에서 @backstage/plugin-signals-react의 useSignal 훅을 신호의 선택적 제네릭 타입과 함께 추가해야 해요.
// To use the same type of signal in the backend, this should be placed in a shared common packageexport type MySignalType = { user: string; data: string; // ....};const { lastSignal } = useSignal<MySignalType>('my-plugin');useEffect(() => { if (lastSignal) { // Do something with the signal }}, [lastSignal]);
백엔드 플러그인에서 신호를 보내려면 플러그인 또는 모듈에 signalsServiceRef를 종속성으로 추가해야 해요.
import { signalsServiceRef } from '@backstage/plugin-signals-node';export const myPlugin = createBackendPlugin({ pluginId: 'my', register(env) { env.registerInit({ deps: { httpRouter: coreServices.httpRouter, signals: signalsServiceRef, }, async init({ httpRouter, signals }) { httpRouter.use( await createRouter({ signals, }), ); }, }); },});
서비스를 사용해 신호를 보내려면 publish 메서드를 사용할 수 있어요.
signals.publish<MySignalType>({ user: 'user', data: 'test' });
알림 소비하기
프론트엔드 플러그인에서 알림을 쿼리하는 가장 간단한 방법은 ID로 조회하는 거예요.
import { useApi } from '@backstage/core-plugin-api';import { notificationsApiRef } from '@backstage/plugin-notifications';const notificationsApi = useApi(notificationsApiRef);notificationsApi.getNotification(yourId);// or with connection to signals:notificationsApi.getNotification(lastSignal.notification_id);
Metadata 필드
metadata 필드는 프로세서가 사용하도록 설계된 자유 형식 객체예요.
잘 알려진 알림 Metadata 필드
아래는 프로세서들 사이에서 공통으로 사용되고 정의된 스키마가 있는 metadata 필드예요.
backstage.io/body.markdown
# Example:const payload = { title: 'Entities Require Attention', description: 'Entities: Service A, Service B', metadata: { 'backstage.io/body.markdown': ` # Entities - Service A - System B ` }}
이 metadata 필드의 값은 마크다운 형식의 알림 메시지여야 해요. 이렇게 하면 마크다운을 지원하는 프로세서에 추가 서식 옵션을 제공할 수 있어요.
사용법
아래는 커스텀 프로세서에서 backstage.io/body.markdown metadata 필드를 사용하는 예시예요.
알림을 보낼 때:
notificationService.send({ recipients: { type: 'entity', entityRef: 'group/default:team-a' }, payload: { title: 'Notification', description: 'Description' metadata: { 'backstage.io/body.markdown': ` ### Notification Description `, }, },});
프로세서에서 metadata 필드를 그에 따라 사용할 수 있어요.
async postProcess(notification: Notification): Promise<void> { // We suggest you parse the metadata field with a schema, i.e. Zod const parseResult = CustomProcessorMetadataSchema.safeParse(notification.payload.metadata ?? {}); const metadata = parseResult.success ? parseResult.data : {}; customNotificationSender.send({ to: getUsers(notification.recipients), subject: notification.payload.title, markdownText: metadata['backstage.io/body.markdown'] ?? notification.payload.description, });}