Skip to content

Commit

Permalink
Add an example of calling gateway from browser
Browse files Browse the repository at this point in the history
  • Loading branch information
yugui committed Jun 14, 2016
1 parent dcb8443 commit 03bbacf
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 9 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ install:
- go get github.com/gengo/grpc-gateway/runtime
- go get github.com/gengo/grpc-gateway/examples
- go get github.com/gengo/grpc-gateway/examples/server
before_script:
- sh -c 'cd examples/browser && npm install'
- npm install -g gulp
script:
- make realclean && make examples SWAGGER_CODEGEN="java -jar $HOME/local/swagger-codegen-cli.jar"
- if ! go version | grep devel; then test -z "$(git status --porcelain)" || (git status; git diff; exit 1); fi
- env GLOG_logtostderr=1 go test -race -v github.com/gengo/grpc-gateway/...
- make lint
- sh -c 'cd examples/browser && gulp'
env:
global:
- "PATH=$PATH:$HOME/local/bin"
2 changes: 2 additions & 0 deletions examples/browser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/bower_components
/node_modules
10 changes: 10 additions & 0 deletions examples/browser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Browser example

This directory contains an example use of grpc-gateway with web browsers.
The following commands automatically check `index.html` with a headless browser.

```shell-session
$ npm install -g gulp-cli
$ npm install
$ gulp
```
2 changes: 2 additions & 0 deletions examples/browser/bin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/*
!/.gitignore
21 changes: 21 additions & 0 deletions examples/browser/bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "grpc-gateway-example-browser",
"description": "Example use of grpc-gateway from browser",
"main": "index.js",
"authors": [
"Yuki Yugui Sonoda <[email protected]>"
],
"license": "SEE LICENSE IN LICENSE file",
"homepage": "https://github.com/gengo/grpc-gateway",
"private": true,
"dependencies": {
"swagger-js": "~> 2.1"
},
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
17 changes: 17 additions & 0 deletions examples/browser/echo_service.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const Browser = require('zombie');

Browser.localhost('localhost', 3000);

describe('Visits example page', function() {
const browser = new Browser();
before(function(done) {
browser.visit("/index.html", done);
});

it('should be successful', function() {
browser.assert.success();
});
it('should show echo back from gRPC service', function() {
browser.assert.text('#echoBack', 'bar');
});
});
49 changes: 49 additions & 0 deletions examples/browser/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
var gulp = require('gulp');

var path = require('path');

var bower = require('gulp-bower');
var exit = require('gulp-exit');
var mocha = require('gulp-mocha');
var gprocess = require('gulp-process');
var serve = require('gulp-serve');
var shell = require('gulp-shell');
var wait = require('gulp-wait');

gulp.task('bower', function(){
return bower();
});

gulp.task('server', shell.task([
'go build -o bin/example-server github.com/gengo/grpc-gateway/examples/server',
]));

gulp.task('gateway', shell.task([
'go build -o bin/example-gw github.com/gengo/grpc-gateway/examples',
]));

gulp.task('serve-server', ['server'], function(){
gprocess.start('server-server', 'bin/example-server', [
'--logtostderr',
]);
gulp.watch('bin/example-server', ['server']);
});

gulp.task('serve-gateway', ['gateway', 'serve-server'], function(){
gprocess.start('gateway-server', 'bin/example-gw', [
'--logtostderr', '--swagger_dir', path.resolve("../examplepb"),
]);
gulp.watch('bin/example-gateway', ['gateway']);
});

gulp.task('serve', serve('.'));

gulp.task('mocha', ['bower', 'serve', 'serve-gateway', 'serve-server'], function(done) {
var l = gulp.src(['echo_service.test.js'], {read: false})
.pipe(wait(1500))
.pipe(mocha())
.on('error', function(err) { done(err); process.exit(1); })
.pipe(exit());
});

gulp.task('default', ['mocha']);
22 changes: 22 additions & 0 deletions examples/browser/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<script type="application/javascript" src="bower_components/swagger-js/browser/swagger-client.min.js"></script>
<script type="application/javascript">
window.client = new SwaggerClient({
url: "http://localhost:8080/swagger/echo_service.swagger.json",
success: function() {
client.EchoService.Echo(
{id: "foo"},
{responseContentType: "application/json"},
function(data) {
document.getElementById("echoBack").innerHTML = data.obj.id;
});
}
})
</script>
</head>
<body>
<div id="echoBack"></div>
</body>
</html>
23 changes: 23 additions & 0 deletions examples/browser/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "grpc-gateway-example",
"version": "1.0.0",
"description": "Example use of grpc-gateway from browser",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "SEE LICENSE IN LICENSE.txt",
"devDependencies": {
"bower": "^1.7.9",
"gulp": "^3.9.1",
"gulp-bower": "0.0.13",
"gulp-exit": "0.0.2",
"gulp-mocha": "^2.2.0",
"gulp-process": "^0.1.2",
"gulp-serve": "^1.2.0",
"gulp-shell": "^0.5.2",
"gulp-wait": "0.0.2",
"mocha": "^2.5.3",
"zombie": "^4.2.1"
}
}
59 changes: 50 additions & 9 deletions examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package main
import (
"flag"
"net/http"
"path"
"strings"

"github.com/gengo/grpc-gateway/examples/examplepb"
"github.com/gengo/grpc-gateway/runtime"
Expand All @@ -15,33 +17,72 @@ var (
echoEndpoint = flag.String("echo_endpoint", "localhost:9090", "endpoint of EchoService")
abeEndpoint = flag.String("more_endpoint", "localhost:9090", "endpoint of ABitOfEverythingService")
flowEndpoint = flag.String("flow_endpoint", "localhost:9090", "endpoint of FlowCombination")
)

func Run(address string, opts ...runtime.ServeMuxOption) error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
swaggerDir = flag.String("swagger_dir", "examples/examplepb", "path to the directory which contains swagger definitions")
)

// newGateway returns a new gateway server which translates HTTP into gRPC.
func newGateway(ctx context.Context, opts ...runtime.ServeMuxOption) (http.Handler, error) {
mux := runtime.NewServeMux(opts...)
dialOpts := []grpc.DialOption{grpc.WithInsecure()}
err := examplepb.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, dialOpts)
if err != nil {
return err
return nil, err
}
err = examplepb.RegisterStreamServiceHandlerFromEndpoint(ctx, mux, *abeEndpoint, dialOpts)
if err != nil {
return err
return nil, err
}
err = examplepb.RegisterABitOfEverythingServiceHandlerFromEndpoint(ctx, mux, *abeEndpoint, dialOpts)
if err != nil {
return err
return nil, err
}
err = examplepb.RegisterFlowCombinationHandlerFromEndpoint(ctx, mux, *flowEndpoint, dialOpts)
if err != nil {
return nil, err
}
return mux, nil
}

func serveSwagger(w http.ResponseWriter, r *http.Request) {
if !strings.HasSuffix(r.URL.Path, ".swagger.json") {
glog.Errorf("Not Found: %s", r.URL.Path)
http.NotFound(w, r)
return
}

glog.Infof("Serving %s", r.URL.Path)
p := strings.TrimPrefix(r.URL.Path, "/swagger/")
p = path.Join(*swaggerDir, p)
http.ServeFile(w, r, p)
}

// allowCROS allows Cross Origin Resoruce Sharing from any origin.
func allowCROS(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if origin := r.Header.Get("Origin"); origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
}
h.ServeHTTP(w, r)
})
}

// Run starts a HTTP server and blocks forever if successful.
func Run(address string, opts ...runtime.ServeMuxOption) error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()

mux := http.NewServeMux()
mux.HandleFunc("/swagger/", serveSwagger)

gw, err := newGateway(ctx, opts...)
if err != nil {
return err
}
mux.Handle("/", gw)

http.ListenAndServe(address, mux)
http.ListenAndServe(address, allowCROS(mux))
return nil
}

Expand Down

0 comments on commit 03bbacf

Please sign in to comment.