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

백엔드 플러그인

원문 보기 위키 갱신

레거시 문서

출처: 문서

본문

레거시 문서

이 섹션은 레거시 플러그인 문서의 일부예요. 이 페이지는 이미 새 백엔드 시스템 패턴을 설명하지만, 백엔드 플러그인 구축의 표준 문서는 Building Backend Plugins and Modules로 이동했어요.

이 페이지는 Backstage 저장소에서 백엔드 플러그인을 만들고 관리하는 과정을 설명해요.

백엔드 플러그인 만들기

새롭고 아주 기본적인 백엔드 플러그인 패키지는 Backstage 저장소 루트에서 다음 명령을 실행하고 backend-plugin을 선택해 만들 수 있어요.

yarn new

플러그인 이름을 제공하라는 요청을 받을 거예요. 이것은 NPM 패키지 이름의 일부가 될 식별자이므로 짧게, 소문자만 사용하고 대시로 구분해야 해요. 예를 들어 Carmen이라는 시스템과의 통합을 추가하는 패키지라면 carmen이 될 수 있어요. 그러면 전체 NPM 패키지 이름은 new 명령에 전달하는 다른 플래그와 루트 package.json의 new 명령 설정에 따라 @internal/plugin-carmen-backend 같은 형태가 될 거예요.

플러그인을 만드는 데는 시간이 조금 걸리므로 인내심을 갖으세요. 초기 설치와 빌드 명령을 유용하게 실행해 주므로 패키지가 바로 해킹할 준비가 될 거예요! plugins 디렉터리의 새 폴더에 위치할 거예요. 이 예시에서는 plugins/carmen-backend예요.

간단한 개발 목적이라면 백엔드 플러그인을 실제로 독립형 모드로 시작할 수 있어요. 서비스의 첫 빛(first-light) 테스트를 할 수 있어요.

cd plugins/carmen-backendyarn start

잠시 생각한 다음 Listening on :7007이라고 말할 거예요. 다른 터미널 창에서 이제 다음을 실행하세요.

curl localhost:7007/api/carmen/todos

다음 응답이 보여야 해요.

{  "items": []}

참고

여기 표시된 라우트는 현재 백엔드 플러그인 템플릿의 기본값과 일치해요. 헬스 체크용 /health 엔드포인트를 원한다면 라우터에 직접 추가할 수 있어요.

백엔드 플러그인 개발

갓 생성된 백엔드 플러그인은 전체 앱 관점에서 기본적으로 아무것도 하지 않아요. 작은 기본 의존성 집합을 가지며 src/service/router.ts에 Express 라우터를 노출해요. 여기서 라우트를 추가하고 그것들을 실제 기본 기능에 연결하기 시작할 거예요. 그러나 Backstage 애플리케이션/백엔드의 어떤 것도 그것을 노출하지 않아요.

플러그인 라우터를 실제로 연결하고 실행하려면 백엔드를 일부 수정해야 해요.

Backstage 루트 디렉터리에서

yarn --cwd packages/backend add @internal/plugin-carmen-backend@^0.1.0 # Change this to match the plugin's package.json

packages/backend/src/index를 다음으로 갱신하세요.

const backend = createBackend();// ...backend.add(import('@internal/plugin-carmen-backend'));// ...backend.start();

백엔드를 시작한 후(예: 저장소 루트에서 yarn start-backend 사용) 그로부터 데이터를 가져올 수 있어야 해요.

# Note the extra /api herecurl localhost:7007/api/carmen/health

이전처럼 {"status":"ok"}를 반환해야 해요. 성공이에요!

기본적으로 안전 (Secure by Default)

1.25에서 Backstage는 플러그인에 대해 기본적으로 안전한 모델로 이동하기 시작했어요. 이는 플러그인에 대한 네트워크 요청이 기본적으로 인증되지 않은 사용자를 허용하지 않는다는 뜻이에요. 위의 curl 요청을 더 자세히 살펴보면, 이것이 인증되지 않은 접근을 허용해야 하는 이유를 알 수 있어요.

실제로 호출되는 엔드포인트는 다음에 정의돼요.

plugins/carmen-backend/src/service/router.ts

export async function createRouter(  options: RouterOptions,): Promise<express.Router> {  // ...  router.get('/health', (_, response) => {    logger.info('PONG!');    response.json({ status: 'ok' });  });  // ...  return router;}

여기에 인증 메커니즘이 정의되어 있지 않다는 것을 알게 될 거예요. 라우트 이름과 응답 데이터만 있어요. 인증은 플러그인 정의에서 처리되기 때문이에요.

plugins/carmen-backend/src/plugin.ts

httpRouter.use(  await createRouter({    logger,  }),);httpRouter.addAuthPolicy({  path: '/health',  allow: 'unauthenticated',});

이로써 이 플러그인의 /health 엔드포인트에 대한 요청이 인증되지 않은 채로 통과하도록 허용돼요!

의존성 사용

새 백엔드에서 의존성은 등록 중에 정적으로 정의되고 초기화 중에 "주입"돼요. 이것이 어떻게 보이는지에 대한 예시는 다음과 같아요.

plugins/carmen-backend/src/plugin.ts

deps: {  httpRouter: coreServices.httpRouter,  logger: coreServices.logger,},// And then you can use them through the options property!async init({ httpRouter, logger }) {    // ...},

deps 파라미터에 이름 있는 항목을 추가해 자체 의존성을 추가할 수 있어요.

deps: {  myDependency: coreServices.rootConfig,},

그런 다음 플러그인 정의의 init 블록에서 그것을 참조해 접근할 수 있어요.

async init({ myDependency }) {   // ..}

그리고 필요에 따라 그것을 호출하고 라우터에 전달할 자유로워져요.

Backstage는 많은 coreServices를 기본 제공해요. 더 심층적인 문서는 여기에서 볼 수 있어요.

데이터베이스 활용

Backstage 백엔드에는 SQL 데이터베이스 접근을 위한 내장 설비가 있어요. 영속성 요구가 있는 대부분의 플러그인은 이 설비를 사용하도록 선택할 거예요. 그러면 Backstage 운영자가 데이터베이스 요구를 균일하게 관리할 수 있기 때문이에요.

coreServices.database 서비스에 대한 의존성을 추가해 이에 접근할 수 있어요. 그러면 Knex 연결 객체를 받게 될 거예요.

plugins/carmen-backend/src/plugin.ts

deps: {  // ...  database: coreServices.database,},async init({  database,}) {  // You will then pass this client into your actual plugin implementation  // code, maybe similar to the following:  const model = new CarmenDatabaseModel(database);  httpRouter.use(    await createRouter({      model,      logger,    }),  );}

모든 플러그인 데이터베이스 요구는 app-config.yaml의 backend.database 구성 키 아래에 구성돼요. 프레임워크는 백스트리트에서 논리적 데이터베이스가 없으면 자동으로 만들어지도록 할 수도 있어요. 이는 Backstage 운영자가 결정하는 규칙에 기반해요.

그러나 프레임워크는 데이터베이스 스키마 마이그레이션을 자동으로 처리하지 않아요. 기본 저장소의 내장 플러그인은 스키마 마이그레이션을 관리하기 위해 Knex 라이브러리를 사용하기로 선택했지만, 원하는 어떤 방식으로든 할 수 있어요.

스키마 마이그레이션 작성과 데이터베이스에 대한 SQL 쿼리 수행의 예시와 세부 사항은 Knex 라이브러리 문서를 참고하세요.

사용자 신원 활용

Backstage 백엔드는 또한 사용자 신원에 접근하기 위한 핵심 서비스를 제공해요. coreServices.httpAuth와 coreServices.userInfo 의존성을 통해 접근할 수 있어요.

plugins/carmen-backend/src/plugin.ts

deps: {  httpAuth: coreServices.httpAuth,  userInfo: coreServices.userInfo,},async init({  httpAuth,  userInfo,}) {  httpRouter.use(    await createRouter({      httpAuth,      userInfo,      logger,    }),  );}

그러면 플러그인은 요청에서 신원을 추출할 수 있어요.

export interface RouterOptions {  logger: LoggerService;  userInfo: UserInfoService;  httpAuth: HttpAuthService;}export async function createRouter(  options: RouterOptions,): Promise<express.Router> {  const { userInfo, httpAuth } = options;  router.post('/me', async (req, res) => {    const credentials = await httpAuth.credentials(req, {      // This rejects request from non-users. Only use this if your plugin needs to access the      // user identity, most of the time it's enough to just call `httpAuth.credentials(req)`      allow: ['user'],    });    const user = await userInfo.getUserInfo(credentials);    res.json({      // The catalog entity ref of the user.      userEntityRef: user.userEntityRef,      // The list of entities that this user or any teams this user is a part of owns.      ownershipEntityRefs: user.ownershipEntityRefs,    });  });  // ...}

더 알아보기 (Learn more)