{"id":13514142,"url":"https://github.com/ysugimoto/grpc-graphql-gateway","last_synced_at":"2025-05-15T14:05:04.224Z","repository":{"id":40426865,"uuid":"237222303","full_name":"ysugimoto/grpc-graphql-gateway","owner":"ysugimoto","description":"A protoc plugin that generates graphql execution code from Protocol Buffers.","archived":false,"fork":false,"pushed_at":"2025-05-13T13:09:55.000Z","size":445,"stargazers_count":400,"open_issues_count":13,"forks_count":54,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-05-13T13:41:09.762Z","etag":null,"topics":["golang","graphql","grpc","protocol-buffers"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ysugimoto.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-30T13:47:07.000Z","updated_at":"2025-05-13T13:09:59.000Z","dependencies_parsed_at":"2024-04-27T17:40:05.925Z","dependency_job_id":"1d4e7897-e4ca-47a2-aaab-8e77f6e7fbcd","html_url":"https://github.com/ysugimoto/grpc-graphql-gateway","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysugimoto%2Fgrpc-graphql-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysugimoto%2Fgrpc-graphql-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysugimoto%2Fgrpc-graphql-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysugimoto%2Fgrpc-graphql-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ysugimoto","download_url":"https://codeload.github.com/ysugimoto/grpc-graphql-gateway/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254355334,"owners_count":22057354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","graphql","grpc","protocol-buffers"],"created_at":"2024-08-01T05:00:47.542Z","updated_at":"2025-05-15T14:05:04.217Z","avatar_url":"https://github.com/ysugimoto.png","language":"Go","funding_links":[],"categories":["Go","Implementations"],"sub_categories":["Go"],"readme":"# grpc-graphql-gateway\n\n`grpc-graphql-gateway` is a protoc plugin that generates graphql execution code from Protocol Buffers.\n\n![image](https://raw.githubusercontent.com/ysugimoto/grpc-graphql-gateway/master/misc/grpc-graphql-gateway.png)\n\n## Motivation\n\nOn API development, frequently we choose some IDL, in order to manage API definitions from a file.\nConsidering two of IDL -- GraphQL and Protocol Buffers (for gRPC) -- these have positive point respectively:\n\n- **GraphQL** -- Can put together multiple resources getting into one HTTP request, appropriate for BFF\n- **gRPC** -- Easy syntax in Protocol Buffers, and easy to implement API server using HTTP/2\n\nBut sometimes it's hard to maintain both GraphQL and Protocol Buffers, so we created this plugin in order to generate GraphQL Schema from Protocol Buffers.\n\nThis project much refers to [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) how to generate a file, provide a plugin. many thanks!\n\n## Installation\n\n### Get plugin binary\n\nGet `protoc-gen-graphql` binary from [releases](https://github.com/ysugimoto/grpc-graphql-gateway/releases) page and set $PATH to be executable.\n\nOr, simply get the latest one:\n\n```shell\ngo get github.com/ysugimoto/grpc-graphql-gateway/protoc-gen-graphql/...\n```\n\nThen the binary will place in `$GOBIN`.\n\n### Get protobuf file\n\nGet `include/graphql.proto` from this repository and put it into your project under the protobuf files.\n\n```shell\ngit submodule add https://github.com/ysugimoto/grpc-graphql-gateway.git grpc-graphql-gateway\n## Or another way...\n```\n\n## Usage\n\nPlease replace  `[your/project]` section to your appropriate project.\n\n### Write Protocol Buffers\n\nDeclare gRPC service with protobuf using `grpc-graphql-gateway` options.\nThis example has two RPCs that names `SayHello` and `SayGoodbye`:\n\n```protobuf\n// greeter.proto\nsyntax = \"proto3\";\n\nimport \"graphql.proto\";\n\nservice Greeter {\n  // gRPC service information\n  option (graphql.service) = {\n    host: \"localhost:50051\"\n    insecure: true\n  };\n\n  rpc SayHello (HelloRequest) returns (HelloReply) {\n    // Here is plugin definition\n    option (graphql.schema) = {\n      type: QUERY   // declare as Query\n      name: \"hello\" // query name\n    };\n  }\n\n  rpc SayGoodbye (GoodbyeRequest) returns (GoodbyeReply) {\n    // Here is plugin definition\n    option (graphql.schema) = {\n      type: QUERY     // declare as Query\n      name: \"goodbye\" // query name\n    };\n  }\n\n  rpc StreamGreetings (HelloRequest) returns (stream HelloReply) {\n    option (graphql.schema) = {\n      type: SUBSCRIPTION;\n      name: \"streamHello\";\n    };\n  }\n}\n\nmessage HelloRequest {\n  // Below line means the \"name\" field is required in GraphQL argument\n  string name = 1 [(graphql.field) = {required: true}];\n}\n\nmessage HelloReply {\n  string message = 1;\n}\n\nmessage GoodbyeRequest {\n  // Below line means the \"name\" field is required in GraphQL argument\n  string name = 1 [(graphql.field) = {required: true}];\n}\n\nmessage GoodbyeReply {\n  string message = 1;\n}\n```\n\n### Compile to Go code\n\nCompile protobuf file with the plugin:\n\n```shell\nprotoc \\\n  -I. \\\n  --go_out=./greeter \\\n  --go-grpc_out=./greeter \\\n  --graphql_out=./greeter \\\n  greeter.proto\n```\n\nThen you can see `greeter/greeter.pb.go` and `greeter/greeter.graphql.go`.\n\n### Implement service\n\nFor example, gRPC service will be:\n\n```go\n// service/main.go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"net\"\n    \"log\"\n\n    \"github.com/[your/project]/greeter\"\n    \"google.golang.org/grpc\"\n)\n\ntype Server struct{}\n\nfunc (s *Server) SayHello(ctx context.Context, req *greeter.HelloRequest) (*greeter.HelloReply, error) {\n\treturn \u0026greeter.HelloReply{\n\t\tMessage: fmt.Sprintf(\"Hello, %s!\", req.GetName()),\n\t}, nil\n}\n\nfunc (s *Server) SayGoodbye(ctx context.Context, req *greeter.GoodbyeRequest) (*greeter.GoodbyeReply, error) {\n\treturn \u0026greeter.GoodbyeReply{\n\t\tMessage: fmt.Sprintf(\"Good-bye, %s!\", req.GetName()),\n\t}, nil\n}\n\nfunc (s *Server) StreamGreetings(req *greeter.HelloRequest, stream greeter.Greeter_StreamGreetingsServer) error {\n\t// Get the name from the request\n\tname := req.GetName()\n\tif name == \"\" {\n\t\treturn status.Error(codes.InvalidArgument, \"name cannot be empty\")\n\t}\n\n\t// Define a list of greeting messages to send\n\tgreetings := []string{\n\t\tfmt.Sprintf(\"Hello, %s!\", name),\n\t\tfmt.Sprintf(\"Greetings, %s!\", name),\n\t\tfmt.Sprintf(\"Good day, %s!\", name),\n\t\tfmt.Sprintf(\"Welcome, %s!\", name),\n\t\tfmt.Sprintf(\"Hi there, %s!\", name),\n\t}\n\n\t// Stream each greeting to the client\n\tfor _, greeting := range greetings {\n\t\t// Create the response message\n\t\treply := \u0026greeter.HelloReply{\n\t\t\tMessage: greeting,\n\t\t}\n\n\t\t// Send the message to the client\n\t\tif err := stream.Send(reply); err != nil {\n\t\t\treturn status.Errorf(codes.Internal, \"failed to send greeting: %v\", err)\n\t\t}\n\n\t\t// Add a small delay between messages (optional)\n\t\ttime.Sleep(time.Millisecond * 200)\n\t}\n\n\treturn nil\n}\n\nfunc main() {\n\tconn, err := net.Listen(\"tcp\", \":500５1\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer conn.Close()\n\n\tserver := grpc.NewServer()\n\tgreeter.RegisterGreeterServer(server, \u0026Server{})\n\tserver.Serve(conn)\n}\n```\n\nThen let's start service:\n\n```shell\ngo run service/main.go\n```\n\nThe gRPC service will start on `localhost:50051`.\n\nNext, GraphQL gateway service should be:\n\n```go\n// gateway/main.go\npackage main\n\nimport (\n    \"log\"\n\n    \"net/http\"\n\n    \"github.com/[your/project]/greeter\"\n    \"github.com/ysugimoto/grpc-graphql-gateway/runtime\"\n)\n\nfunc main() {\n    mux := runtime.NewServeMux()\n\n    if err := greeter.RegisterGreeterGraphql(mux); err != nil {\n        log.Fatalln(err)\n    }\n    http.Handle(\"/graphql\", mux)\n    log.Fatalln(http.ListenAndServe(\":8888\", nil))\n}\n```\n\nThen let's start gateway:\n\n```shell\ngo run gateway/main.go\n```\n\nThe GraphQL gateway will start on `localhost:8888`\n\n### Send request via the gateway\n\nNow you can access gRPC service via GraphQL gateway!\n\n```shell\ncurl -g \"http://localhost:8888/graphql\" -d '\n{\n  hello(name: \"GraphQL Gateway\") {\n    message\n  }\n}'\n#=\u003e {\"data\":{\"hello\":{\"message\":\"Hello, GraphQL Gateway!\"}}}\n```\n\nYou can also send request via `POST` method with operation name like:\n\n```shell\ncurl -XPOST \"http://localhost:8888/graphql\" -d '\nquery greeting($name: String = \"GraphQL Gateway\") {\n  hello(name: $name) {\n    message\n  }\n  goodbye(name: $name) {\n    message\n  }\n}'\n#=\u003e {\"data\":{\"goodbye\":{\"message\":\"Good-bye, GraphQL Gateway!\"},\"hello\":{\"message\":\"Hello, GraphQL Gateway!\"}}}\n```\n\nYou can send subscription\n```shell\nwscat -c ws://localhost:8888/graphql -s graphql-ws\n{\"id\":\"1\",\"type\":\"subscribe\",\"payload\":{\"query\":\"subscription($name:String!){ streamHello(name:$name){ message }}\",\"variables\":{\"name\":\"Kamil\"}}}\n#=\u003e  {\"payload\":{\"data\":{\"streamHello\":{\"message\":\"Hello, Kamil!\"}}},\"id\":\"1\",\"type\":\"data\"}\n#=\u003e {\"payload\":{\"data\":{\"streamHello\":{\"message\":\"Greetings, Kamil!\"}}},\"id\":\"1\",\"type\":\"data\"}\n#=\u003e {\"payload\":{\"data\":{\"streamHello\":{\"message\":\"Good day, Kamil!\"}}},\"id\":\"1\",\"type\":\"data\"}\n#=\u003e {\"payload\":{\"data\":{\"streamHello\":{\"message\":\"Welcome, Kamil!\"}}},\"id\":\"1\",\"type\":\"data\"}\n#=\u003e {\"payload\":{\"data\":{\"streamHello\":{\"message\":\"Hi there, Kamil!\"}}},\"id\":\"1\",\"type\":\"data\"}\n#=\u003e {\"id\":\"1\",\"type\":\"complete\"}\n```\n\nThis is the most simplest way :-) \n\n## Resources\n\nTo learn more, please see the following resources:\n\n- `graphql.proto` Plugin option definition. See a comment section for custom usage (e.g mutation).\n- [example/greeter](https://github.com/ysugimoto/grpc-graphql-gateway/tree/master/example/greeter)  Files of above usage.\n- [example/starwars](https://github.com/ysugimoto/grpc-graphql-gateway/tree/master/example/starwars) Common implementation for GraphQL explanation, the StarWars API example\n\nThis plugin generates graphql execution code using [graphql-go/graphql](https://github.com/graphql-go/graphql), see that repository in detail.\n\n## Limitations\n\nThis plugin just aims to generate a simple gateway of gRPC.\n\nSome of things could be solved and could not be solved.\nThe most of limitations come from the IDL's power of expression -- some kind of GraphQL schema feature cannot implement by Protocol Buffers X(\n\nCurrently we don't support some Protobuf types:\n\n- Builtin `oneof` type\n\n## Contribute\n\n- Fork this repository\n- Customize / Fix problem\n- Send PR :-)\n- Or feel free to create issue for us. We'll look into it\n\n## Author\n\nYoshiaki Sugimoto\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fysugimoto%2Fgrpc-graphql-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fysugimoto%2Fgrpc-graphql-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fysugimoto%2Fgrpc-graphql-gateway/lists"}