Git Product home page Git Product logo

protostructure's Introduction

protostructure Godoc

protostructure is a Go library for encoding and decoding a struct type over the wire.

This library is useful when you want to send arbitrary structures over protocol buffers for behavior such as configuration decoding (encoding/json, etc.), validation (using packages that use tags), etc. This works because we can reconstruct the struct type dynamically using reflect including any field tags.

This library only sends the structure of the struct, not the value. If you want to send the value, you should build your protocol buffer message in such a way that it encodes that somehow using something such as JSON.

Installation

Standard go get:

$ go get github.com/mitchellh/protostructure

Usage & Example

For usage and examples see the Godoc.

A quick code example is shown below using both the imaginary proto file and the Go code that uses it.

syntax = "proto3";
package myapp;
import "protostructure.proto";

// Response is an example response structure for an RPC endpoint.
message Response {
	protostructure.Struct config = 1;
}
type Config struct {
	Name string            `json:"name"`
	Meta map[string]string `json:"metadata"`
	Port []*Port           `json:"ports"`
}

type Port struct {
	Number uint `json:"number"`
	Desc   string `json:"desc"`
}

// You can encode the structure on one side:
message, err := protostructure.Encode(Config{})

// And you can use the structure on the other side. Imagine resp
// is populated using some protobuf RPC such as gRPC.
val, err := protostructure.New(resp.Config)
json.Unmarshal([]byte(`{
	"name": "example",
	"meta": { "env": "prod" },
	"ports": [
		{ "number": 8080 },
		{ "number": 8100, desc: "backup" },
	]
}`, val)

// val now holds the same structure dynamically. You can pair with other
// libraries such as https://github.com/go-playground/validator to also
// send validation using this library.

Limitations

There are several limitations on the structures that can be encoded. Some of these limitations are fixable but the effort hasn't been put in while others are fundamental due to the limitations of Go currently:

  • Circular references are not allowed between any struct types.
  • Embedded structs are not supported
  • Methods are not preserved, and therefore interface implementation is not known. This is also an important detail because custom callbacks such as UnmarshalJSON may not work properly.
  • Field types cannot be: interfaces, channels, functions
  • Certain stdlib types such as time.Time currently do not encode well.

But... why?

The real world use case that led to the creation of this library was to facilitate decoding and validating configuration for plugins via go-plugin, a plugin system for Go that communicates using gRPC.

The plugins for this particular program have dynamic configuration structures that were decoded using an encoding/json-like interface (struct tags) and validated using go-playground/validator which also uses struct tags. Using protostructure, we can send the configuration structure across the wire, decode and validate the configuration in the host process, and report more rich errors that way.

Another reason we wanted to ship the config structure vs. ship the config is because the actual language we are using for configuration is HCL which supports things like function calls, logic, and more and shipping that runtime across is much, much more difficult.

This was extracted into a separate library because the ability to encode a Go structure (particulary to include tags) seemed more generally useful, although rare.

protostructure's People

Contributors

mitchellh avatar shammishailaj avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.