{"id":15393863,"url":"https://github.com/mitchellh/protostructure","last_synced_at":"2025-04-06T22:10:48.619Z","repository":{"id":57517093,"uuid":"244281778","full_name":"mitchellh/protostructure","owner":"mitchellh","description":"Encode and decode Go (golang) struct types via protocol buffers.","archived":false,"fork":false,"pushed_at":"2020-08-14T18:05:17.000Z","size":32,"stargazers_count":176,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T21:08:33.459Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitchellh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-02T04:42:32.000Z","updated_at":"2025-03-23T13:33:27.000Z","dependencies_parsed_at":"2022-09-15T21:22:41.432Z","dependency_job_id":null,"html_url":"https://github.com/mitchellh/protostructure","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fprotostructure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fprotostructure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fprotostructure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fprotostructure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitchellh","download_url":"https://codeload.github.com/mitchellh/protostructure/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247557767,"owners_count":20958047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T15:20:36.780Z","updated_at":"2025-04-06T22:10:48.598Z","avatar_url":"https://github.com/mitchellh.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# protostructure [![Godoc](https://godoc.org/github.com/mitchellh/protostructure?status.svg)](https://godoc.org/github.com/mitchellh/protostructure)\n\nprotostructure is a Go library for encoding and decoding a `struct`\n_type_ over the wire.\n\nThis library is useful when you want to send arbitrary structures\nover protocol buffers for behavior such as configuration decoding\n(`encoding/json`, etc.), validation (using packages that use tags), etc.\nThis works because we can reconstruct the struct type dynamically using\n`reflect` including any field tags.\n\nThis library only sends the structure of the struct, not the _value_.\nIf you want to send the value, you should build your protocol buffer\nmessage in such a way that it encodes that somehow using something\nsuch as JSON.\n\n## Installation\n\nStandard `go get`:\n\n```\n$ go get github.com/mitchellh/protostructure\n```\n\n## Usage \u0026 Example\n\nFor usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/protostructure).\n\nA quick code example is shown below using both the imaginary proto file\nand the Go code that uses it.\n\n```proto\nsyntax = \"proto3\";\npackage myapp;\nimport \"protostructure.proto\";\n\n// Response is an example response structure for an RPC endpoint.\nmessage Response {\n\tprotostructure.Struct config = 1;\n}\n```\n\n```go\ntype Config struct {\n\tName string            `json:\"name\"`\n\tMeta map[string]string `json:\"metadata\"`\n\tPort []*Port           `json:\"ports\"`\n}\n\ntype Port struct {\n\tNumber uint `json:\"number\"`\n\tDesc   string `json:\"desc\"`\n}\n\n// You can encode the structure on one side:\nmessage, err := protostructure.Encode(Config{})\n\n// And you can use the structure on the other side. Imagine resp\n// is populated using some protobuf RPC such as gRPC.\nval, err := protostructure.New(resp.Config)\njson.Unmarshal([]byte(`{\n\t\"name\": \"example\",\n\t\"meta\": { \"env\": \"prod\" },\n\t\"ports\": [\n\t\t{ \"number\": 8080 },\n\t\t{ \"number\": 8100, desc: \"backup\" },\n\t]\n}`, val)\n\n// val now holds the same structure dynamically. You can pair with other\n// libraries such as https://github.com/go-playground/validator to also\n// send validation using this library.\n```\n\n## Limitations\n\nThere are several limitations on the structures that can be encoded.\nSome of these limitations are fixable but the effort hasn't been put in\nwhile others are fundamental due to the limitations of Go currently:\n\n  * Circular references are not allowed between any struct types.\n  * Embedded structs are not supported\n  * Methods are not preserved, and therefore interface implementation\n    is not known. This is also an important detail because custom callbacks\n    such as `UnmarshalJSON` may not work properly.\n  * Field types cannot be: interfaces, channels, functions\n  * Certain stdlib types such as `time.Time` currently do not encode well.\n\n## But... why?\n\nThe real world use case that led to the creation of this library was\nto facilitate decoding and validating configuration for plugins via\n[go-plugin](https://github.com/hashicorp/go-plugin), a plugin system for\nGo that communicates using [gRPC](https://grpc.io).\n\nThe plugins for this particular program have dynamic configuration structures\nthat were decoded using an `encoding/json`-like interface (struct tags) and\nvalidated using [`go-playground/validator`](https://github.com/go-playground/validator)\nwhich also uses struct tags. Using protostructure, we can send the configuration\nstructure across the wire, decode and validate the configuration in the host process,\nand report more rich errors that way.\n\nAnother reason we wanted to ship the config structure vs. ship the\nconfig is because the actual language we are using for configuration\nis [HCL](https://github.com/hashicorp/hcl) which supports things like\nfunction calls, logic, and more and shipping that runtime across is\nmuch, much more difficult.\n\nThis was extracted into a separate library because the ability to\nencode a Go structure (particulary to include tags) seemed more generally\nuseful, although rare.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchellh%2Fprotostructure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitchellh%2Fprotostructure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchellh%2Fprotostructure/lists"}