Skip to content

Commit 282fbcd

Browse files
Merge branch 'feature/add-grpc-metadata' of https://github.com/AlexDaSoul/docs.nestjs.com into AlexDaSoul-feature/add-grpc-metadata
2 parents 3ee09b7 + f2a3a40 commit 282fbcd

File tree

1 file changed

+77
-7
lines changed

1 file changed

+77
-7
lines changed

content/microservices/grpc.md

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Next, we need to implement the service. To define a handler that fulfills this d
123123
@Controller()
124124
export class HeroesController {
125125
@GrpcMethod('HeroesService', 'FindOne')
126-
findOne(data: HeroById, metadata: any): Hero {
126+
findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
127127
const items = [
128128
{ id: 1, name: 'John' },
129129
{ id: 2, name: 'Doe' },
@@ -135,7 +135,7 @@ export class HeroesController {
135135
@Controller()
136136
export class HeroesController {
137137
@GrpcMethod('HeroesService', 'FindOne')
138-
findOne(data, metadata) {
138+
findOne(data, metadata, call) {
139139
const items = [
140140
{ id: 1, name: 'John' },
141141
{ id: 2, name: 'Doe' },
@@ -149,7 +149,9 @@ export class HeroesController {
149149
150150
The decorator shown above takes two arguments. The first is the service name (e.g., `'HeroesService'`), corresponding to the `HeroesService` service definition in `hero.proto`. The second (the string `'FindOne'`) corresponds to the `FindOne()` rpc method defined within `HeroesService` in the `hero.proto` file.
151151

152-
The `findOne()` handler method takes two arguments, the `data` passed from the caller and `metadata` that stores gRPC request metadata.
152+
The `findOne()` handler method takes three arguments, the `data` passed from the caller, `metadata` that stores gRPC
153+
request metadata and `call` to obtain the `GrpcCall` object properties such as `sendMetadata` for send metadata to client.
154+
153155

154156
Both `@GrpcMethod()` decorator arguments are optional. If called without the second argument (e.g., `'FindOne'`), Nest will automatically associate the `.proto` file rpc method with the handler based on converting the handler name to upper camel case (e.g., the `findOne` handler is associated with the `FindOne` rpc call definition). This is shown below.
155157

@@ -158,7 +160,7 @@ Both `@GrpcMethod()` decorator arguments are optional. If called without the sec
158160
@Controller()
159161
export class HeroesController {
160162
@GrpcMethod('HeroesService')
161-
findOne(data: HeroById, metadata: any): Hero {
163+
findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
162164
const items = [
163165
{ id: 1, name: 'John' },
164166
{ id: 2, name: 'Doe' },
@@ -170,7 +172,7 @@ export class HeroesController {
170172
@Controller()
171173
export class HeroesController {
172174
@GrpcMethod('HeroesService')
173-
findOne(data, metadata) {
175+
findOne(data, metadata, call) {
174176
const items = [
175177
{ id: 1, name: 'John' },
176178
{ id: 2, name: 'Doe' },
@@ -187,7 +189,7 @@ You can also omit the first `@GrpcMethod()` argument. In this case, Nest automat
187189
@Controller()
188190
export class HeroesService {
189191
@GrpcMethod()
190-
findOne(data: HeroById, metadata: any): Hero {
192+
findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
191193
const items = [
192194
{ id: 1, name: 'John' },
193195
{ id: 2, name: 'Doe' },
@@ -199,7 +201,7 @@ export class HeroesService {
199201
@Controller()
200202
export class HeroesService {
201203
@GrpcMethod()
202-
findOne(data, metadata) {
204+
findOne(data, metadata, call) {
203205
const items = [
204206
{ id: 1, name: 'John' },
205207
{ id: 2, name: 'Doe' },
@@ -440,3 +442,71 @@ lotsOfGreetings(requestStream: any, callback: (err: unknown, value: HelloRespons
440442
```
441443

442444
Here we used the `callback` function to send the response once processing of the `requestStream` has been completed.
445+
446+
#### gRPC Metadata
447+
448+
gRPC metadata is additional data that may be useful during the processing of requests and responses, but is not part of the actual application data. Metadata may include authentication tokens, request identifiers and tags for monitoring purposes, and data information such as the number of records in a data set.
449+
450+
To read the metadata in `@GrpcMethod()` use the second handler metadata argument, which returns the gRPC class `Metadata`.
451+
452+
You can send metadata from `@GrpcMethod()` using the function `sendMetadata()` which is provided by the object `GrpcCall` in the third handler argument.
453+
454+
```typescript
455+
@@filename(heroes.controller)
456+
@Controller()
457+
export class HeroesService {
458+
@GrpcMethod()
459+
findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
460+
const srvMetadata = new Metadata();
461+
const items = [
462+
{ id: 1, name: 'John' },
463+
{ id: 2, name: 'Doe' },
464+
];
465+
466+
srvMetadata.add('Set-Cookie', 'yummy_cookie=choco');
467+
call.sendMetadata(srvMetadata);
468+
469+
return items.find(({ id }) => id === data.id);
470+
}
471+
}
472+
@@switch
473+
@Controller()
474+
export class HeroesService {
475+
@GrpcMethod()
476+
findOne(data, metadata, call) {
477+
const srvMetadata = new Metadata();
478+
const items = [
479+
{ id: 1, name: 'John' },
480+
{ id: 2, name: 'Doe' },
481+
];
482+
483+
srvMetadata.add('Set-Cookie', 'yummy_cookie=choco');
484+
call.sendMetadata(srvMetadata);
485+
486+
return items.find(({ id }) => id === data.id);
487+
}
488+
}
489+
```
490+
> info **Hint** The classes `Metadata`, `ServerUnaryCall`, `ServerUnaryCall`, `ServerReadableStream` etc. are exported
491+
> from the
492+
> `grpc` package.
493+
494+
The Grpc client can also send metadata if it is sent by the second parameter:
495+
496+
```typescript
497+
getHero(): Observable<string> {
498+
const srvMetadata = new Metadata();
499+
500+
srvMetadata.add('Set-Cookie', 'yummy_cookie=choco');
501+
502+
return this.heroesService.findOne({ id: 1 }, srvMetadata);
503+
}
504+
```
505+
506+
Stream can receive metadata using a `metadata` event:
507+
508+
```typescript
509+
stream.on('metadata', (metadata: Metadata) => {
510+
const getMeta = metadata.get('X-My-Meta');
511+
});
512+
```

0 commit comments

Comments
 (0)