[컴] vendure plugin 만들기 - plugin 적용

vendure extension / vendure plugin /db migration

vendure plugin 만들기 - plugin 적용

여기서는 만들어진 plugin 을 추가하고, 적용하는 방법을 다룬다.

Prerequisites

  1. vendure server를 설치해야 한다.

절차

  1. vendure server 설치

  2. plugin 만들고

  3. bootstrap config 에 추가 : <proj_root>\src\vendure-config.ts 에 추가하면 된다.

  4. db migration

    • yarn migration:create <migration_file_name>
    • yarn migration:run
  5. 서버 재시작

  6. http://localhost:3000/admin-api 에서 다음 mutation 을 실행하면 된다.

    mutation {
      addRandomCat(id: "1") {
        id
        name
        customFields {
          catImageUrl
        }
      }
    }

plugin 추가하고 적용해보기

  1. RandomCat plugin-full-example
  2. <proj_root>/src/vendure-config.ts 에 추가 : 이것으로 vendure server에서 plugin 을 사용할 수 있게 된다.
  3. 서버 재시작

아래 plugin 을 아무 곳에나 넣는다. 여기서는 /src/plugins/randomcat안에 넣었다.

// ------------------------
// <proj_root>\src\plugins\randomcatrandomcat.plugin.ts
// ------------------------
import { Injectable } from '@nestjs/common';
import { Args, Mutation, Resolver } from '@nestjs/graphql';
import gql from 'graphql-tag';
import http from 'http';
import { Allow, Ctx, PluginCommonModule, ProductService, 
    RequestContext, VendureConfig, VendurePlugin } from '@vendure/core';
import { Permission } from '@vendure/common/lib/generated-types';

const schemaExtension = gql`
    extend type Mutation {
        addRandomCat(id: ID!): Product!
    }
`;

@Injectable()
export class CatFetcher {
  /** Fetch a random cat image url from random.cat */
  fetchCat(): Promise<string> {
    return new Promise((resolve) => {
      http.get('http://fastly.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U', (resp) => {
        let data = '';
        resp.on('data', chunk => data += chunk);
        resp.on('end', () => {
          // 수정
          // return resolve(JSON.parse(data).file)
          return resolve('http://fastly.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U')
        })
          ;
      });
    });
  }
}

@Resolver()
export class RandomCatResolver {
  constructor(private productService: ProductService, 
              private catFetcher: CatFetcher) {}

  @Mutation()
  // 수정
  // @Allow(Permission.UpdateCatalog)
  @Allow(Permission.Public)
  async addRandomCat(@Ctx() ctx: RequestContext, @Args() args: any) {
    const catImageUrl = await this.catFetcher.fetchCat();
    return this.productService.update(ctx, {
      id: args.id,
      customFields: { catImageUrl },
    });
  }
}

@VendurePlugin({
  imports: [PluginCommonModule],
  providers: [CatFetcher],
  adminApiExtensions: {
    schema: schemaExtension,
    resolvers: [RandomCatResolver],
  },
  configuration: config => {
    config.customFields.Product.push({
      type: 'string',
      name: 'catImageUrl',
    });
    return config;
  },
  compatibility: '^2.0.0',
})
export class RandomCatPlugin {}

다음처럼 config 으 plugins 부분에 새롭게 추가된 plugin 을 추가해주면 된다.

// 
// <proj_root>/src/vendure-config.ts
// 
...
import { RandomCatPlugin } from './plugins/randomcat/randomcat.plugin';

const IS_DEV = process.env.APP_ENV === 'dev';

export const config: VendureConfig = {
    apiOptions: {
        ...
    },
    authOptions: {
        ...
    },
    dbConnectionOptions: {
        ...
    },
    paymentOptions: {
        ...
    },
    // When adding or altering custom field definitions, the database will
    // need to be updated. See the "Migrations" section in README.md.
    customFields: {},
    plugins: [
        ...
        // --------------------------------------------
        // 여기에 추가한다.
        // --------------------------------------------
        RandomCatPlugin,
    ],
};

이제 서버를 다시 시작하면 된다. 그러면 노란색으로 db 를 변경해야 된다고 나온다.

db field 추가하기(DB Migration)

이제 저 노란 warning 을 없애보자. 즉 database 에 변경사항을 적용해보자.

ref. 4(Migrations | Vendure docs) 에 보면 설명이 있다.

기본적으로 <root>/src/vendure-config.ts 에 있는 설정값 dbConnectionOptions을 이용하게 된다. 여기에 migrations 정보가 있다. 이곳에 migrataion file을 만들게 된다.

migration command 는 package.json에 있다. 참고로 내부적으로 TypeORM 의 migration 기능을 사용한다.

migration:generate

yarn migration:generate <migration_file_name> 하면 현재 VendureConfig 와 현재의 database의 차이를 보고 migration file을 만들어주게 된다. <migration_file_name> 는 아무 string이나 넣으면 된다. 되도록 migration 을 설명하는 내용이면 좋다.

yarn migration:generate alter_product_catimageurl

migration:run

이제 이 만들어진 migration 을 실행하자. yarn migration:run 을 하면 된다.

yarn migration:run
D:\a\prog\real-world-vendure\v2\twin-cat>yarn migration:generate alter_product_catimageurl
yarn run v1.22.19
$ ts-node migration generate alter_product_catimageurl
Migration src\migrations\1692419711349-alter_product_catimageurl.ts has been generated successfully.
Done in 6.06s.

D:\a\prog\real-world-vendure\v2\twin-cat>yarn migration:run
yarn run v1.22.19
$ ts-node migration run
Successfully ran migration: alterProductCatimageurl1692419711349
Done in 5.93s.

아래처럼 customFieldsCatimageurl 이 생겼다.

migration:revert

yarn migration:revert

실패하는 경우

실패하면 기본적으로 rollback을 하도록 되어 있다. 다만 migration 여러개를 하던중에 문제가 발생한 경우 rollback을 하지만, MySQL/MariaDB 에서는 여러 transaction 을 rollback 하는 것을 지원하지 못한다고 한다.(?) Run migrations 을 참고하자.

사용하는 db table

db의 migrations라는 table을 사용해서 migration 이 어디까지 진행됐는지등을 파악한다.

Reference

  1. GitHub - vendure-ecommerce/plugin-template: A template for creating re-usable Vendure plugins
  2. Writing a Vendure Plugin | Vendure docs
  3. real-world-vendure/src/plugins/reviews at master · vendure-ecommerce/real-world-vendure · GitHub
  4. Migrations | Vendure docs

댓글 없음:

댓글 쓰기