After learning some design patterns, I suddenly felt that a lot of knowledge could be built on this basic system. In order to understand the famous NestJS again, there is a project that feels like express is a bit of a drag to write, and plans to upgrade it to Nest.

The controller

The controller is responsible for processing incoming requests and returning responses to the client.

The purpose of the controller is to receive application-specific requests. The routing mechanism controls which controller receives which requests. Typically, each controller has multiple routes, and different routes can perform different operations.

To create a basic controller, we use classes and decorators. The decorator associates the class with the required metadata and enables Nest to create a routing map that binds the request to the appropriate controller.

Let’s start with decorators. Decorators are a way to implement decorator patterns, similar to the HOC we used in React. Its purpose is to enhance the object. Decorators can be used to decorate not only functions but also parameters.

// nest
@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats'; }}Copy the code

Let’s take a look at a few decorators in the Nest code.

  • Controller: class decorator, declared before class declaration, applied to class constructors to monitor, enhance, and replace class definitions;

    function Controller(prefixOrOptions) {
       const defaultPath = '/'; .return (target) = > {
            Reflect.defineMetadata(constants_1.PATH_METADATA, path, target);
            Reflect.defineMetadata(constants_1.HOST_METADATA, host, target);
            Reflect.defineMetadata(constants_1.SCOPE_OPTIONS_METADATA, scopeOptions, target);
        };
    }
    Copy the code

    This snippet of controller code uses Reflect Metadata, an ES7 proposal that adds and reads Metadata at declaration time.

    function classDecorator() :ClassDecorator {
      return target= > {
        // Define metadata on the class with key as' classMetaData 'and value as' a'
        Reflect.defineMetadata('classMetaData'.'a', target);
      };
    }
    
    function methodDecorator() :MethodDecorator {
      return (target, key, descriptor) = > {
        // Define the metadata on the class's prototype property 'someMethod' with key 'methodMetaData' and value 'b'
        Reflect.defineMetadata('methodMetaData'.'b', target, key);
      };
    }
    
    @classDecorator()
    class SomeClass {
      @methodDecorator()
      someMethod(){}}Reflect.getMetadata('classMetaData', SomeClass); // 'a'
    Reflect.getMetadata('methodMetaData'.new SomeClass(), 'someMethod'); // 'b'
    Copy the code
  • Get: method decorator

    Take a quick look at the source code

    const createMappingDecorator = (method) = > (path) = > {
        return exports.RequestMapping({
            [constants_1.PATH_METADATA]: path,
            [constants_1.METHOD_METADATA]: method,
        });
    };
    const RequestMapping = (metadata = defaultMetadata) = >{...// Returns a closure function with three arguments
        return (target, key, descriptor) = > {
            Reflect.defineMetadata(constants_1.PATH_METADATA, path, descriptor.value);
            Reflect.defineMetadata(constants_1.METHOD_METADATA, requestMethod, descriptor.value);
            return descriptor;
        };
    };
    
    exports.Get = createMappingDecorator(request_method_enum_1.RequestMethod.GET);
    
    Copy the code

    The method decorator passes in three arguments at runtime:

    1. Class constructor for static members, class prototype object for instance members;
    2. Member’s name;
    3. Attribute descriptor for a member;
  • Req: method parameter decorator

    The parameter decorator expression is called at run time to add some element data to the prototype of the class, passing in three arguments:

    1. Class constructor for static members, class prototype object for instance members;
    2. Method namesIf the constructor argument is decorated, the value isundefined
    3. Parameter index in function parameter list;