A trivial bridge between Go functions and JSON consumers over HTTP.
Is this the simplest way of communication Go structs/funcs with JSON talking
clients?
This is a work in progress.
Installation
go get -u github.com/xiam/bridge
Usage
Something simple, a Go function that sums arguments.
package main
import (
"fmt"
"github.com/xiam/bridge"
)
func Sum(a ...int) int64 {
z := int64(0)
for i := 0; i < len(a); i++ {
z = z + int64(a[i])
}
return z
}
// You don't need to change your code, no need to change anything at all, just
// spawn a server and map a route to the function!
func main() {
// Creating server
srv := bridge.New("tcp", "127.0.0.1:8088")
// Mapping "sum" to the function Sum
srv.AddRoute("/sum", Sum)
// Starting server
err := srv.Start()
if err != nil {
fmt.Errorf("Error: %v\n", err)
}
}
An example on how to call the above Go function using curl and getting the
result:
$ curl '127.0.0.1:8088/sum/78/45'
123
A more complex example, this time we'll use a Go struct instead of a function.
All public methods on this struct will become available for consuming when you
map the struct:
package main
import (
"fmt"
"github.com/xiam/bridge"
)
type Simple struct {
// Set operator with a POST parameter.
Operator string
}
// Pass arguments with slash separated segments.
func (self *Simple) Exec(a ...int) (float64, error) {
fmt.Printf("Received operator: %v\n", self.Operator)
z := float64(0)
switch self.Operator {
case "+":
{
for i := 0; i < len(a); i++ {
z = z + float64(a[i])
}
return z, nil
}
case "-":
{
for i := 0; i < len(a); i++ {
z = z - float64(a[i])
}
return z, nil
}
case "*":
{
z = 1.0
for i := 0; i < len(a); i++ {
z = z * float64(a[i])
}
return z, nil
}
case "/":
{
z = 1.0
for i := 0; i < len(a); i++ {
z = z / float64(a[i])
}
return z, nil
}
}
return z, fmt.Errorf(`No POST[operator] given. Try "+" or "-"`)
}
func main() {
// Creating a new server
srv := bridge.New("tcp", "127.0.0.1:8088")
// Mapping "/" to a new instance of *Simple
// All public methods become available.
srv.AddRoute("/", &Simple{})
// Starting server.
err := srv.Start()
if err != nil {
fmt.Errorf("Error: %v\n", err)
}
}
This call that multiplies 76...21 and outputs 5040.
$ curl '127.0.0.1:8088/exec/1/2/3/4/5/6/7' -d 'operator=*'
5040
Another piece of code that links functions from the strings
package.
package main
import (
"fmt"
"github.com/xiam/bridge"
"strings"
)
func main() {
srv := bridge.New("tcp", "127.0.0.1:8088")
srv.AddRoute("/strings/contains", strings.Contains)
srv.AddRoute("/strings/split", strings.Split)
srv.AddRoute("/strings/repeat", strings.Repeat)
err := srv.Start()
if err != nil {
fmt.Errorf("Error: %v\n", err)
}
}
Yes, you can use the strings
package over HTTP too:
$ curl '127.0.0.1:8088/strings/contains/chocolate/lat'
true
$ curl '127.0.0.1:8088/strings/contains/chocolate/let'
false
Want to see actual JSON?
package main
import (
"errors"
"fmt"
"github.com/xiam/bridge"
)
type Demo struct {
Name string
LastName string
}
// This method will be mapped to /demo/hello_world
func (self *Demo) HelloWorld() (map[string]interface{}, error) {
if self.LastName != "Smith" {
return nil, errors.New(`Your last name is not "Smith".`)
} else {
res := map[string]interface{}{
"success": "ok",
"message": fmt.Sprintf("Hello %s %s!", self.Name, self.LastName),
}
return res, nil
}
}
func main() {
srv := bridge.New("tcp", "127.0.0.1:8088")
srv.AddRoute("/demo", &Demo{})
err := srv.Start()
if err != nil {
fmt.Errorf("Error: %v\n", err)
}
}
Make it salute you!
$ curl 'http://127.0.0.1:8088/demo/hello_world' -d "name=John"
{"error":"Your last name is not \"Smith\"."}
$ curl 'http://127.0.0.1:8088/demo/hello_world' -d "name=John&last_name=Smith"
{"message":"Hello John Smith!","success":"ok"}
See more examples.
Documentation
See online docs.
License
Copyright (c) 2013 José Carlos Nieto, https://menteslibres.net/xiam
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.