gdong42 / grpc-mate

A dynamic proxy server that translates JSON HTTP requests into gRPC calls.
https://grpcmate.io
Apache License 2.0
75 stars 9 forks source link

How to set Access-Control header? #10

Open Paxa opened 4 years ago

Paxa commented 4 years ago

Is it possible to set custom headers?

I can't interact with grpc-mate by browser

gdong42 commented 4 years ago

What was the error? How should I reproduce it. I can interact with grpc-mate by browser with no problem.

Paxa commented 4 years ago

Create simple http server on same host, and type fetch('http://127.0.0.1:6600/actuator/services') Error will be something like this

Access to fetch at 'http://127.0.0.1:6600/actuator/services' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Screen Shot 2020-05-16 at 22 20 46

Having option to set Access-Control-Allow-Origin: * will be nice https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

gdong42 commented 4 years ago

I see. So you are requesting /actuator/services using JavaScript, probably from a web UI running on other origin. It's not supported yet, but I think I can add it as an option. Is it needed for /v1/.. endpoints that are proxied to the backend gRPC server?

gdong42 commented 4 years ago

There is a plan to add Web UI support: https://github.com/gdong42/grpc-mate/issues/8

Hopefully when it's done folks don't have to enable Access-Control headers and build a web UI theirselves. But for now, let me add an ACCESS_CONTROL_ALLOW_ORIGIN env option to set the response header.

Paxa commented 4 years ago

I'm building some UI for generating documentation and sending requests (similar to openapi) The challenge so far to get all proto details because grpc.reflection.v1alpha.ServerReflection uses bi-directional streaming, which is not supported by grpc-mate

Btw any plans to support multiple backends?

As workaround I built grpc service to serve all protos as json

syntax = "proto3";
package internal;

option go_package = "protos";

service DescriptorServer { // after service
    rpc getAll(DescriptorsRequest) returns (DescriptorsResponse) {} // ta ta ta
}

message DescriptorsRequest {
}

message DescriptorsResponse {
    repeated string file = 1; // just one
}

go server

import (
    "context"
    pb "grpc-reflector/protos"

    "github.com/gogo/protobuf/jsonpb"
    log "github.com/sirupsen/logrus"
)

type DescriptorServer struct {
    pb.UnimplementedDescriptorServerServer
}

// be careful with output, it may break your terminal
func (s *DescriptorServer) GetAll(ctx context.Context, in *pb.DescriptorsRequest) (*pb.DescriptorsResponse, error) {
    all := []string{}
    m := jsonpb.Marshaler{}
    for _, descriptor := range CompiledProtos {
        compiled, err := m.MarshalToString(descriptor)
        if err == nil {
            all = append(all, compiled)
        } else {
            log.Errorf("Can not compile %v", err)
        }
    }
    return &pb.DescriptorsResponse{File: all}, nil
}

It serve protos encoded as json string, in this way I don't need to do any protobuf decoding in JS

Will share some preview when it's usable