• Stars
    star
    368
  • Rank 115,370 (Top 3 %)
  • Language
    Go
  • License
    MIT License
  • Created over 4 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A protoc plugin that generates graphql execution code from Protocol Buffers.

grpc-graphql-gateway

CircleCI

grpc-graphql-gateway is a protoc plugin that generates graphql execution code from Protocol Buffers.

image

Motivation

On API development, frequently we choose some IDL, in order to manage API definitions from a file. Considering two of IDL -- GraphQL and Protocol Buffers (for gRPC) -- these have positive point respectively:

  • GraphQL -- Can put together multiple resources getting into one HTTP request, appropriate for BFF
  • gRPC -- Easy syntax in Protocol Buffers, and easy to implement API server using HTTP/2

But 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.

This project much refers to grpc-gateway how to generate a file, provide a plugin. many thanks!

Installation

Get plugin binary

Get protoc-gen-graphql binary from releases page and set $PATH to be executable.

Or, simply get the latest one:

go get github.com/ysugimoto/grpc-graphql-gateway/protoc-gen-graphql/...

Then the binary will place in $GOBIN.

Get protobuf file

Get include/graphql.proto from this repository and put it into your project under the protobuf files.

git submodule add https://github.com/ysugimoto/grpc-graphql-gateway.git grpc-graphql-gateway
## Or another way...

Usage

Please replace [your/project] section to your appropriate project.

Write Protocol Buffers

Declare gRPC service with protobuf using grpc-graphql-gateway options. This example has two RPCs that names SayHello and SayGoodbye:

// greeter.proto
syntax = "proto3";

import "graphql.proto";

service Greeter {
  // gRPC service information
  option (graphql.service) = {
    host: "localhost:50051"
    insecure: true
  };

  rpc SayHello (HelloRequest) returns (HelloReply) {
    // Here is plugin definition
    option (graphql.schema) = {
      type: QUERY   // declare as Query
      name: "hello" // query name
    };
  }

  rpc SayGoodbye (GoodbyeRequest) returns (GoodbyeReply) {
    // Here is plugin definition
    option (graphql.schema) = {
      type: QUERY     // declare as Query
      name: "goodbye" // query name
    };
  }
}

message HelloRequest {
  // Below line means the "name" field is required in GraphQL argument
  string name = 1 [(graphql.field) = {required: true}];
}

message HelloReply {
  string message = 1;
}

message GoodbyeRequest {
  // Below line means the "name" field is required in GraphQL argument
  string name = 1 [(graphql.field) = {required: true}];
}

message GoodbyeReply {
  string message = 1;
}

Compile to Go code

Compile protobuf file with the plugin:

protoc \
  -I. \
  --go_out=./greeter \
  --go-grpc_out=./greeter \
  --graphql_out=./greeter \
  greeter.proto

Then you can see greeter/greeter.pb.go and greeter/greeter.graphql.go.

Implement service

For example, gRPC service will be:

// service/main.go
package main

import (
    "context"
    "fmt"
    "net"
    "log"

    "github.com/[your/project]/greeter"
    "google.golang.org/grpc"
)

type Server struct{}

func (s *Server) SayHello(ctx context.Context, req *greeter.HelloRequest) (*greeter.HelloReply, error) {
	return &greeter.HelloReply{
		Message: fmt.Sprintf("Hello, %s!", req.GetName()),
	}, nil
}

func (s *Server) SayGoodbye(ctx context.Context, req *greeter.GoodbyeRequest) (*greeter.GoodbyeReply, error) {
	return &greeter.GoodbyeReply{
		Message: fmt.Sprintf("Good-bye, %s!", req.GetName()),
	}, nil
}

func main() {
	conn, err := net.Listen("tcp", ":500οΌ•1")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	server := grpc.NewServer()
	greeter.RegisterGreeterServer(server, &Server{})
	server.Serve(conn)
}

Then let's start service:

go run service/main.go

The gRPC service will start on localhost:50051.

Next, GraphQL gateway service should be:

// gateway/main.go
package main

import (
    "log"

    "net/http"

    "github.com/[your/project]/greeter"
    "github.com/ysugimoto/grpc-graphql-gateway/runtime"
)

func main() {
    mux := runtime.NewServeMux()

    if err := greeter.RegisterGreeterGraphql(mux); err != nil {
        log.Fatalln(err)
    }
    http.Handle("/graphql", mux)
    log.Fatalln(http.ListenAndServe(":8888", nil))
}

Then let's start gateway:

go run gateway/main.go

The GraphQL gateway will start on localhost:8888

Send request via the gateway

Now you can access gRPC service via GraphQL gateway!

curl -g "http://localhost:8888/graphql" -d '
{
  hello(name: "GraphQL Gateway") {
    message
  }
}'
#=> {"data":{"hello":{"message":"Hello, GraphQL Gateway!"}}}

You can also send request via POST method with operation name like:

curl -XPOST "http://localhost:8888/graphql" -d '
query greeting($name: String = "GraphQL Gateway") {
  hello(name: $name) {
    message
  }
  goodbye(name: $name) {
    message
  }
}'
#=> {"data":{"goodbye":{"message":"Good-bye, GraphQL Gateway!"},"hello":{"message":"Hello, GraphQL Gateway!"}}}

This is the most simplest way :-)

Resources

To learn more, please see the following resources:

  • graphql.proto Plugin option definition. See a comment section for custom usage (e.g mutation).
  • example/greeter Files of above usage.
  • example/starwars Common implementation for GraphQL explanation, the StarWars API example

This plugin generates graphql execution code using graphql-go/graphql, see that repository in detail.

Limitations

This plugin just aims to generate a simple gateway of gRPC.

Some of things could be solved and could not be solved. The most of limitations come from the IDL's power of expression -- some kind of GraphQL schema feature cannot implement by Protocol Buffers X(

Currently we don't support some Protobuf types:

  • Builtin oneof type

Contribute

  • Fork this repository
  • Customize / Fix problem
  • Send PR :-)
  • Or feel free to create issue for us. We'll look into it

Author

Yoshiaki Sugimoto

License

MIT

More Repositories

1

aws-lambda-image

Automatic image resize/reduce on AWS Lambda
JavaScript
824
star
2

webassembly-lua

Write and compile WebAssembly code with Lua
Python
119
star
3

falco

falco is a VCL parser and linter optimized for Fastly
Go
99
star
4

lua-resty-grpc-gateway

REST <-> gRPC gateway library implementation with OpenResty
Lua
85
star
5

RTCPeerConnectionSample

WebRTC peer connection video chat sample ( chrome only )
JavaScript
31
star
6

resumify

Capture screenshot and make PDF on your HTML presentation.
JavaScript
28
star
7

gssp

GSSP : Golang Style Sheet Postprocessor
Go
24
star
8

vintage

VCL Transpiler for Edge Runtime
Go
20
star
9

ginger

Serverless framework for Go runtime.
Go
16
star
10

markdown-tree-parser

Parse markdown string to Abstract Syntax Tree which we defined.
JavaScript
13
star
11

jest-preset-fastly-js-compute

Jest preset for Fastly Compute@Edge
TypeScript
11
star
12

ls3

AWS S3 file explorer on CLI
Go
11
star
13

cloudflare-worker-lambda-gateway

Example for call lambda function gateway via cloudflare worker
JavaScript
11
star
14

graphql-edge

Execute graphql on the edge
TypeScript
10
star
15

GifManipulator

Treats Animated GIF (GIF89a + Netscape Extension) on PHP-GD
PHP
10
star
16

gqtt

MQTT5 implementation by golang
Go
10
star
17

Terrier

A simple mailform written by PHP
PHP
9
star
18

js-dependency-visualizer

JavaScript Module dependency visualizer
JavaScript
9
star
19

go-kakasi

C binding library of kakasi.
Go
8
star
20

Retriever

A simple / lightweight JavaScript template engine
JavaScript
8
star
21

cloudflare-workers-github-auth

Edge-side GitHub authentication
TypeScript
8
star
22

node-memcached-client

Memcached client library for nodejs with ES6 promisified methods
JavaScript
8
star
23

metro

Windows8 metro UI on brwoser
JavaScript
7
star
24

doorkeeper

Validate Github PullRequest title and description and collect release notes.
Go
6
star
25

like-a-pinboard

Pinboard implementation for myself
JavaScript
6
star
26

go-static-server

Golang local static server for development
Go
6
star
27

grunt-sprockets

Resolve static files like rails
JavaScript
6
star
28

tailor

A tail output on any interface
JavaScript
6
star
29

ScrollBarView

Attach ScrollBar-Node for cocos2d-x's ScrollView/TableView
C++
6
star
30

gqb

Query Builder for Golang
Go
5
star
31

google-meet-api

Yet another Google Meet URL generation API
Go
5
star
32

szfw

Seezoo-Framework
PHP
5
star
33

unifee

Unify static assets into single resource
TypeScript
5
star
34

socket.io-cpp

Socket.IO Client for C++ ( use for cocos2d-x )
C
4
star
35

nw-alfred

Alfred clone on node-webkit
JavaScript
4
star
36

gang

Command tool snippet manager written by Golang
Go
4
star
37

ChatworkNotificationSelector

Enable to Select your chat desktop notification
JavaScript
4
star
38

qrterm

Read QR code from screencapture and process it
Go
3
star
39

twist

Cascade and integrate config struct from various setting files and environment.
Go
3
star
40

lua-local-resolver

Create resolver table from local hosts file
Lua
3
star
41

WebRTetris

Network play "Tetris" using WebRTC-DataChannel API
JavaScript
3
star
42

TFCRatioConverter

Convert multiple ratio published from Toolkit for CreateJS source
JavaScript
3
star
43

robots-linter

Parse and lint robots.txt
TypeScript
3
star
44

KickStart-Lite

Kickstart lightweight version of the template set by the independent jQuery
JavaScript
2
star
45

signalingo

A general signaling server for WebRTC or others
Go
2
star
46

artisan-findup

Call laravel's command-tool "artisan" at any project directory
Makefile
2
star
47

DDUploader

FileUpload with HTML5 Drap And Drop API
JavaScript
2
star
48

ChatworkAPIDriver

Library to simplify the acquisition of data and communication with the Chatwork API.
PHP
2
star
49

openfresh-api

[unofficial] openfresh API client
JavaScript
2
star
50

WebGL-Study

JavaScript
2
star
51

tfapprove

Go
2
star
52

gov

Golang versioning tool
Go
2
star
53

aun

Simple WebSocket Implementation over TCP/TLS.
Go
2
star
54

pss

PHP-CSS-Preprocessor on console/web interface
PHP
2
star
55

Spicy

Spicy is tuned Spyc Yaml Parser
PHP
2
star
56

server-timing-benchmark

Benchmark based on Server Timing API.
JavaScript
1
star
57

tf

Transfer.sh (https://transfer.sh/) utility tool written by Go
Go
1
star
58

seezoo2

JavaScript
1
star
59

esanuka

esanuka is managing idempotency tool for AWS API Gateway.
JavaScript
1
star
60

sssh

Execute SSH to selected host from .ssh/config
Go
1
star
61

jsonenv

Extract JSON-formatted environment value
Go
1
star
62

grunt-node-webkit-builder

node-webkit builder for grunt task
JavaScript
1
star
63

perooon

Example application by seezoo-framework
PHP
1
star
64

account-env-label-chrome-extension

Chrome extension to display environment label in AWS console from your config
JavaScript
1
star
65

pecolify

Transform your golang's data to peco
Go
1
star
66

mqtt-example

MQTT Sample Broker/Publisher/Subscriber implements
Go
1
star
67

kennel

My own project useful JavaScript toolkit.
JavaScript
1
star
68

go-cliargs

CLI argument parser/ manager for golang
Go
1
star
69

workers-template-zig

Template to run zig code on Cloudflare Workers
JavaScript
1
star
70

vite-plugin-fastly-js-compute

Vite plugin for Fastly Compute
TypeScript
1
star
71

fastly-costs

Calculate Fastly service costs includes Compute and VCL.
TypeScript
1
star
72

flint

Back compatible fullstack javascript framework
JavaScript
1
star