Reputation: 332
hey i am trying to implement nest js microservice with grpc. it looks impossible to use nestjs microservice with struct type for plain objects.
how can i use compiled protos with nestjs ?
imports: [
ClientsModule.register([
{
name: 'HERO_PACKAGE',
transport: Transport.GRPC,
options: {
package: 'hero',
protoPath: join(__dirname, 'hero/hero.proto'),
},
},
]),
];
how can i load the compiled protos. something like https://medium.com/@waynelpu/how-to-pass-plain-javascript-object-with-gprc-94a91906ab1c
Upvotes: 2
Views: 2566
Reputation: 241
I'm maybe late but I found an answer.
Imagine you have the following protobuf
// task.proto
syntax = "proto3";
// Area API
package task;
// Imports
import "google/protobuf/struct.proto";
import "google/protobuf/empty.proto";
message Task {
string name = 1;
// Any additional metadata required to execute the task
google.protobuf.Struct params = 2;
}
service TaskService {
rpc CreateTask(CreateTaskRequest) returns (Task)
}
message CreateTaskRequest {
string name = 1;
google.protobuf.Struct params = 2;
}
You will need to add an option in your module to correctly load object
await app.connectMicroservice<MicroserviceOptions>({
transport: Transport.GRPC,
options: {
package: [ 'task' ],
protoPath: [ __dirname + '/protos/task.proto' ],
url: `${host}:${port}`,
loader: {
objects: true // This property
}
},
});
And then in the resolver, you will retrieve a structure that his gRPC Struct compliant, you can find more information here.
Now imagine that you execute a rpc call to CreateTask
(Postman has a great beta client for example)
{
"name": "fugiat qui laboris dolore",
"params": {
"fields": {
"foo": {
"stringValue": "bar"
},
"bar": {
"numberValue": 4
},
"baz": {
"boolValue": false
}
}
}
}
You will correctly retrieve it in your handler
async createTask(@Payload(new ValidationPipe({ whitelist: true })) req: CreateTaskRequest): Promise<Task> {
console.log(req.params)
...
}
Result
[Nest] 36410 - 02/09/2022, 3:33:33 PM LOG [NestMicroservice] Nest microservice successfully started +55ms
[Nest] 36410 - 02/09/2022, 3:33:33 PM LOG Workflow gRPC service listening on localhost:8000
[Nest] 36410 - 02/09/2022, 3:33:36 PM LOG Received rpc call to /area.task.TaskService/CreateTask with data: '{"workflowId":"1f5a0501-ce63-437d-b70f-a0ea3c22f0ff","name":"fugiat qui laboris dolore","type":0,"action":0,"nextTask":"Ut mollit","params":{"fields":{"foo":{"stringValue":"bar"},"bar":{"numberValue":4},"baz":{"boolValue":false}}}}'
{
fields: {
foo: { stringValue: 'bar' },
bar: { numberValue: 4 },
baz: { boolValue: false }
}
}
The only thing you have to do now is creating a simple function to correctly wrap struct send by your client. You can find more information with a real example on that repository.
Don't hesitate if you need anything else or if you found a better way to do it :D
Upvotes: 3