Browse Source

Use gRPC gateway

master
parent
commit
49a60d73c9
Signed by: chris GPG Key ID: 3025DCBD46F81C0F
  1. 13
      buf.gen.yaml
  2. 8
      buf.lock
  3. 9
      buf.yaml
  4. 72
      cmd/server/main.go
  5. 29
      flake.nix
  6. 14
      go.mod
  7. 32
      go.sum
  8. 2
      proto/users.pb.go
  9. 154
      proto/users.swagger.json
  10. 2
      proto/users_grpc.pb.go

13
buf.gen.yaml

@ -0,0 +1,13 @@
version: v1
plugins:
- name : go
out: .
opt: paths=source_relative
- name: go-grpc
out: .
opt: paths=source_relative
- name: grpc-gateway
out: .
opt: paths=source_relative
- name: openapiv2
out: .

8
buf.lock

@ -0,0 +1,8 @@
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 711e289f6a384c4caeebaff7c6931ade
digest: shake256:e08fb55dad7469f69df00304eed31427d2d1576e9aab31e6bf86642688e04caaf0372f15fe6974cf79432779a635b3ea401ca69c943976dc42749524e4c25d94

9
buf.yaml

@ -0,0 +1,9 @@
version: v1
deps:
- buf.build/googleapis/googleapis
breaking:
use:
- FILE
lint:
use:
- DEFAULT

72
cmd/server/main.go

@ -1,14 +1,17 @@
package main
import (
"context"
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"git.chrishayward.xyz/x/users/proto"
"git.chrishayward.xyz/x/users/server"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"gopkg.in/yaml.v3"
@ -20,8 +23,12 @@ import (
var configPath = flag.String("config", "./config/server.yaml", "--config=./config/server.yaml")
type config struct {
Port int `yaml:"port"`
Secret string `yaml:"secret"`
Port int `yaml:"port"`
Secret string `yaml:"secret"`
Gateway struct {
URL string `yaml:"url"`
Port int `yaml:"port"`
}
Database struct {
Type string `yaml:"type"`
File string `yaml:"file"`
@ -34,17 +41,28 @@ type config struct {
}
func main() {
// Parse the optional flags.
// Create the context.
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
// Parse the application flags.
flag.Parse()
// Read the config file.
config := &config{}
file, err := os.Open(*configPath)
if err != nil {
log.Fatal(err)
log.Fatalf("Failed to open config file: %v", err)
}
defer file.Close()
if err := yaml.NewDecoder(file).Decode(&config); err != nil {
log.Fatalf("Failed to read config file: %v", err)
}
// Create the server network listener.
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", config.Port))
if err != nil {
log.Fatal(err)
}
@ -65,16 +83,46 @@ func main() {
db, _ = gorm.Open(sqlite.Open(config.Database.File), &gorm.Config{})
}
// Create the network listener.
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", config.Port))
// Create the server.
grpcServer := grpc.NewServer()
proto.RegisterUsersServer(grpcServer, server.NewUsersServer(config.Secret, db))
reflection.Register(grpcServer)
go grpcServer.Serve(lis)
// Create the gateway client connection.
conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", config.Port), grpc.WithInsecure())
if err != nil {
log.Fatal(err)
log.Fatalf("Failed to create client connection: %v", err)
}
defer conn.Close()
// Create the gRPC gateway.
rmux := runtime.NewServeMux()
client := proto.NewUsersClient(conn)
err = proto.RegisterUserHandlerClient(ctx, rmux, client)
if err != nil {
log.Fatalf("Failed to register client handler: %v", err)
}
// Create a standard HTTP router.
mux := http.NewServeMux()
// Mount the gRPC gateway.
mux.Handle("/", rmux)
// Create the gRPC OpenAPI UI.
mux.HandleFunc("/swagger-ui/swagger.json", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./proto/users.swagger.json")
})
mux.Handle("/swagger-ui/",
http.StripPrefix("/swagger-ui/",
http.FileServer(http.Dir("./modules/swagger-ui/dist"))))
// Start listening for requests.
srv := grpc.NewServer()
proto.RegisterUsersServer(srv, server.NewUsersServer(config.Secret, db))
reflection.Register(srv)
log.Printf("Listening on :%d", config.Port)
srv.Serve(lis)
log.Println(fmt.Sprintf("Listening on:\n=>\tgRPC[::]:%d\n=>\tHTTP[::]:%d",
config.Port, config.Gateway.Port))
err = http.ListenAndServe(fmt.Sprintf(":%d", config.Gateway.Port), mux)
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
}

29
flake.nix

@ -9,21 +9,15 @@
inputs.flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system};
myGo = "${pkgs.go}/bin/go";
myProtoc = "${pkgs.grpc-tools}/bin/protoc";
myUsersDir = "$MY_USERS_DIR";
myUsersBuild = pkgs.writeShellScriptBin "users-build" ''
pushd ${myUsersDir} > /dev/null &&
${myProtoc} --proto_path=${myUsersDir} \
--go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
proto/users.proto &&
${myGo} build -o ${myUsersDir}/bin/users-server ${myUsersDir}/cmd/server/main.go &&
${myGo} build -o ${myUsersDir}/bin/users-gateway ${myUsersDir}/cmd/gateway/main.go &&
popd > /dev/null
'';
myUsersTest = pkgs.writeShellScriptBin "users-test" ''
pushd ${myUsersDir} > /dev/null &&
${pkgs.parallel}/bin/parallel ::: ${myUsersDir}/bin/users-server ${myUsersDir}/bin/users-gateway
myBuf = "${pkgs.buf}/bin/buf";
myDir = "$MY_USERS_DIR";
myBuild = pkgs.writeShellScriptBin "users-build" ''
pushd ${myDir} > /dev/null &&
sed -n 's,https://petstore.swagger.io/v2/swagger.json,swagger.json,g' \
${myDir}/modules/swagger-ui/dist/swagger-initializer.js &&
${myBuf} build &&
${myBuf} generate &&
${myGo} build -o ${myDir}/bin/users-server ${myDir}/cmd/server/main.go &&
popd > /dev/null
'';
in
@ -35,13 +29,14 @@
protoc-gen-go
protoc-gen-go-grpc
buf
grpc
grpcui
grpcurl
grpc-tools
grpc-gateway
myUsersBuild
myUsersTest
myBuild
];
shellHook = ''

14
go.mod

@ -4,8 +4,9 @@ go 1.20
require (
github.com/google/uuid v1.3.0
golang.org/x/crypto v0.10.0
google.golang.org/grpc v1.56.1
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2
golang.org/x/crypto v0.11.0
google.golang.org/grpc v1.57.0
google.golang.org/protobuf v1.31.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/postgres v1.5.2
@ -23,8 +24,9 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-sqlite3 v1.14.17 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230726155614-23370e0ffb3e // indirect
)

32
go.sum

@ -1,6 +1,7 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -8,6 +9,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 h1:dygLcbEBA+t/P7ck6a8AkXv6juQ4cK0RHBoh32jxhHM=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2/go.mod h1:Ap9RLCIJVtgQg1/BBgVEfypOAySvvlcpcVQkSzJCH4Y=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
@ -18,7 +21,7 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
@ -31,19 +34,22 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ=
google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw=
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230726155614-23370e0ffb3e h1:S83+ibolgyZ0bqz7KEsUOPErxcv4VzlszxY+31OfB/E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=

2
proto/users.pb.go

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
// protoc v3.15.6
// protoc (unknown)
// source: proto/users.proto
package proto

154
proto/users.swagger.json

@ -0,0 +1,154 @@
{
"swagger": "2.0",
"info": {
"title": "proto/users.proto",
"version": "version not set"
},
"tags": [
{
"name": "Users"
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {},
"definitions": {
"protobufAny": {
"type": "object",
"properties": {
"@type": {
"type": "string"
}
},
"additionalProperties": {}
},
"rpcStatus": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/protobufAny"
}
}
}
},
"usersAuthorizeResponse": {
"type": "object",
"properties": {
"user": {
"$ref": "#/definitions/usersUserInfo"
},
"roles": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/usersUserRole"
}
}
}
},
"usersChangePasswordResponse": {
"type": "object"
},
"usersListRolesResponse": {
"type": "object",
"properties": {
"roles": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/usersUserRole"
}
}
}
},
"usersLoginResponse": {
"type": "object",
"properties": {
"token": {
"$ref": "#/definitions/usersUserToken"
}
}
},
"usersLogoutResponse": {
"type": "object"
},
"usersRegisterResponse": {
"type": "object"
},
"usersResetPasswordResponse": {
"type": "object",
"properties": {
"token": {
"$ref": "#/definitions/usersUserToken"
}
}
},
"usersSetRolesResponse": {
"type": "object"
},
"usersUserForm": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"passwordAgain": {
"type": "string"
}
}
},
"usersUserInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "int64"
},
"uuid": {
"type": "string"
}
}
},
"usersUserRole": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "int64"
},
"name": {
"type": "string"
}
}
},
"usersUserToken": {
"type": "object",
"properties": {
"token": {
"type": "string"
},
"expires": {
"type": "string",
"format": "int64"
}
}
}
}
}

2
proto/users_grpc.pb.go

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v3.15.6
// - protoc (unknown)
// source: proto/users.proto
package proto

Loading…
Cancel
Save