diff --git a/build.go b/build.go index ef31b54..0172d96 100644 --- a/build.go +++ b/build.go @@ -55,9 +55,10 @@ func Build(conf *config.Config, goPath string) { mappedTypeScript := map[string]map[string]*code{} for name, target := range conf.Targets { fmt.Fprintln(os.Stderr, "building target", name) + longPackageName := target.Package longPackageNameParts := strings.Split(longPackageName, "/") - goRPCProxiesFilename := path.Join(goPath, "src", longPackageName, "gorpc.go") + goRPCProxiesFilename := path.Join(goPath, "src", longPackageName, "gorpc.go") goRPCClientsFilename := path.Join(goPath, "src", longPackageName, "gorpcclient.go") goTSRPCProxiesFilename := path.Join(goPath, "src", longPackageName, "gotsrpc.go") goTSRPCClientsFilename := path.Join(goPath, "src", longPackageName, "gotsrpcclient.go") @@ -83,7 +84,7 @@ func Build(conf *config.Config, goPath string) { os.Exit(2) } - ts, err := RenderTypeScriptServices(conf.ModuleKind, services, conf.Mappings, scalarTypes, target.TypeScriptModule) + ts, err := RenderTypeScriptServices(conf.ModuleKind, services, conf.Mappings, scalarTypes, target) if err != nil { fmt.Fprintln(os.Stderr, " could not generate ts code", err) os.Exit(3) @@ -122,29 +123,29 @@ func Build(conf *config.Config, goPath string) { } } - goTSRPCProxiesCode, goerr := RenderGoTSRPCProxies(services, longPackageName, packageName) + goTSRPCProxiesCode, goerr := RenderGoTSRPCProxies(services, longPackageName, packageName, target) if goerr != nil { fmt.Fprintln(os.Stderr, " could not generate go ts rpc proxies code in target", name, goerr) os.Exit(4) } formatAndWrite(goTSRPCProxiesCode, goTSRPCProxiesFilename) - goTSRPCClientsCode, goerr := RenderGoTSRPCClients(services, longPackageName, packageName) + goTSRPCClientsCode, goerr := RenderGoTSRPCClients(services, longPackageName, packageName, target) if goerr != nil { fmt.Fprintln(os.Stderr, " could not generate go ts rpc clients code in target", name, goerr) os.Exit(4) } formatAndWrite(goTSRPCClientsCode, goTSRPCClientsFilename) - if target.RPC == true { - goRPCProxiesCode, goerr := RenderGoRPCProxies(services, longPackageName, packageName) + if len(target.GoRPC) > 0 { + goRPCProxiesCode, goerr := RenderGoRPCProxies(services, longPackageName, packageName, target) if goerr != nil { fmt.Fprintln(os.Stderr, " could not generate go rpc proxies code in target", name, goerr) os.Exit(4) } formatAndWrite(goRPCProxiesCode, goRPCProxiesFilename) - goRPCClientsCode, goerr := RenderGoRPCClients(services, longPackageName, packageName) + goRPCClientsCode, goerr := RenderGoRPCClients(services, longPackageName, packageName, target) if goerr != nil { fmt.Fprintln(os.Stderr, " could not generate go rpc clients code in target", name, goerr) os.Exit(4) @@ -152,6 +153,7 @@ func Build(conf *config.Config, goPath string) { formatAndWrite(goRPCClientsCode, goRPCClientsFilename) } } + // spew.Dump(mappedTypeScript) for goPackage, mappedStructsMap := range mappedTypeScript { mapping, ok := conf.Mappings[goPackage] diff --git a/cmd/demo/demo.go b/cmd/demo/demo.go index f81e316..e7bb9ac 100644 --- a/cmd/demo/demo.go +++ b/cmd/demo/demo.go @@ -39,7 +39,7 @@ func serveFile(name string, w http.ResponseWriter) { func main() { d := &Demo{ - proxy: demo.NewServiceGoTSRPCProxy(&demo.Service{}, "/service"), + proxy: demo.NewServiceGoTSRPCProxy(&demo.Demo{}, "/service"), } fmt.Println(http.ListenAndServe(":8080", d)) } diff --git a/config/config.go b/config/config.go index 8e94952..b6e5734 100644 --- a/config/config.go +++ b/config/config.go @@ -9,11 +9,33 @@ import ( ) type Target struct { - Package string `yaml:"package"` + Package string `yaml:"package"` Services map[string]string `yaml:"services"` - TypeScriptModule string `yaml:"module"` - Out string `yaml:"out"` - RPC bool `yaml:"rpc"` + TypeScriptModule string `yaml:"module"` + Out string `yaml:"out"` + GoRPC []string `yaml:"gorpc"` + TSRPC []string `yaml:"tsrpc"` +} + +func (t *Target) IsGoRPC(service string) bool { + for _, value := range t.GoRPC { + if value == service { + return true + } + } + return false +} + +func (t *Target) IsTSRPC(service string) bool { + if len(t.TSRPC) == 0 { + return true + } + for _, value := range t.TSRPC { + if value == service { + return true + } + } + return false } type Mapping struct { diff --git a/demo/config.yml b/demo/config.yml index 9778152..8bacaf5 100644 --- a/demo/config.yml +++ b/demo/config.yml @@ -3,10 +3,14 @@ targets: demo: module: GoTSRPC.Demo services: - /service/demo: Service + /service/foo: Foo + /service/demo: Demo package: github.com/foomo/gotsrpc/demo out: /tmp/test.ts - rpc: true + gorpc: + - Foo + - Demo + mappings: github.com/foomo/gotsrpc/demo: module: GoTSRPC.Demo diff --git a/demo/demo.go b/demo/demo.go index 369b92c..16714f0 100644 --- a/demo/demo.go +++ b/demo/demo.go @@ -6,21 +6,17 @@ type Err struct { type ScalarInPlace string -type Service struct { +type Demo struct { Bla bool } -func (s *Service) Hello(name string) (reply string, err *Err) { +func (d *Demo) Hello(name string) (reply string, err *Err) { if name == "Peter" { return "", &Err{"fuck you Peter I do not like you"} } return "Hello from the server: " + name, nil } -func sepp(bar bool) string { - return "ich bin der sepp" -} - -func (s *Service) nothingInNothinOut() { +func (d *Demo) nothingInNothinOut() { } diff --git a/demo/complex.go b/demo/demo_complex.go similarity index 75% rename from demo/complex.go rename to demo/demo_complex.go index 278593f..44fb73e 100644 --- a/demo/complex.go +++ b/demo/demo_complex.go @@ -30,22 +30,26 @@ type Person struct { iAmPrivate string } -func (s *Service) ExtractAddress(person *Person) (addr *Address, e *Err) { +func (d *Demo) ExtractAddress(person *Person) (addr *Address, e *Err) { if person.AddressPtr != nil { return person.AddressPtr, nil } return nil, &Err{"there is no address on that person"} } -func (s *Service) TestScalarInPlace() ScalarInPlace { +func (d *Demo) TestScalarInPlace() ScalarInPlace { return ScalarInPlace("hier") } -func (s *Service) Nest() *nstd.Nested { +func (d *Demo) MapCrap() (crap map[string][]int) { + return map[string][]int{} +} + +func (d *Demo) Nest() *nstd.Nested { return nil } -func (s *Service) GiveMeAScalar() (amount nstd.Amount, wahr nstd.True, hier ScalarInPlace) { +func (d *Demo) GiveMeAScalar() (amount nstd.Amount, wahr nstd.True, hier ScalarInPlace) { //func (s *Service) giveMeAScalar() (amount nstd.Amount, wahr nstd.True, hier ScalarInPlace) { return nstd.Amount(10), nstd.ItIsTrue, ScalarInPlace("hier") } diff --git a/demo/gorpc.go b/demo/gorpc.go index 5c05246..1e8d6f6 100644 --- a/demo/gorpc.go +++ b/demo/gorpc.go @@ -14,9 +14,83 @@ import ( ) type ( - ServiceGoRPCProxy struct { + FooGoRPCProxy struct { server *gorpc.Server - service *Service + service *Foo + callStatsHandler gotsrpc.GoRPCCallStatsHandlerFun + } + + HelloRequest struct { + Number int64 + } + HelloResponse struct { + RetHello_0 int + } +) + +func init() { + gob.Register(HelloRequest{}) + gob.Register(HelloResponse{}) +} + +func NewFooGoRPCProxy(addr string, service *Foo, tlsConfig *tls.Config) *FooGoRPCProxy { + proxy := &FooGoRPCProxy{ + service: service, + } + + if tlsConfig != nil { + proxy.server = gorpc.NewTLSServer(addr, proxy.handler, tlsConfig) + } else { + proxy.server = gorpc.NewTCPServer(addr, proxy.handler) + } + + return proxy +} + +func (p *FooGoRPCProxy) Start() error { + return p.server.Start() +} + +func (p *FooGoRPCProxy) Stop() { + p.server.Stop() +} + +func (p *FooGoRPCProxy) SetCallStatsHandler(handler gotsrpc.GoRPCCallStatsHandlerFun) { + p.callStatsHandler = handler +} + +func (p *FooGoRPCProxy) handler(clientAddr string, request interface{}) (response interface{}) { + start := time.Now() + + reqType := reflect.TypeOf(request).String() + funcNameParts := strings.Split(reqType, ".") + funcName := funcNameParts[len(funcNameParts)-1] + + switch funcName { + case "HelloRequest": + req := request.(HelloRequest) + retHello_0 := p.service.Hello(req.Number) + response = HelloResponse{RetHello_0: retHello_0} + default: + fmt.Println("Unkown request type", reflect.TypeOf(request).String()) + } + + if p.callStatsHandler != nil { + p.callStatsHandler(&gotsrpc.CallStats{ + Func: funcName, + Package: "github.com/foomo/gotsrpc/demo", + Service: "Foo", + Execution: time.Since(start), + }) + } + + return +} + +type ( + DemoGoRPCProxy struct { + server *gorpc.Server + service *Demo callStatsHandler gotsrpc.GoRPCCallStatsHandlerFun } @@ -44,6 +118,12 @@ type ( Err *Err } + MapCrapRequest struct { + } + MapCrapResponse struct { + Crap map[string][]int + } + NestRequest struct { } NestResponse struct { @@ -64,14 +144,16 @@ func init() { gob.Register(GiveMeAScalarResponse{}) gob.Register(HelloRequest{}) gob.Register(HelloResponse{}) + gob.Register(MapCrapRequest{}) + gob.Register(MapCrapResponse{}) gob.Register(NestRequest{}) gob.Register(NestResponse{}) gob.Register(TestScalarInPlaceRequest{}) gob.Register(TestScalarInPlaceResponse{}) } -func NewServiceGoRPCProxy(addr string, service *Service, tlsConfig *tls.Config) *ServiceGoRPCProxy { - proxy := &ServiceGoRPCProxy{ +func NewDemoGoRPCProxy(addr string, service *Demo, tlsConfig *tls.Config) *DemoGoRPCProxy { + proxy := &DemoGoRPCProxy{ service: service, } @@ -84,19 +166,19 @@ func NewServiceGoRPCProxy(addr string, service *Service, tlsConfig *tls.Config) return proxy } -func (p *ServiceGoRPCProxy) Start() error { +func (p *DemoGoRPCProxy) Start() error { return p.server.Start() } -func (p *ServiceGoRPCProxy) Stop() { +func (p *DemoGoRPCProxy) Stop() { p.server.Stop() } -func (p *ServiceGoRPCProxy) SetCallStatsHandler(handler gotsrpc.GoRPCCallStatsHandlerFun) { +func (p *DemoGoRPCProxy) SetCallStatsHandler(handler gotsrpc.GoRPCCallStatsHandlerFun) { p.callStatsHandler = handler } -func (p *ServiceGoRPCProxy) handler(clientAddr string, request interface{}) (response interface{}) { +func (p *DemoGoRPCProxy) handler(clientAddr string, request interface{}) (response interface{}) { start := time.Now() reqType := reflect.TypeOf(request).String() @@ -115,6 +197,9 @@ func (p *ServiceGoRPCProxy) handler(clientAddr string, request interface{}) (res req := request.(HelloRequest) reply, err := p.service.Hello(req.Name) response = HelloResponse{Reply: reply, Err: err} + case "MapCrapRequest": + crap := p.service.MapCrap() + response = MapCrapResponse{Crap: crap} case "NestRequest": retNest_0 := p.service.Nest() response = NestResponse{RetNest_0: retNest_0} @@ -129,7 +214,7 @@ func (p *ServiceGoRPCProxy) handler(clientAddr string, request interface{}) (res p.callStatsHandler(&gotsrpc.CallStats{ Func: funcName, Package: "github.com/foomo/gotsrpc/demo", - Service: "Service", + Service: "Demo", Execution: time.Since(start), }) } diff --git a/demo/gorpcclient.go b/demo/gorpcclient.go index a8a2001..09118a6 100644 --- a/demo/gorpcclient.go +++ b/demo/gorpcclient.go @@ -7,12 +7,12 @@ import ( gorpc "github.com/valyala/gorpc" ) -type ServiceGoRPCClient struct { +type FooGoRPCClient struct { client *gorpc.Client } -func NewServiceGoRPCClient(addr string, tlsConfig *tls.Config) *ServiceGoRPCClient { - client := &ServiceGoRPCClient{} +func NewFooGoRPCClient(addr string, tlsConfig *tls.Config) *FooGoRPCClient { + client := &FooGoRPCClient{} if tlsConfig == nil { client.client = gorpc.NewTCPClient(addr) } else { @@ -22,15 +22,49 @@ func NewServiceGoRPCClient(addr string, tlsConfig *tls.Config) *ServiceGoRPCClie return client } -func (c *ServiceGoRPCClient) Start() { +func (c *FooGoRPCClient) Start() { c.client.Start() } -func (c *ServiceGoRPCClient) Stop() { +func (c *FooGoRPCClient) Stop() { c.client.Stop() } -func (c *ServiceGoRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) { +func (c *FooGoRPCClient) Hello(number int64) (retHello_0 int, clientErr error) { + req := HelloRequest{Number: number} + res, err := c.client.Call(req) + if err != nil { + clientErr = err + return + } + response := res.(HelloResponse) + return response.RetHello_0, nil +} + +type DemoGoRPCClient struct { + client *gorpc.Client +} + +func NewDemoGoRPCClient(addr string, tlsConfig *tls.Config) *DemoGoRPCClient { + client := &DemoGoRPCClient{} + if tlsConfig == nil { + client.client = gorpc.NewTCPClient(addr) + } else { + client.client = gorpc.NewTLSClient(addr, tlsConfig) + } + client.Start() + return client +} + +func (c *DemoGoRPCClient) Start() { + c.client.Start() +} + +func (c *DemoGoRPCClient) Stop() { + c.client.Stop() +} + +func (c *DemoGoRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) { req := ExtractAddressRequest{Person: person} res, err := c.client.Call(req) if err != nil { @@ -41,7 +75,7 @@ func (c *ServiceGoRPCClient) ExtractAddress(person *Person) (addr *Address, e *E return response.Addr, response.E, nil } -func (c *ServiceGoRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) { +func (c *DemoGoRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) { req := GiveMeAScalarRequest{} res, err := c.client.Call(req) if err != nil { @@ -52,7 +86,7 @@ func (c *ServiceGoRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested. return response.Amount, response.Wahr, response.Hier, nil } -func (c *ServiceGoRPCClient) Hello(name string) (reply string, err *Err, clientErr error) { +func (c *DemoGoRPCClient) Hello(name string) (reply string, err *Err, clientErr error) { req := HelloRequest{Name: name} res, err := c.client.Call(req) if err != nil { @@ -63,7 +97,18 @@ func (c *ServiceGoRPCClient) Hello(name string) (reply string, err *Err, clientE return response.Reply, response.Err, nil } -func (c *ServiceGoRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) { +func (c *DemoGoRPCClient) MapCrap() (crap map[string][]int, clientErr error) { + req := MapCrapRequest{} + res, err := c.client.Call(req) + if err != nil { + clientErr = err + return + } + response := res.(MapCrapResponse) + return response.Crap, nil +} + +func (c *DemoGoRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) { req := NestRequest{} res, err := c.client.Call(req) if err != nil { @@ -74,7 +119,7 @@ func (c *ServiceGoRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) return response.RetNest_0, nil } -func (c *ServiceGoRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) { +func (c *DemoGoRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) { req := TestScalarInPlaceRequest{} res, err := c.client.Call(req) if err != nil { diff --git a/demo/gotsrpc.go b/demo/gotsrpc.go index d6e6e3f..803fc89 100644 --- a/demo/gotsrpc.go +++ b/demo/gotsrpc.go @@ -7,22 +7,22 @@ import ( time "time" ) -type ServiceGoTSRPCProxy struct { +type FooGoTSRPCProxy struct { EndPoint string allowOrigin []string - service *Service + service *Foo } -func NewDefaultServiceGoTSRPCProxy(service *Service, allowOrigin []string) *ServiceGoTSRPCProxy { - return &ServiceGoTSRPCProxy{ - EndPoint: "/service/demo", +func NewDefaultFooGoTSRPCProxy(service *Foo, allowOrigin []string) *FooGoTSRPCProxy { + return &FooGoTSRPCProxy{ + EndPoint: "/service/foo", allowOrigin: allowOrigin, service: service, } } -func NewServiceGoTSRPCProxy(service *Service, endpoint string, allowOrigin []string) *ServiceGoTSRPCProxy { - return &ServiceGoTSRPCProxy{ +func NewFooGoTSRPCProxy(service *Foo, endpoint string, allowOrigin []string) *FooGoTSRPCProxy { + return &FooGoTSRPCProxy{ EndPoint: endpoint, allowOrigin: allowOrigin, service: service, @@ -30,7 +30,7 @@ func NewServiceGoTSRPCProxy(service *Service, endpoint string, allowOrigin []str } // ServeHTTP exposes your service -func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (p *FooGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { for _, origin := range p.allowOrigin { // todo we have to compare this with the referer ... and only send one @@ -51,7 +51,73 @@ func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) if callStats != nil { callStats.Func = funcName callStats.Package = "github.com/foomo/gotsrpc/demo" - callStats.Service = "Service" + callStats.Service = "Foo" + } + switch funcName { + case "Hello": + args = []interface{}{int64(0)} + err := gotsrpc.LoadArgs(args, callStats, r) + if err != nil { + gotsrpc.ErrorCouldNotLoadArgs(w) + return + } + executionStart := time.Now() + helloRet := p.service.Hello(int64(args[0].(float64))) + if callStats != nil { + callStats.Execution = time.Now().Sub(executionStart) + } + gotsrpc.Reply([]interface{}{helloRet}, callStats, r, w) + return + default: + http.Error(w, "404 - not found "+r.URL.Path, http.StatusNotFound) + } +} + +type DemoGoTSRPCProxy struct { + EndPoint string + allowOrigin []string + service *Demo +} + +func NewDefaultDemoGoTSRPCProxy(service *Demo, allowOrigin []string) *DemoGoTSRPCProxy { + return &DemoGoTSRPCProxy{ + EndPoint: "/service/demo", + allowOrigin: allowOrigin, + service: service, + } +} + +func NewDemoGoTSRPCProxy(service *Demo, endpoint string, allowOrigin []string) *DemoGoTSRPCProxy { + return &DemoGoTSRPCProxy{ + EndPoint: endpoint, + allowOrigin: allowOrigin, + service: service, + } +} + +// ServeHTTP exposes your service +func (p *DemoGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { + + for _, origin := range p.allowOrigin { + // todo we have to compare this with the referer ... and only send one + w.Header().Add("Access-Control-Allow-Origin", origin) + } + w.Header().Set("Access-Control-Allow-Credentials", "true") + if r.Method != http.MethodPost { + if r.Method == http.MethodOptions { + return + } + gotsrpc.ErrorMethodNotAllowed(w) + return + } + + var args []interface{} + funcName := gotsrpc.GetCalledFunc(r, p.EndPoint) + callStats := gotsrpc.GetStatsForRequest(r) + if callStats != nil { + callStats.Func = funcName + callStats.Package = "github.com/foomo/gotsrpc/demo" + callStats.Service = "Demo" } switch funcName { case "ExtractAddress": @@ -90,6 +156,14 @@ func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) } gotsrpc.Reply([]interface{}{helloReply, helloErr}, callStats, r, w) return + case "MapCrap": + executionStart := time.Now() + mapCrapCrap := p.service.MapCrap() + if callStats != nil { + callStats.Execution = time.Now().Sub(executionStart) + } + gotsrpc.Reply([]interface{}{mapCrapCrap}, callStats, r, w) + return case "Nest": executionStart := time.Now() nestRet := p.service.Nest() diff --git a/demo/gotsrpcclient.go b/demo/gotsrpcclient.go index dfa5ed2..e4afe3a 100644 --- a/demo/gotsrpcclient.go +++ b/demo/gotsrpcclient.go @@ -6,51 +6,81 @@ import ( nested "github.com/foomo/gotsrpc/demo/nested" ) -type ServiceGoTSRPCClient struct { +type FooGoTSRPCClient struct { URL string EndPoint string } -func NewDefaultServiceGoTSRPCClient(url string) *ServiceGoTSRPCClient { - return NewServiceGoTSRPCClient(url, "/service/demo") +func NewDefaultFooGoTSRPCClient(url string) *FooGoTSRPCClient { + return NewFooGoTSRPCClient(url, "/service/foo") } -func NewServiceGoTSRPCClient(url string, endpoint string) *ServiceGoTSRPCClient { - return &ServiceGoTSRPCClient{ +func NewFooGoTSRPCClient(url string, endpoint string) *FooGoTSRPCClient { + return &FooGoTSRPCClient{ URL: url, EndPoint: endpoint, } } -func (c *ServiceGoTSRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) { +func (c *FooGoTSRPCClient) Hello(number int64) (retHello_0 int, clientErr error) { + args := []interface{}{number} + reply := []interface{}{&retHello_0} + clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "Hello", args, reply) + return +} + +type DemoGoTSRPCClient struct { + URL string + EndPoint string +} + +func NewDefaultDemoGoTSRPCClient(url string) *DemoGoTSRPCClient { + return NewDemoGoTSRPCClient(url, "/service/demo") +} + +func NewDemoGoTSRPCClient(url string, endpoint string) *DemoGoTSRPCClient { + return &DemoGoTSRPCClient{ + URL: url, + EndPoint: endpoint, + } +} + +func (c *DemoGoTSRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) { args := []interface{}{person} reply := []interface{}{&addr, &e} clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "ExtractAddress", args, reply) return } -func (c *ServiceGoTSRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) { +func (c *DemoGoTSRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) { args := []interface{}{} reply := []interface{}{&amount, &wahr, &hier} clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "GiveMeAScalar", args, reply) return } -func (c *ServiceGoTSRPCClient) Hello(name string) (reply string, err *Err, clientErr error) { +func (c *DemoGoTSRPCClient) Hello(name string) (reply string, err *Err, clientErr error) { args := []interface{}{name} reply := []interface{}{&reply, &err} clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "Hello", args, reply) return } -func (c *ServiceGoTSRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) { +func (c *DemoGoTSRPCClient) MapCrap() (crap map[string][]int, clientErr error) { + args := []interface{}{} + reply := []interface{}{&crap} + clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "MapCrap", args, reply) + return +} + +func (c *DemoGoTSRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) { args := []interface{}{} reply := []interface{}{&retNest_0} clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "Nest", args, reply) return } -func (c *ServiceGoTSRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) { +func (c *DemoGoTSRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) { args := []interface{}{} reply := []interface{}{&retTestScalarInPlace_0} clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "TestScalarInPlace", args, reply) diff --git a/go.go b/go.go index 4bb6517..0919c58 100644 --- a/go.go +++ b/go.go @@ -3,6 +3,8 @@ package gotsrpc import ( "fmt" "strings" + + "github.com/foomo/gotsrpc/config" ) func (v *Value) isHTTPResponseWriter() bool { @@ -27,6 +29,8 @@ func (v *Value) goType(aliases map[string]string, packageName string) (t string) t += aliases[v.StructType.Package] + "." } t += v.StructType.Name + case v.Map != nil: + t += `map[` + v.Map.KeyType + `]` + v.Map.Value.goType(aliases, packageName) case v.Scalar != nil: // TODO this is a hack to retrieve string types if packageName != v.Scalar.Package { @@ -35,6 +39,7 @@ func (v *Value) goType(aliases map[string]string, packageName string) (t string) t += v.Scalar.Name[len(v.Scalar.Package)+1:] default: // TODO + fmt.Println("WARN: can't resolve goType") } return @@ -124,7 +129,6 @@ func strfirst(str string, strfunc func(string) string) string { } return res - } func extractImports(fields []*Field, fullPackageName string, aliases map[string]string) { @@ -159,15 +163,20 @@ func extractImports(fields []*Field, fullPackageName string, aliases map[string] } } -func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName string, packageName string, g *code) error { +func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName string, packageName string, config *config.Target, g *code) error { aliases := map[string]string{ "time": "time", "net/http": "http", "github.com/foomo/gotsrpc": "gotsrpc", } - for _, s := range services { - for _, m := range s.Methods { + for _, service := range services { + // Check if we should render this service as ts rcp + // Note: remove once there's a separate gorcp generator + if !config.IsTSRPC(service.Name) { + continue + } + for _, m := range service.Methods { extractImports(m.Args, fullPackageName, aliases) } } @@ -185,6 +194,12 @@ func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName str ) `) for endpoint, service := range services { + // Check if we should render this service as ts rcp + // Note: remove once there's a separate gorcp generator + if !config.IsTSRPC(service.Name) { + continue + } + proxyName := service.Name + "GoTSRPCProxy" g.l(` type ` + proxyName + ` struct { @@ -329,13 +344,18 @@ func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName str return nil } -func renderTSRPCServiceClients(services map[string]*Service, fullPackageName string, packageName string, g *code) error { +func renderTSRPCServiceClients(services map[string]*Service, fullPackageName string, packageName string, config *config.Target, g *code) error { aliases := map[string]string{ "github.com/foomo/gotsrpc": "gotsrpc", } - for _, s := range services { - for _, m := range s.Methods { + for _, service := range services { + // Check if we should render this service as ts rcp + // Note: remove once there's a separate gorcp generator + if !config.IsTSRPC(service.Name) { + continue + } + for _, m := range service.Methods { extractImports(m.Args, fullPackageName, aliases) extractImports(m.Return, fullPackageName, aliases) } @@ -354,6 +374,12 @@ func renderTSRPCServiceClients(services map[string]*Service, fullPackageName str ) `) for endpoint, service := range services { + // Check if we should render this service as ts rcp + // Note: remove once there's a separate gorcp generator + if !config.IsTSRPC(service.Name) { + continue + } + clientName := service.Name + "GoTSRPCClient" g.l(` type ` + clientName + ` struct { @@ -402,7 +428,7 @@ func renderTSRPCServiceClients(services map[string]*Service, fullPackageName str return nil } -func renderRPCServiceProxies(services map[string]*Service, fullPackageName string, packageName string, g *code) error { +func renderGoRPCServiceProxies(services map[string]*Service, fullPackageName string, packageName string, config *config.Target, g *code) error { aliases := map[string]string{ "fmt": "fmt", "time": "time", @@ -414,8 +440,12 @@ func renderRPCServiceProxies(services map[string]*Service, fullPackageName strin "github.com/foomo/gotsrpc": "gotsrpc", } - for _, s := range services { - for _, m := range s.Methods { + for _, service := range services { + if !config.IsGoRPC(service.Name) { + continue + } + + for _, m := range service.Methods { extractImports(m.Args, fullPackageName, aliases) extractImports(m.Return, fullPackageName, aliases) } @@ -433,7 +463,12 @@ func renderRPCServiceProxies(services map[string]*Service, fullPackageName strin ` + imports + ` ) `) + for _, service := range services { + if !config.IsGoRPC(service.Name) { + continue + } + proxyName := service.Name + "GoRPCProxy" // Types g.l(`type (`) @@ -498,7 +533,7 @@ func renderRPCServiceProxies(services map[string]*Service, fullPackageName strin p.server.Stop() } - func (p *ServiceGoRPCProxy) SetCallStatsHandler(handler gotsrpc.GoRPCCallStatsHandlerFun) { + func (p *` + proxyName + `) SetCallStatsHandler(handler gotsrpc.GoRPCCallStatsHandlerFun) { p.callStatsHandler = handler } `) @@ -557,14 +592,17 @@ func renderRPCServiceProxies(services map[string]*Service, fullPackageName strin return nil } -func renderRPCServiceClients(services map[string]*Service, fullPackageName string, packageName string, g *code) error { +func renderGoRPCServiceClients(services map[string]*Service, fullPackageName string, packageName string, config *config.Target, g *code) error { aliases := map[string]string{ "crypto/tls": "tls", "github.com/valyala/gorpc": "gorpc", } - for _, s := range services { - for _, m := range s.Methods { + for _, service := range services { + if !config.IsGoRPC(service.Name) { + continue + } + for _, m := range service.Methods { extractImports(m.Args, fullPackageName, aliases) extractImports(m.Return, fullPackageName, aliases) } @@ -583,6 +621,9 @@ func renderRPCServiceClients(services map[string]*Service, fullPackageName strin ) `) for _, service := range services { + if !config.IsGoRPC(service.Name) { + continue + } clientName := service.Name + "GoRPCClient" // Client type g.l(` @@ -655,9 +696,9 @@ func renderRPCServiceClients(services map[string]*Service, fullPackageName strin return nil } -func RenderGoTSRPCProxies(services map[string]*Service, longPackageName, packageName string) (gocode string, err error) { +func RenderGoTSRPCProxies(services map[string]*Service, longPackageName, packageName string, config *config.Target) (gocode string, err error) { g := newCode(" ") - err = renderTSRPCServiceProxies(services, longPackageName, packageName, g) + err = renderTSRPCServiceProxies(services, longPackageName, packageName, config, g) if err != nil { return } @@ -665,9 +706,9 @@ func RenderGoTSRPCProxies(services map[string]*Service, longPackageName, package return } -func RenderGoTSRPCClients(services map[string]*Service, longPackageName, packageName string) (gocode string, err error) { +func RenderGoTSRPCClients(services map[string]*Service, longPackageName, packageName string, config *config.Target) (gocode string, err error) { g := newCode(" ") - err = renderTSRPCServiceClients(services, longPackageName, packageName, g) + err = renderTSRPCServiceClients(services, longPackageName, packageName, config, g) if err != nil { return } @@ -675,9 +716,9 @@ func RenderGoTSRPCClients(services map[string]*Service, longPackageName, package return } -func RenderGoRPCProxies(services map[string]*Service, longPackageName, packageName string) (gocode string, err error) { +func RenderGoRPCProxies(services map[string]*Service, longPackageName, packageName string, config *config.Target) (gocode string, err error) { g := newCode(" ") - err = renderRPCServiceProxies(services, longPackageName, packageName, g) + err = renderGoRPCServiceProxies(services, longPackageName, packageName, config, g) if err != nil { return } @@ -685,9 +726,9 @@ func RenderGoRPCProxies(services map[string]*Service, longPackageName, packageNa return } -func RenderGoRPCClients(services map[string]*Service, longPackageName, packageName string) (gocode string, err error) { +func RenderGoRPCClients(services map[string]*Service, longPackageName, packageName string, config *config.Target) (gocode string, err error) { g := newCode(" ") - err = renderRPCServiceClients(services, longPackageName, packageName, g) + err = renderGoRPCServiceClients(services, longPackageName, packageName, config, g) if err != nil { return } diff --git a/typescript.go b/typescript.go index 15635cf..804984f 100644 --- a/typescript.go +++ b/typescript.go @@ -285,7 +285,7 @@ func ucFirst(str string) string { return constPrefix } -func RenderTypeScriptServices(moduleKind config.ModuleKind, services map[string]*Service, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, tsModuleName string) (typeScript string, err error) { +func RenderTypeScriptServices(moduleKind config.ModuleKind, services map[string]*Service, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, target *config.Target) (typeScript string, err error) { ts := newCode(" ") if !SkipGoTSRPC { @@ -299,7 +299,7 @@ func RenderTypeScriptServices(moduleKind config.ModuleKind, services map[string] request.open('POST', endPoint + "/" + encodeURIComponent(method), true); // this causes problems, when the browser decides to do a cors OPTIONS request // request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); - request.send(JSON.stringify(args)); + request.send(JSON.stringify(args)); request.onload = function() { if (request.status == 200) { try { @@ -311,7 +311,7 @@ func RenderTypeScriptServices(moduleKind config.ModuleKind, services map[string] } else { err(request); } - }; + }; request.onerror = function() { err(request); }; @@ -323,11 +323,16 @@ func RenderTypeScriptServices(moduleKind config.ModuleKind, services map[string] if !SkipGoTSRPC { ts.l("} // close") } - ts.l("module " + tsModuleName + " {") + ts.l("module " + target.TypeScriptModule + " {") ts.ind(1) } for endPoint, service := range services { + // Check if we should render this service as ts rcp + // Note: remove once there's a separate gorcp generator + if !target.IsTSRPC(service.Name) { + continue + } err = renderService(SkipGoTSRPC, moduleKind, service, endPoint, mappings, scalarTypes, ts) if err != nil { return