Metadata is empty, but Network tab shows it
- Dominant language
- JavaScript
- Stars
- 9.3k
- Forks
- 802
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 5
Description
In short, the metadata of my web-grpc client is always empty.
### Proto definition
Let's say my proto file looks like:
```proto
// some/path/myservice.proto
syntax = "proto3";
import "google/protobuf/empty.proto";
package some.path.myservice;
service MyService {
rpc RespondMetadata(google.protobuf.Empty) returns (google.protobuf.Empty) {}
}
```
### Code generation
I generated code for my proto files using `"grpc-web": "^1.4.2"`.
And protoc:
```shell
$ protoc --version
libprotoc 24.3
```
The command is:
```shell
protoc -I=. --js_out=import_style=commonjs,binary:. \
--grpc-web_out=import_style=typescript,mode=grpcweb:. \
some/path/myservice.proto
```
### Server-side
The server of this gRPC sets the metadata header `some-header` in Golang:
```go
func (s myServer) RespondMetadata(ctx context.Context, request *emptypb.Empty) (*emptypb.Empty, error) {
// ... Do some other stuff
// All side-effects resulting from this call happen sucessfully in the server. e.g. printing to console
// Set the metadata key value pair as header
header := metadata.New(map[string]string{"some-header": "some-value"})
err := grpc.SetHeader(ctx, header)
if err != nil {
return nil, fmt.Errorf("Failed to set header: %w", err)
}
return &emptypb.Empty{}, nil
}
```
I know this is working fine because I can create a Golang client for this server and successfully read the headers, both by dialing into the grpc port directly, or by dialing an Envoy proxy that I have already set up.
### Metadata transformed into HTTP headers
If I create my grpc client for the browser using grpc-web, I can see the metadata present in the HTTP Response Headers of the browser Network tab:
### Issue within browser (grpc-web) typescript code
However, in the code the metadata is always empty.
I initialize my client in the following way:
```typescript
import { MyServiceClient } "some/path/MyServiceClientPb";
const client = new MyServiceClient(serverUrl, null, null)
```
And I have tried calling the method and reading metadata in the following ways:
```typescript
const grpcRequest = new google_protobuf_empty_pb.Empty();
const call = client.respondMetadata(grpcRequest, {}, (err, response) => {
if (err) {
console.log("There was an error", err);
} else {
// response is of type google.protobuf.Empty
// So I can't read metadata from here
console.log("Successfull response: ", response)
}
});
call.on('status', (status) => {
console.log("Status metadata: ", status.metadata) // This is empty: {}
console.log("Status!:", status)
});
call.on('metadata', (metadata) => {
console.log("Received metadata: ", metadata); // This is empty: {}
const value = metadata['some-header'];
console.log('The received header is: ', value); // this is undefined
})
```
Any ideas how can I read **response** metadata? Or why are these approaches not working?
Contributor guide
Assessment
This issue has not been assessed yet.