LifeSports Application(ReactNative & Nest.js) - 12. map-service

#1 map-service

map-service는 디바이스에서 사용될 맵 관련 서비스입니다. 예를 들어 유저가 풋살장을 검색할 경우 map-service -> wayfinding-service 통신 -> 풋살장 데이터 호출 식의 흐름을 가질 수 있습니다. 그림으로 간략히 살펴보겠습니다.

그림처럼 1) map data 요청 -> 2) map-service와 wayfinding-service 통신 -> 3) 데이터 탐색 -> 4) 결과 반환 -> 5) client에게 결과 보여주기 순으로 진행됩니다.

그러면 map-service를 만들어 보도록 하겠습니다.

#2 map-service project

nest new map-service
cd map-service
nest generate module maps
nest generate service maps

map-service와 wayfinding-service는 TCP기반의 통신을 진행합니다. rabbitmq라는 메시지 브로커가 존재하지만 다양한 방법으로 시도한 결과 큐 하나만으로 request와 response가 동시에 이루어지지 않아 TCP기반의 통신을 채택했습니다.

우선 map-service부터 구현을 진행하겠습니다.

  • ./src/app.controller.ts
import { Controller, Get, HttpStatus, Param, Query } from "@nestjs/common";
import { statusConstants } from "./constants/status.constant";
import { MapsService } from "./maps/maps.service";

@Controller("map-service")
export class AppController {
    constructor(private readonly mapsService: MapsService) {}

    @Get('/')
    public async getAll(): Promise<any> {
        try {
            const result: any = await this.mapsService.getAll();
            
            if(result.status === statusConstants.ERROR) {
                return await Object.assign({
                    status: HttpStatus.INTERNAL_SERVER_ERROR,
                    payload: null,
                    message: "Error message: " + result.message
                });
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: "Get list of map"
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }

    @Get('map/:_id')
    public async getOne(@Param('_id') _id: string): Promise<any> {
        try {
            const result: any = await this.mapsService.getOne(_id);

            if(result.status === statusConstants.ERROR)  {
                return await Object.assign({
                    status: statusConstants.ERROR,
                    payload: null,
                    message: "Error message: " + result.message,
                });
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: Builder(ResponseMaps)._id(result.payload._id)
                                              .ycode(result.payload.ycode)
                                              .type_nm(result.payload.type_nm)
                                              .gu_nm(result.payload.gu_nm)
                                              .parking_lot(result.payload.parking_lot)
                                              .bigo(result.payload.bigo)
                                              .xcode(result.payload.xcode)
                                              .tel(result.payload.tel)
                                              .addr(result.payload.addr)
                                              .in_out(result.payload.in_out)
                                              .home_page(result.payload.home_page)
                                              .edu_yn(result.payload.edu_yn)
                                              .nm(result.payload.nm)
                                              .build(),
                message: "Get data by _id"
            });
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Error Message: " + err
            });
        }
    }

    @Get('maps/list-type-nm/:type_nm')
    public async getListByTypeNm(@Param('type_nm') type_nm: string): Promise<any> {
        try {
            const result: any = await this.mapsService.getListByTypeNm(type_nm);
            
            if(result.status === statusConstants.ERROR) {
                return await Object.assign({
                    status: HttpStatus.INTERNAL_SERVER_ERROR,
                    payload: null,
                    message: "Error message: " + result.message
                });
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: "Get list of map"
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }
    
    @Get('maps/list-gu-nm/:gu_nm')
    public async getListByGuNm(@Param('gu_nm') gu_nm: string) : Promise<any> {
        try {
            const result: any = await this.mapsService.getListByGuNm(gu_nm);

            if(result.status === statusConstants.ERROR) {
                return await Object.assign({
                    status: HttpStatus.INTERNAL_SERVER_ERROR,
                    payload: null,
                    message: "Error message: " + result.message
                });
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: "Get list of map"
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }

    @Get('maps/list-gu-type')
    public async getListGuNmAndTypeNm(@Query() query): Promise<any> {
        try {
            const result: any = await this.mapsService.getListGuNmAndTypeNm(query.gu_nm, query.type_nm);
            
            if(result.status === statusConstants.ERROR) {
                return await Object.assign({
                    status: HttpStatus.INTERNAL_SERVER_ERROR,
                    payload: null,
                    message: "Error message: " + result.message
                });
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: "Get list of map"
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }
}

컨트롤러의 오류 코드들을 제거해나가면서 컨트롤러를 완성시키도록 하겠습니다.

npm install --save class-validator class-transformer builder-pattern
  • ./src/dto/map.dto.ts
import { IsNumber, IsString } from "class-validator";

export class MapsDto {
    @IsString()
    _id: string;
    
    @IsNumber()
    ycode: Number;

    @IsString()
    type_nm: string;

    @IsString()
    gu_nm: string;

    @IsString()
    parking_lot: string;

    @IsString()
    bigo: string;

    @IsNumber()
    xcode: Number;

    @IsString()
    tel: string;
    
    @IsString()
    addr: string;

    @IsString()
    in_out: string;

    @IsString()
    home_page: string;

    @IsString()
    edu_yn: string;

    @IsString()
    nm: string;
}
  • ./src/vo/response.maps.ts
export class ResponseMaps {
    _id: string;
    
    ycode: Number;

    type_nm: string;

    gu_nm: string;

    parking_lot: string;

    bigo: string;

    xcode: Number;

    tel: string;
    
    addr: string;

    in_out: string;

    home_page: string;

    edu_yn: string;

    nm: string;
}
  • ./src/constants/status.contants.ts
export const statusConstants = {
    SUCCESS: "SUCCESS",
    ERROR: "ERROR",
};

컨트롤러에서 대부분의 오류 코드들을 제거했으니 wayfinding-service와 rabbitmq를 이용하여 통신을 진행하도록 하겠습니다.

#3 TCP 통신

map-service, wayfinding-service에 다음의 패키지를 설치하도록 하겠습니다.

npm i --save @nestjs/microservices

map-service부터 설정을 하도록 하겠습니다.

  • ./src/maps/maps.module.ts
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { MapsService } from './maps.service';

@Module({
  imports: [
    ClientsModule.register([{
      name: 'wayfinding-service',
      transport: Transport.TCP
  }])],
  providers: [MapsService],
  exports: [MapsService],
})
export class MapsModule {}

wayfinding-service도 map-service에 등록하여 양 서비스 간의 통신을 하도록 하겠습니다.

  • ./src/main.ts
import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const microservice = app.connectMicroservice({
    transport: Transport.TCP
  });

  app.enableCors();
  
  await app.startAllMicroservices();
  await app.listen(7900);
}
bootstrap();

nestjs에서 request-response 메시지 통신은 client.send 메서드를 활용해 메시지를 발행하고, @MessagePattern이라는 데코레이터를 이용해 메시지를 전달받습니다. 그러면 maps.service.ts 클래스에서 메시지를 발행하고 wayfinding-service에서 메시지를 전달받도록 하겠습니다.

  • ./src/app.controller.ts
import { Controller, Get, HttpStatus, Param, Query } from "@nestjs/common";
import { Builder } from "builder-pattern";
import { statusConstants } from "./constants/status.constant";
import { MapsService } from "./maps/maps.service";
import { ResponseMaps } from "./vo/response.maps";

@Controller("map-service")
export class AppController {
    constructor(private readonly mapsService: MapsService) {}

    @Get('/')
    public getAll(): any {
        try {
            const result: any = this.mapsService.getAll();

            if(result.status !== HttpStatus.OK) {
                return result;
            }

            return result;
        } catch(err) {
            return Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }

    @Get('map/:_id')
    public async getOne(@Param('_id') _id: string): Promise<any> {
        try {
            const result: any = await this.mapsService.getOne(_id);

            if(result.status !== HttpStatus.OK) {
                return result;
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: Builder(ResponseMaps)._id(result.payload._id)
                                              .ycode(result.payload.ycode)
                                              .type_nm(result.payload.type_nm)
                                              .gu_nm(result.payload.gu_nm)
                                              .parking_lot(result.payload.parking_lot)
                                              .bigo(result.payload.bigo)
                                              .xcode(result.payload.xcode)
                                              .tel(result.payload.tel)
                                              .addr(result.payload.addr)
                                              .in_out(result.payload.in_out)
                                              .home_page(result.payload.home_page)
                                              .edu_yn(result.payload.edu_yn)
                                              .nm(result.payload.nm)
                                              .build(),
                message: "Get data by _id"
            });
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Error Message: " + err
            });
        }
    }

    @Get('maps/list-type-nm/:type_nm')
    public async getListByTypeNm(@Param('type_nm') type_nm: string): Promise<any> {
        try {
            const result: any = await this.mapsService.getListByTypeNm(type_nm);
            
            if(result.status !== HttpStatus.OK) {
                return result;
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: "Get list of map"
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }
    
    @Get('maps/list-gu-nm/:gu_nm')
    public async getListByGuNm(@Param('gu_nm') gu_nm: string) : Promise<any> {
        try {
            console.log(gu_nm);

            const result: any = await this.mapsService.getListByGuNm(gu_nm);

            if(result.status !== HttpStatus.OK) {
                return result;
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: "Get list of map"
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }

    @Get('maps/list-gu-type')
    public async getListGuNmAndTypeNm(@Query() query): Promise<any> {
        try {
            const result: any = await this.mapsService.getListGuNmAndTypeNm(query.gu_nm, query.type_nm);
            
            if(result.status !== HttpStatus.OK) {
                return result;
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: "Get list of map"
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }
}
  • ./src/maps/maps.service.ts
import { HttpStatus, Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { Observable } from 'rxjs';
import { statusConstants } from 'src/constants/status.constant';

@Injectable()
export class MapsService {
    constructor(@Inject('wayfinding-service') private readonly client: ClientProxy) {}

    public getAll(): Observable<any> {
        try {
            return this.client.send({ cmd: 'GET_ALL' }, '');
        } catch(err) {
            return Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Map-service: " + err
            });
        }
    }

    public async getOne(_id: string): Promise<any> {
        try {
            return this.client.send({ cmd: 'GET_ONE' }, _id);
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Map-service: " + err
            });
        }
    }

    public async getListByTypeNm(type_nm: string): Promise<any> {
        try {
            return this.client.send({ cmd: 'GET_LIST_TYPE' }, type_nm);    
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Map-service: " + err
            });
        }
    }

    public async getListByGuNm(gu_nm: string): Promise<any> {
        try {
            return this.client.send({ cmd: 'GET_LIST_GU' }, gu_nm);
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "map-service: " + err
            });
        }
    }

    public async getListGuNmAndTypeNm(gu_nm: string, type_nm: string): Promise<any> {
        try {
            return this.client.send({ cmd: 'GET_LIST_GU_TYPE' }, [gu_nm, type_nm]);
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "map-service: " + err
            });
        }
    }
}

메서드마다 전반적인 코드는 비슷합니다. 마지막 getListGuNmAndTypeNm을 기준으로 코드를 설명하겠습니다. this.client.send 첫 번째 인자는 메시지명이고, 두 번째 인자는 데이터입니다. 만약 client.send과정에서 오류가 발생한다면 try~catch문을 이용하여 유저에게 map-service의 에러메시지를 반환하도록 합니다.

이어서 wayfinding-service컨트롤러 부분에서 이 메시지를 받아보도록 하겠습니다.

  • ./src/app.controller.ts
import { Controller, HttpStatus } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
import { Builder } from 'builder-pattern';
import { statusConstants } from './constants/status.constant';
import { ResponseMaps } from './vo/response.maps';
import { WayfindingService } from './wayfinding/wayfinding.service';

@Controller("wayfinding-service")
export class AppController {
    constructor(private readonly wayfindingService: WayfindingService) {}

    @MessagePattern({ cmd: 'GET_ALL' })
    public async getAll(data: any): Promise<any> {
        try {
            const result: any = await this.wayfindingService.getAll();

            if(result.status === statusConstants.ERROR) {
                return await Object.assign({
                    status: HttpStatus.INTERNAL_SERVER_ERROR,
                    payload: null,
                    message: "Error message: " + result.message
                });
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: result.message
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }

    @MessagePattern({ cmd: 'GET_ONE' })
    public async getOne(data: any): Promise<any> {
        try {
            const result: any = await this.wayfindingService.getOne(data);

            if(result.status === statusConstants.ERROR)  {
                return await Object.assign({
                    status: statusConstants.ERROR,
                    payload: null,
                    message: "Error message: " + result.message,
                });
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: Builder(ResponseMaps)._id(result.payload._id)
                                              .ycode(result.payload.ycode)
                                              .type_nm(result.payload.type_nm)
                                              .gu_nm(result.payload.gu_nm)
                                              .parking_lot(result.payload.parking_lot)
                                              .bigo(result.payload.bigo)
                                              .xcode(result.payload.xcode)
                                              .tel(result.payload.tel)
                                              .addr(result.payload.addr)
                                              .in_out(result.payload.in_out)
                                              .home_page(result.payload.home_page)
                                              .edu_yn(result.payload.edu_yn)
                                              .nm(result.payload.nm)
                                              .build(),
                message: result.message
            });
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Error Message: " + err
            });
        }
    }

    @MessagePattern({ cmd: 'GET_LIST_TYPE' })
    public async getListByTypeNm(data: any): Promise<any> {
        try {
            const result: any = await this.wayfindingService.getListByTypeNm(data);
            
            if(result.status === statusConstants.ERROR) {
                return await Object.assign({
                    status: HttpStatus.INTERNAL_SERVER_ERROR,
                    payload: null,
                    message: "Error message: " + result.message
                });
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: result.message,
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err,
            });
        }
    }
    
    @MessagePattern({ cmd: 'GET_LIST_GU' })
    public async getListByGuNm(data: any) : Promise<any> {
        try {
            const result: any = await this.wayfindingService.getListByGuNm(data);

            if(result.status === statusConstants.ERROR) {
                return await Object.assign({
                    status: HttpStatus.INTERNAL_SERVER_ERROR,
                    payload: null,
                    message: "Error message: " + result.message
                });
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: result.message,
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }

    @MessagePattern({ cmd: 'GET_LIST_GU_TYPE' })
    public async getListGuNmAndTypeNm(data: any): Promise<any> {
        try {
            
            console.log(data);
            const result: any = await this.wayfindingService.getListGuNmAndTypeNm(data[0], data[1]);
            

            if(result.status === statusConstants.ERROR) {
                return await Object.assign({
                    status: HttpStatus.INTERNAL_SERVER_ERROR,
                    payload: null,
                    message: "Error message: " + result.message
                });
            }

            const responseMaps: Array<ResponseMaps> = [];

            for(const el of result.payload) {
                responseMaps.push(el);
            }

            return await Object.assign({
                status: HttpStatus.OK,
                payload: responseMaps,
                message: result.message,
            });
        } catch(err) {
            return await Object.assign({
                status: HttpStatus.BAD_REQUEST,
                payload: null,
                message: "Error message: " + err
            });
        }
    }
}
  • ./src/wayfinding/wayfinding.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Builder } from 'builder-pattern';
import { Model } from 'mongoose';
import { statusConstants } from 'src/constants/status.constant';
import { MapsDto } from 'src/dto/maps.dto';
import { Maps, MapsDocument } from 'src/schema/maps.schema';

@Injectable()
export class WayfindingService {
    constructor(@InjectModel(Maps.name) private mapsModel: Model<MapsDocument>,) {}

    public async getAll(): Promise<any> {
        try {
            const maps = await this.mapsModel.find();

            if(!maps) {
                return await Object.assign({
                    status: statusConstants.ERROR,
                    payload: null,
                    message: "Wayfinding-service: Not data!"
                });
            }

            const result: Array<MapsDto> = [];

            for(const element of maps) {
                result.push(element);
            }

            return await Object.assign({
                status: statusConstants.SUCCESS,
                payload: result,
                message: "Success transaction"
            });
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Wayfinding-service: " + err
            });
        }
    }

    public async getOne(_id: string): Promise<any> {
        try {
            const map = await this.mapsModel.findById(_id);

            if(!map) {
                return await Object.assign({
                    status: statusConstants.ERROR,
                    payload: null,
                    message: "Wayfinding-service: Not data!"
                });
            }
            
            return await Object.assign({
                status: statusConstants.SUCCESS,
                payload: Builder(MapsDto)._id(String(map._id))
                                         .ycode(map.ycode)
                                         .type_nm(map.type_nm)
                                         .gu_nm(map.gu_nm)
                                         .parking_lot(map.parking_lot)
                                         .bigo(map.bigo)
                                         .xcode(map.xcode)
                                         .tel(map.tel)
                                         .addr(map.addr)
                                         .in_out(map.in_out)
                                         .home_page(map.home_page)
                                         .edu_yn(map.edu_yn)
                                         .nm(map.nm)
                                         .build(),
                message: "Success transaction"
            });
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Wayfinding-service: " + err
            });
        }
    }

    public async getListByTypeNm(type_nm: string): Promise<any> {
        try {
            const maps = await this.mapsModel.find({ type_nm: type_nm });

            if(!maps) {
                return await Object.assign({
                    status: statusConstants.ERROR,
                    payload: null,
                    message: "Wayfinding-service: Not data!"
                });
            }

            const result: Array<MapsDto> = [];

            for(const element of maps) {
                result.push(element);
            }

            return await Object.assign({
                status: statusConstants.SUCCESS,
                payload: result,
                message: "Success transaction"
            });
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Wayfinding-service: " + err
            });
        }
    }

    public async getListByGuNm(gu_nm: string): Promise<any> {
        try {
            const maps = await this.mapsModel.find({ gu_nm: gu_nm });

            if(!maps) {
                return await Object.assign({
                    status: statusConstants.ERROR,
                    payload: null,
                    message: "Wayfinding-service: Not data!"
                });
            }

            const result: Array<MapsDto> = [];

            for(const element of maps) {
                result.push(element);
            }

            return await Object.assign({
                status: statusConstants.SUCCESS,
                payload: result,
                message: "Success transaction"
            });
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Wayfinding-service: " + err
            });
        }
    }

    public async getListGuNmAndTypeNm(gu_nm: string, type_nm: string): Promise<any> {
        try {
            const maps = await this.mapsModel.find({ 
                gu_nm: gu_nm,
                type_nm: type_nm
            });

            if(!maps) {
                return await Object.assign({
                    status: statusConstants.ERROR,
                    payload: null,
                    message: "Wayfinding-service: Not data!"
                });
            }

            const result: Array<MapsDto> = [];

            for(const element of maps) {
                result.push(element);
            }

            return await Object.assign({
                status: statusConstants.SUCCESS,
                payload: result,
                message: "Success transaction"
            });
        } catch(err) {
            return await Object.assign({
                status: statusConstants.ERROR,
                payload: null,
                message: "Wayfinding-service: " + err
            });
        }
    }
}

map-service와 wayfinding-service 간 통신을 위한 코드를 완료했습니다. 그러면 postman을 이용하여 데이터를 잘 받아오는지 테스트를 진행하겠습니다.

#4 테스트

1) GET /map-service/

2) GET /map-service/map/:_id

3) GET /map-service/maps/list-type-nm/:type_nm

4) GET /map-service/maps/list-gu-nm/:gu_nm

5) GET /map-service/maps/list-gu-type?gu_nm=:gu_nm&type_nm=:type_nm

5개의 endpoint 통신 결과 데이터가 응답이 잘 되는 모습을 확인할 수 있습니다.

다음 포스트에서는 kong을 이용하여 apigateway를 만들어 지금까지 만든 서비스들을 하나의 포트로 묶어 보도록 하겠습니다.

좋은 웹페이지 즐겨찾기