rest 쉘 스크립트

유석현(SeokHyun Yu)·2023년 5월 21일
0

정보

목록 보기
7/9

개요

지난해 회사에서 백엔드 코드를 Nest.js로 기술 스택을 이전하는 작업을 진행하였다.

이 작업에서는 동일한 도메인 명을 사용하되 세 가지 버전(관리자용, B2B용, 클라이언트용)을 생성하는 작업이 필요하였다.

이를 능률적으로 처리하기 위해 쉘 스크립트를 작성하여 사용하였다.

작성한 쉘 스크립트는 다음과 같은 작업을 자동으로 수행한다:

  1. 사용자로부터 도메인 이름 입력: 스크립트가 실행되면 먼저 사용자로부터 도메인 이름을 입력받는다. 이 이름은 후속 작업에 사용된다.

  2. 세 개의 서브디렉터리 생성: 입력받은 도메인 이름을 바탕으로 'admin', 'business', 'client'라는 이름의 세 개의 서브디렉터리를 생성한다.

  3. 필수 파일 생성 및 초기 코드 작성: 각 서브디렉터리에는 Controller, Service, Module 이라는 세 가지 TypeScript 파일을 생성한다. 각각의 파일에는 초기 코드가 적혀 있으며, 이 코드는 도메인 이름에 따라 달라진다. 이 초기 코드에는 필요한 의존성이 주입되어 있다.

    • Controller 파일에는 도메인에 해당하는 Service를 주입하는 코드가 작성된다.
    • Service 파일에는 도메인에 해당하는 Repository를 주입하는 코드가 작성된다.
    • Module 파일에는 Controller와 Service가 등록되고, 다른 모듈에 필요한 설정이 주입된다.

이러한 쉘 스크립트를 통해 반복되는 작업을 자동화하여, 더 빠르고 효과적으로 기술 스택 이전 작업을 진행할 수 있었다.

이를 통해 작업 시간을 크게 절약하고, 실수를 최소화하며, 작업의 일관성을 유지할 수 있었다.


코드

#!/bin/bash

# Validation
if [ $# -eq 0 ]
  then
    echo "No directory name provided"
    exit 1
fi

# Variables
dir_name=$1
dir_name_upper="$(tr '[:lower:]' '[:upper:]' <<< ${dir_name:0:1})${dir_name:1}"
path=apps/api/src

# Create subdirectories
mkdir $path/$dir_name/admin
mkdir $path/$dir_name/business
mkdir $path/$dir_name/client

# Create Admin
touch $path/$dir_name/admin/${dir_name}Admin.controller.ts
echo "import { ${dir_name_upper}AdminService } from '@api/$dir_name/admin/${dir_name}Admin.service';
import { Controller } from '@nestjs/common';

@Controller('$dir_name')
export class ${dir_name_upper}AdminController {
  constructor(private ${dir_name}AdminService: ${dir_name_upper}AdminService) {}
}" > $path/$dir_name/admin/${dir_name}Admin.controller.ts

touch $path/$dir_name/admin/${dir_name}Admin.service.ts
echo "import { ${dir_name_upper}Entity } from '@libs/entity/src/domain/$dir_name/${dir_name}.entity';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

@Injectable()
export class ${dir_name_upper}AdminService {
  constructor(
    @InjectRepository(${dir_name_upper}Entity)
    private ${dir_name}Repository: Repository<${dir_name_upper}Entity>,
  ) {}
}" > $path/$dir_name/admin/${dir_name}Admin.service.ts

touch $path/$dir_name/admin/${dir_name}Admin.module.ts
echo "import { ${dir_name_upper}AdminController } from '@api/$dir_name/admin/${dir_name}Admin.controller';
import { ${dir_name_upper}AdminService } from '@api/$dir_name/admin/${dir_name}Admin.service';
import { ${dir_name_upper}EntityModule } from '@libs/entity/src/domain/$dir_name/${dir_name}Entity.module';
import { Module } from '@nestjs/common';

@Module({
  imports: [
    ${dir_name_upper}EntityModule,
  ],
  controllers: [${dir_name_upper}AdminController],
  providers: [${dir_name_upper}AdminService],
})
export class ${dir_name_upper}AdminModule {}" > $path/$dir_name/admin/${dir_name}Admin.module.ts

# Create Business
touch $path/$dir_name/business/${dir_name}Business.controller.ts
echo "import { ${dir_name_upper}BusinessService } from '@api/$dir_name/business/${dir_name}Business.service';
import { Controller } from '@nestjs/common';

@Controller('$dir_name')
export class ${dir_name_upper}BusinessController {
  constructor(private ${dir_name}BusinessService: ${dir_name_upper}BusinessService) {}
}" > $path/$dir_name/business/${dir_name}Business.controller.ts

touch $path/$dir_name/business/${dir_name}Business.service.ts
echo "import { ${dir_name_upper}Entity } from '@libs/entity/src/domain/$dir_name/${dir_name}.entity';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

@Injectable()
export class ${dir_name_upper}BusinessService {
  constructor(
    @InjectRepository(${dir_name_upper}Entity)
    private ${dir_name}Repository: Repository<${dir_name_upper}Entity>,
  ) {}
}" > $path/$dir_name/business/${dir_name}Business.service.ts

touch $path/$dir_name/business/${dir_name}Business.module.ts
echo "import { ${dir_name_upper}BusinessController } from '@api/$dir_name/business/${dir_name}Business.controller';
import { ${dir_name_upper}BusinessService } from '@api/$dir_name/business/${dir_name}Business.service';
import { ${dir_name_upper}EntityModule } from '@libs/entity/src/domain/$dir_name/${dir_name}Entity.module';
import { Module } from '@nestjs/common';

@Module({
  imports: [
    ${dir_name_upper}EntityModule,
  ],
  controllers: [${dir_name_upper}BusinessController],
  providers: [${dir_name_upper}BusinessService],
})
export class ${dir_name_upper}BusinessModule {}" > $path/$dir_name/business/${dir_name}Business.module.ts

# Create Client
touch $path/$dir_name/client/${dir_name}Client.controller.ts
echo "import { ${dir_name_upper}ClientService } from '@api/$dir_name/client/${dir_name}Client.service';
import { Controller } from '@nestjs/common';

@Controller('$dir_name')
export class ${dir_name_upper}ClientController {
  constructor(private ${dir_name}ClientService: ${dir_name_upper}ClientService) {}
}" > $path/$dir_name/client/${dir_name}Client.controller.ts

touch $path/$dir_name/client/${dir_name}Client.service.ts
echo "import { ${dir_name_upper}Entity } from '@libs/entity/src/domain/$dir_name/${dir_name}.entity';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

@Injectable()
export class ${dir_name_upper}ClientService {
  constructor(
    @InjectRepository(${dir_name_upper}Entity)
    private ${dir_name}Repository: Repository<${dir_name_upper}Entity>,
  ) {}
}" > $path/$dir_name/client/${dir_name}Client.service.ts

touch $path/$dir_name/client/${dir_name}Client.module.ts
echo "import { ${dir_name_upper}ClientController } from '@api/$dir_name/client/${dir_name}Client.controller';
import { ${dir_name_upper}ClientService } from '@api/$dir_name/client/${dir_name}Client.service';
import { ${dir_name_upper}EntityModule } from '@libs/entity/src/domain/$dir_name/${dir_name}Entity.module';
import { Module } from '@nestjs/common';

@Module({
  imports: [
    ${dir_name_upper}EntityModule,
  ],
  controllers: [${dir_name_upper}ClientController],
  providers: [${dir_name_upper}ClientService],
})
export class ${dir_name_upper}ClientModule {}" > $path/$dir_name/client/${dir_name}Client.module.ts

# Create Module
echo "import { Module } from '@nestjs/common';
import { ${dir_name_upper}EntityModule } from '@libs/entity/src/domain/$dir_name/${dir_name}Entity.module';
import { RouterModule } from '@nestjs/core';
import { ${dir_name_upper}ClientModule } from '@api/$dir_name/client/${dir_name}Client.module';
import { ${dir_name_upper}AdminModule } from '@api/$dir_name/admin/${dir_name}Admin.module';
import { ${dir_name_upper}BusinessModule } from '@api/$dir_name/business/${dir_name}Business.module';

@Module({
  imports:[
    ${dir_name_upper}AdminModule,
    ${dir_name_upper}BusinessModule,
    ${dir_name_upper}ClientModule,
    RouterModule.register([
      {
        path: 'adm',
        module: ${dir_name_upper}AdminModule,
      },
      {
        path: 'bus',
        module: ${dir_name_upper}BusinessModule,
      },
      {
        path: '',
        module: ${dir_name_upper}ClientModule,
      },
    ]),
  ],
})
export class ${dir_name_upper}Module {}" > $path/$dir_name/${dir_name}.module.ts

echo "[$dir_name_upper] Admin, Business, Client 생성 완료!"

실행 결과

1. 생성되는 폴더 및 파일

2. Admin

3. Business

4. Client

5. Module

profile
Backend Engineer

0개의 댓글