Code warehouse

  • Client code
  • Server code

After the development of the company’s project, I found that the back-end logic of the project was single. Compared with the development process of the front and back end separation, I decided to use NestJS + GraphQL +mysql to optimize the project of the front and back end separation and optimize the development resources.

Why use nestjs

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, has built-in and full support for TypeScript (but still allows developers to write code in pure JavaScript) and combines elements of OOP (object-oriented programming), FP (functional programming), and FRP (functional responsive programming).

Underneath, Nest uses powerful HTTP Server frameworks such as Express (the default) and Fastify. Nest provides a degree of abstraction on top of these frameworks, while exposing its API directly to developers. This makes it easy to use the myriad third-party modules for each platform.

Why graphQL

  • Avoid excessive scraping of data
  • Compatible with data requirements of different environments
  • Rapid iteration of the product

Introduction to the

1. What isnest.js

A progressive Node.js framework for building efficient and scalable server-side applications. Perfect support for Typescript, AOP programming, support for Typeorm, Node.js version of Spring, and building microservice applications.

2. What isgraphql

GraphQL is a query language for application programming interfaces (apis) and a server-side runtime that enables clients to get exactly the data they need, without any redundancy.

Nest. Js project setup

1. Install the Nest CLI
npm i -g @nestjs/cli / / install nest - cli
nest new nest-graphql // New project
cd nest-grapql
yarn run start
Copy the code
2. Add@nestjs/graphql

npm i --save @nestjs/graphql graphql-tools graphql apollo-server-express ts-morph @apollo/gateway

3. Introduce the GraphQLModule
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { GraphQLModule } from '@nestjs/graphql';

@Module({  
    imports: [GraphQLModule.forRoot({})],  
    controllers: [AppController],  
    providers: [AppService],
})
export class AppModule {}
Copy the code

In this case, running NPM start will raise an exception that the schema cannot be found. In this case, you only need to configure the corresponding GQL file to solve the problem.

4. Add @ nestjs/config

In the process of project development, we often encounter different projects, or need to configure different parameters in different environments. Or maybe we need to have parameters that can’t be modified in different environments of development. In this case, we typically use Dotenv to read the.env file at the project root and access the parameters through process. In nestjs, we use the ConfigModule in the @nestjs/config package to handle the parameters.

NPM I — save@nestjs /config Add the corresponding configuration file

// src/config/configuration.ts
export default() = > ({graphql: {    
        installSubscriptionHandlers: true.// Enable subscription
        typePaths: ['./**/*.graphql'].// Indicates that the GraphQLModule should look for the location of the GraphQL file}});Copy the code

Inject the module in AppMoudle and import it into the GraphQLModule

// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { GraphQLModule } from '@nestjs/graphql';
import { ConfigModule, ConfigService } from '@nestjs/config';
import config from './config/configuration';

@Module({  
imports: [    
    ConfigModule.forRoot({
        envFilePath: '.env'.//      
        ignoreEnvFile: false.isGlobal: true.load: [config],    
    }),    
    GraphQLModule.forRootAsync({      
        imports: [ConfigModule],      
        useFactory: async (configService: ConfigService) => {        
            return {          
                typePaths: configService.get('graphql.typePaths'),}; },inject: [ConfigService],    
    }),  
],  
controllers: [AppController],  
providers: [AppService],
})
export class AppModule {}
Copy the code
  1. The corresponding service module is injected
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { GraphQLModule } from '@nestjs/graphql';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { CatsModule } from './cats/cats.module';
import config from './config/configuration';

@Module({
  imports: [
    CatsModule,
    ConfigModule.forRoot({
      envFilePath: '.env'.ignoreEnvFile: false.isGlobal: true.load: [config],
    }),
    GraphQLModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => {
        return {
          typePaths: configService.get('graphql.typePaths'),}; },inject: [ConfigService],
    }),
  ],
  controllers: [AppController],
  providers: [AppService], 
}) 
export class AppModule {} 
Copy the code

Why do some imported modules have forRoot after them

In nest. Js, we’ll notice that in the imports array, the corresponding module calls the forRoot() method and can pass in an optional home object. So what is forRoot()?

In NestJS, you can register modules not only with imports:[ConfigModule], but also with code that dynamically registers modules by calling the static method forRoot on the module class and returning an object that is an instance of DynamicModule.

// These are the same properties we use when we use @Module
{
      module: ConfigModule,
      providers: [ConfigService],
      exports: [ConfigService],
}
// When we call forRoot() to return the dynamic module, the dynamic module will be registered
Copy the code

The options object passed in can be registered with the dynamic module as a content provider, thus playing the role of configuring the module

import { DynamicModule, Module } from '@nestjs/common';

import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static forRoot(options): DynamicModule {
    return {
      module: ConfigModule,
      providers: [{provide: 'CONFIG_OPTIONS'.// You can use @inject ('CONFIG_OPTIONS') to Inject the desired module
          useValue: options, // Options uses a custom provider method to inject
        },
        ConfigService,
      ],
      exports: [ConfigService], }; }}Copy the code
import { Injectable, Inject } from '@nestjs/common';

import * as dotenv from 'dotenv';
import * as fs from 'fs';

import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(@Inject('CONFIG_OPTIONS') private options) { // We use @inject to identify the object
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '.. /.. / ', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key]; }}Copy the code

So far, Nest. Js combined with graphQL overall framework. It’s all done. The client setup will be explained in detail in part 2.

The article summary

  • Nest. Js and GraphQL intimate combination (ii) – client