Skip to content
A trivial bridge between Go functions and JSON consumers over HTTP.
Go
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
_examples
LICENSE
README.md
main.go
main_test.go

README.md

github.com/xiam/bridge

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.

Something went wrong with that request. Please try again.