LifeSports Application(ReactNative & Nest.js) - 12. map-service
38162 ワード
#1 map-service
map-serviceは、マッピングに関連するデバイスが使用するサービスです.たとえば、ユーザがフットサルフィールドを検索する場合、map-service->ルックアップサービス通信->フットサルフィールドデータを使用してストリームを呼び出すことができる.図で要約してみましょう.
図1)mapデータ要求->2)map-serviceとwayfing-service communication->3)データナビゲーション->4)戻り結果->5)は、順次クライアントに結果を表示する.
それではmap-serviceを作りましょう
#2 map-service project
nest new map-service
cd map-service
nest generate module maps
nest generate service maps
map-serviceとwayfind-serviceはTCPベースの通信を行う.rabbitmqという名前のメッセージエージェントが存在するが,複数の方法を試みた結果,要求と応答を同時に完了できないキューが1つしかなかったため,TCPベースの通信を採用した.まずmap-serviceから実施します.
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
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;
}
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;
}
export const statusConstants = {
SUCCESS: "SUCCESS",
ERROR: "ERROR",
};
コントローラからエラーコードの大部分が削除されたため、ルーティングサービスとrabbitmqを使用して通信します.#3 TCP通信
map-service、wayfing-serviceに次のパッケージをインストールします.
npm i --save @nestjs/microservices
map-service設定を開始しましょう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に登録され、2つのサービス間で通信する.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では、リクエスト応答メッセージ通信はclientである.sendメソッドを使用してメッセージを送信し、@MessagePatternというレコーダを使用してメッセージを送信します.では地図service.TSクラスでメッセージを公開し、wayfing-serviceでメッセージを受信します.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
});
}
}
}
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
});
}
}
}
各メソッドの全体的なコードは似ています.最後のgetListGunmAndTypeに従ってコードを説明します.this.client.sendの最初のパラメータはメッセージ名であり、2番目のパラメータはデータである.お客様がsend中にエラーが発生した場合はtry~catch文を使用してmap-serviceのエラーメッセージをユーザーに返させます.次にwayfing-serviceコントローラセクションでこのメッセージを受信します
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
});
}
}
}
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とwayfind-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つのエンドポイント通信の結果は,データ応答が良好であることを示した.
次の記事では、Kongを使用してapiGatewayを作成し、これまでに作成したサービスを1つのポートに組み合わせます.
Reference
この問題について(LifeSports Application(ReactNative & Nest.js) - 12. map-service), 我々は、より多くの情報をここで見つけました https://velog.io/@biuea/LifeSports-ApplicationReactNative-Nest.js-12.-map-serviceテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol