# 安裝套件
```
npm i @grpc/grpc-js @grpc/proto-loader
npm i @nestjs/microservices@9.0.0
npm i -D ts-proto
```
# 修改nest-cli.json
```json=
"compilerOptions": {
"assets": ["**/*.proto"],
"watchAssets": true
}
```
# 新增proto檔
```protobuf=
syntax = "proto3";
package echo;
service EchoService {
rpc EchoMessage(EchoRequest) returns (EchoResponse);
}
message EchoRequest{
string name = 1;
}
message EchoResponse {
string name = 1;
string timestamp = 2;
}
```
# 加入Makefile
```
DIRNAME:= src/protos
proto:
protoc --plugin=node_modules/ts-proto/protoc-gen-ts_proto \
$(DIRNAME)/*.proto -I. \
--ts_proto_out=. \
--ts_proto_opt=fileSuffix=.pb \
--ts_proto_opt=nestJs=true \
--ts_proto_opt=addGrpcMetadata=false \
--ts_proto_opt=addNestjsRestParameter=false
clean:
rm -rf $(DIRNAME)/*.pb.ts
```
# 產生的型別
* Server端介面: xxxServiceController
* Client端介面: xxxServiceClient
* package名稱: xxx_PACKAGE_NAME
* service名稱: xxx_SERVICE_NAME
* GrpcMethod修飾詞: xxxServiceControllerMethods
# Server端
* grpcs需設定credentials
```typescript=
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Transport } from '@nestjs/microservices';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.connectMicroservice({
transport: Transport.GRPC,
options: {
url: 'localhost:50051',
package: 'echo',
protoPath: __dirname + '/echo/echo.proto',
},
});
app.startAllMicroservices();
app.listen(3000);
}
bootstrap();
```
```typescript=
@Controller()
@EchoServiceControllerMethods()
export class EchoController implements EchoServiceController {
echoMessage(
request: EchoRequest,
): EchoResponse | Promise<EchoResponse> | Observable<EchoResponse> {
return {
name: request.name,
timestamp: Date.now().toString(),
};
}
}
```
# Client端
```typescript=
import { Module } from '@nestjs/common';
import { HelloController } from './hello.controller';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { ECHO_PACKAGE_NAME, ECHO_SERVICE_NAME } from 'src/echo/echo.pb';
import { HelloService } from './hello.service';
@Module({
imports: [
ClientsModule.register([
{
name: ECHO_SERVICE_NAME,
transport: Transport.GRPC,
options: {
url: 'localhost:50051',
package: ECHO_PACKAGE_NAME,
protoPath: __dirname + '/../echo/echo.proto',
},
},
]),
],
controllers: [HelloController],
providers: [HelloService],
})
export class HelloModule {}
```
```typescript=
@Injectable()
export class HelloService {
private svc: EchoServiceClient;
constructor(
@Inject(ECHO_SERVICE_NAME)
private readonly client: ClientGrpc,
) {
this.svc = this.client.getService<EchoServiceClient>(ECHO_SERVICE_NAME);
}
hello() {
return this.svc.echoMessage({ name: 'abc' });
}
}
```