Browse Source

add collection api

nameczz 3 years ago
parent
commit
62bbfb1f59

+ 17 - 0
.vscode/launch.json

@@ -0,0 +1,17 @@
+{
+  // Use IntelliSense to learn about possible attributes.
+  // Hover to view descriptions of existing attributes.
+  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "type": "node",
+      "request": "attach",
+      "name": "Attach NestJS WS",
+      "port": 9229,
+      "restart": true,
+      "stopOnEntry": false,
+      "protocol": "inspector"
+    }
+  ]
+}

+ 1 - 0
server/.eslintrc.js

@@ -2,6 +2,7 @@ module.exports = {
   parser: '@typescript-eslint/parser',
   parserOptions: {
     project: 'tsconfig.json',
+    tsconfigRootDir: __dirname,
     sourceType: 'module',
   },
   plugins: ['@typescript-eslint/eslint-plugin'],

+ 2 - 1
server/src/app.module.ts

@@ -1,9 +1,10 @@
 import { Module } from '@nestjs/common';
 import { AppController } from './app.controller';
 import { AppService } from './app.service';
+import { CollectionModule } from './collection/collection.module';
 
 @Module({
-  imports: [],
+  imports: [CollectionModule],
   controllers: [AppController],
   providers: [AppService],
 })

+ 18 - 0
server/src/collection/collection.controller.spec.ts

@@ -0,0 +1,18 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { CollectionController } from './collection.controller';
+
+describe('CollectionController', () => {
+  let controller: CollectionController;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      controllers: [CollectionController],
+    }).compile();
+
+    controller = module.get<CollectionController>(CollectionController);
+  });
+
+  it('should be defined', () => {
+    expect(controller).toBeDefined();
+  });
+});

+ 4 - 0
server/src/collection/collection.controller.ts

@@ -0,0 +1,4 @@
+import { Controller } from '@nestjs/common';
+
+@Controller('collection')
+export class CollectionController {}

+ 9 - 0
server/src/collection/collection.module.ts

@@ -0,0 +1,9 @@
+import { Module } from '@nestjs/common';
+import { CollectionController } from './collection.controller';
+import { CollectionService } from './collection.service';
+
+@Module({
+  controllers: [CollectionController],
+  providers: [CollectionService],
+})
+export class CollectionModule {}

+ 18 - 0
server/src/collection/collection.service.spec.ts

@@ -0,0 +1,18 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { CollectionService } from './collection.service';
+
+describe('CollectionService', () => {
+  let service: CollectionService;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      providers: [CollectionService],
+    }).compile();
+
+    service = module.get<CollectionService>(CollectionService);
+  });
+
+  it('should be defined', () => {
+    expect(service).toBeDefined();
+  });
+});

+ 4 - 0
server/src/collection/collection.service.ts

@@ -0,0 +1,4 @@
+import { Injectable } from '@nestjs/common';
+
+@Injectable()
+export class CollectionService {}

+ 67 - 0
server/src/interceptors/index.ts

@@ -0,0 +1,67 @@
+import {
+  Injectable,
+  NestInterceptor,
+  ExecutionContext,
+  CallHandler,
+  HttpStatus,
+  BadRequestException,
+  NotFoundException,
+} from '@nestjs/common';
+import { map, catchError } from 'rxjs/operators';
+import { Observable, throwError } from 'rxjs';
+
+export interface Response<T> {
+  code: number;
+  data: T;
+}
+
+/**
+ *  transform response to client
+ */
+@Injectable()
+export class TransformResInterceptor<T>
+  implements NestInterceptor<T, Response<T>>
+{
+  intercept(
+    context: ExecutionContext,
+    next: CallHandler,
+  ): Observable<Response<T>> {
+    return next.handle().pipe(map((data) => ({ code: HttpStatus.OK, data })));
+  }
+}
+
+/**
+ * Handle error in here.
+ * Normally depend on status which from milvus service.
+ */
+@Injectable()
+export class ErrorInterceptor implements NestInterceptor {
+  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
+    return next.handle().pipe(
+      catchError((err) => {
+        console.error(err);
+
+        if (err.isAxiosError && err.response) {
+          const errContent = err.response.data || 'Bad Request';
+          // from milvus http service
+          const status = err.response.status || 400;
+
+          // operationId is milvus operation id, client need it in response
+          err.operationId &&
+            errContent instanceof Object &&
+            (errContent.operationId = err.operationId);
+          switch (status) {
+            case 400:
+              return throwError(new BadRequestException(errContent));
+            case 404:
+              return throwError(new NotFoundException('Not Found Api'));
+            default:
+              return throwError(new BadRequestException(errContent));
+          }
+        }
+
+        return throwError(err);
+      }),
+    );
+  }
+}

+ 14 - 0
server/src/middlewares/logger.ts

@@ -0,0 +1,14 @@
+import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
+import { Request, Response } from 'express';
+
+@Injectable()
+export class LoggerMiddleware implements NestMiddleware {
+  // eslint-disable-next-line @typescript-eslint/ban-types
+  use(req: Request, res: Response, next: Function) {
+    const { method = '', url = '' } = req.body || {};
+    const { path = '' } = req.route || {};
+
+    Logger.log(`${method} ${url}`, `API ${path}`);
+    next();
+  }
+}

+ 2 - 2
server/tsconfig.json

@@ -5,11 +5,11 @@
     "removeComments": true,
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
-    "allowSyntheticDefaultImports": true,
     "target": "es2017",
     "sourceMap": true,
     "outDir": "./dist",
     "baseUrl": "./",
     "incremental": true
-  }
+  },
+  "exclude": ["node_modules", "dist"]
 }