{"id":13837321,"url":"https://github.com/qaware/protocurl","last_synced_at":"2025-04-12T22:20:47.424Z","repository":{"id":37778097,"uuid":"472779112","full_name":"qaware/protocurl","owner":"qaware","description":"protoCURL is cURL for Protobuf: The command-line tool for interacting with Protobuf over HTTP REST endpoints using human-readable text formats","archived":false,"fork":false,"pushed_at":"2025-03-31T17:45:03.000Z","size":712,"stargazers_count":244,"open_issues_count":16,"forks_count":10,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-04T01:23:33.232Z","etag":null,"topics":["cli","curl","protobuf","protocol-buffers","rest","rest-client"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qaware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-22T13:26:23.000Z","updated_at":"2025-03-31T17:45:05.000Z","dependencies_parsed_at":"2023-10-02T18:09:15.779Z","dependency_job_id":"2a913ac2-68ca-4f02-bfe4-6e26feea8e9b","html_url":"https://github.com/qaware/protocurl","commit_stats":{"total_commits":366,"total_committers":8,"mean_commits":45.75,"dds":0.5792349726775956,"last_synced_commit":"026ea3533b6f64703c3110600f223f62a8b38ec9"},"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qaware%2Fprotocurl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qaware%2Fprotocurl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qaware%2Fprotocurl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qaware%2Fprotocurl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qaware","download_url":"https://codeload.github.com/qaware/protocurl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248638469,"owners_count":21137664,"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":["cli","curl","protobuf","protocol-buffers","rest","rest-client"],"created_at":"2024-08-04T15:01:06.357Z","updated_at":"2025-04-12T22:20:47.398Z","avatar_url":"https://github.com/qaware.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"\u003c!--\n================= AUTOGENERATED FILE =================\n================= DO NOT EDIT THIS   =================\n\nIf you want to edit this, then change doc/template.README.md instead.\n\n================= DO NOT EDIT THIS   =================\n================= AUTOGENERATED FILE =================\n--\u003e\n\n# protoCURL\n\n[![Tests Status](https://github.com/qaware/protocurl/actions/workflows/test.yml/badge.svg)](https://github.com/qaware/protocurl/actions/workflows/test.yml)\n[![GitHub Release (latest SemVer)](https://img.shields.io/github/v/release/qaware/protocurl?label=Release\u0026logoColor=white\u0026logo=GitHub\u0026sort=semver)](https://github.com/qaware/protocurl/releases)\n[![DockerHub Version (latest semver)](https://img.shields.io/docker/v/qaware/protocurl?label=Docker\u0026logo=Docker\u0026logoColor=white\u0026sort=semver)](https://hub.docker.com/r/qaware/protocurl/tags)\n\n[![Pull Requests](https://img.shields.io/github/issues-pr/qaware/protocurl?color=lightgreen\u0026label=Pull%20Requests)](https://github.com/qaware/protocurl/pulls)\n[![Pull Requests (closed)](https://img.shields.io/github/issues-pr-closed/qaware/protocurl?color=blue\u0026label=Pull%20Requests)](https://github.com/qaware/protocurl/pulls?q=is%3Apr+is%3Aclosed)\n\nprotoCURL is cURL for Protobuf: The command-line tool for interacting with Protobuf over HTTP REST endpoints using\nhuman-readable text formats.\n\n## Why?\n\nEvery data interchange format, which is used between service boundaries, benefits from a command-line-tool enabling one to directly talk to a service. We do not want to use a full-blown programming language and all its libraries just for quick and simple requests. Such a tool is very useful during development and debugging.\n\nText-based formats, like JSON and XML, can simply be used with tools like [curl](https://curl.se/) as the requests can be written by hand. However, since Protobuf is a binary-encoded format, writing these requests by hand is hard and cumbersome.\n\nHence, **protoCURL**.\n\nprotoCURL enables us to write requests in a human-readable textual-format while talking to a binary-encoded Protobuf over HTTP REST endpoint.\n\nWithout protoCURL, one would either need to duplicate the HTTP REST endpoints returning equivalent JSON/XML responses - or one needs to write custom code and run it from the IDE just to send simple requests. The first option is technical debt at its finest - and the second one is less ergonomic than using protoCURL.\n\nFor an introduction with an example: [Read the intro Blogpost](https://blog.qaware.de/posts/protocurl-intro)\n\nThis project reached the HackerNews frontpage when it was [posted on HackerNews in Feb 2023](https://news.ycombinator.com/item?id=34866155).\n\n## Install\n\n`protocurl` includes and uses a bundled `protoc` by default. It is recommended to install `curl` into PATH for\nconfigurable http requests. Otherwise `protocurl` will use a simple non-configurable fallback http implementation.\n\n`protocurl` uses [semantic versioning](https://semver.org/spec/v2.0.0.html) when new releases are versioned.\n\n### Native CLI\n\n**Archive**\n\n1. Download the latest release archive for your platform from https://github.com/qaware/protocurl/releases\n2. Extract the archive into a folder, e.g. `/opt/protocurl`.\n3. Add symlink to the binary in the folder. e.g. `ln -s /opt/protocurl/bin/protocurl /usr/bin/protocurl`\n   Or add the binary folder `/opt/protocurl/bin` to your system-wide path.\n4. Test it via `protocurl -h`\n\n**Debian .deb package**\n\n1. Download the latest release `.deb` for your architecture from https://github.com/qaware/protocurl/releases\n2. Install dependency curl: `sudo apt install curl`\n3. Install `sudo dpkg -i \u003cdownloaded-release\u003e.deb`\n4. Test it via `protocurl -h`\n\n**Alpine .apk package**\n\n1. Download the latest release `.apk` for your architecture from https://github.com/qaware/protocurl/releases\n2. Install dependencies curl and gcompat: `sudo apk add curl gcompat`\n3. Install `sudo apk add --allow-untrusted \u003cdownloaded-release\u003e.apk`\n4. Test it via `protocurl -h`\n\n### Docker\n\nSimply run `docker run -v \"/path/to/proto/files:/proto\" qaware/protocurl \u003cargs\u003e`. See [Quick Start](#quick-start) for\nhow to use.\n\n## Quick Start\n\nAfter installing `protocurl` a request is as simple as:\n\n```bash\nprotocurl -I test/proto -i ..HappyDayRequest -o ..HappyDayResponse \\\n  -u http://localhost:8080/happy-day/verify -d \"includeReason: true\"\n```\n\nwhere\n\n* `-I test/proto` points to the directory of protobuf files of your service\n    * with docker one needs to instead mount the directory to `/proto` via `-v $PWD/test/proto:/proto`\n* `-i ..HappyDayRequest` and `-o ..HappyDayResponse` are Protobuf message types. The `..` makes protocurl infer their full package paths.\n* `-u http://localhost:8080/happy-day/verify` is the url to the HTTP REST endpoint accepting and returning binary protobuf\n  payloads\n    * with docker one may additionally need `--network host`\n* `-d \"includeReason: true\"` is the protobuf payload in Protobuf [Text](#protobuf-text-format)\n  or [JSON](#protobuf-json-format) Format\n\nThen protocurl will\n\n* encode the textual Protobuf message to a binary request payload\n* send the binary request to the HTTP REST endpoint (via `curl`, if possible) and receive the binary response payload\n* decode the binary response payload back to text and display it\n\nand produce the following output:\n\n```\n=========================== POST Request  Text    =========================== \u003e\u003e\u003e\nincludeReason: true\n=========================== POST Response Text    =========================== \u003c\u003c\u003c\nisHappyDay: true\nreason: \"Thursday is a Happy Day! ⭐\"\nformattedDate: \"Thu, 01 Jan 1970 00:00:00 GMT\"\n```\n\nSee below for usage notes and [EXAMPLES.md](EXAMPLES.md) for more information.\n\n## Usage and Example\n\nSee [usage notes](doc/generated.usage.txt), [EXAMPLES.md](EXAMPLES.md) as well as the [intro Blogpost](https://blog.qaware.de/posts/protocurl-intro).\n\n## Protobuf JSON Format\n\nprotoCURL supports the [Protobuf JSON Format](https://protobuf.dev/programming-guides/proto3/#json). Note,\nthat the JSON format is not a straightforward 1:1 mapping as it is in the case of the Protobuf Text Format (described\nbelow). For instance,\nthe [JSON mapping for timestamp.proto](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/timestamp.proto)\nuses a human-readable string representation, whereas the payload itself and the text format use a representation with\nseconds and nanoseconds.\n\n## Protobuf Text Format\n\nAside from JSON, Protobuf primarily and natively supports a text format which represents the fields 1:1 like in the\nwire-format. For instance, repeated fields are condensed into an array in the JSON format - whereas they are simply '\nrepeated' without an array type in the text format.\n\nFor instance, for the following .proto file\n\n```\nsyntax = \"proto3\";\n\nimport \"google/protobuf/timestamp.proto\";\n\nmessage HappyDayRequest {\n  google.protobuf.Timestamp date = 1;\n  bool includeReason = 2;\n\n  double myDouble = 3;\n  int64 myInt64 = 5;\n  repeated string myString = 6;\n  repeated NestedMessage messages = 9;\n}\n\nmessage NestedMessage {\n  Foo fooEnum = 1;\n  repeated int32 i = 4;\n}\n\nenum Foo {\n  BAR = 0;\n  BAZ = 1;\n}\n```\n\na `HappyDayRequest` message in text format might look like this:\n\n```\nincludeReason: true,\nmyInt64: 123123123123,\nmyString: \"hello world\"\nmyString: 'single quotes are also possible'\nmyDouble: 123.456\nmessages: { fooEnum: BAR, i: 0, i: 1, i: 1337 },\nmessages: { i: 15, fooEnum: BAZ, i: -1337 },\nmessages: { },\ndate: { seconds: 123, nanos: 321 }\n```\n\nIn summary:\n\n- No encapsulating `{ ... }` are used for the top level message (in contrast to JSON).\n- fields are comma separated and described via `\u003cfieldname\u003e: \u003cvalue\u003e`.\n    - Strictly speaking, the commas are optional and whitespace is sufficient\n- repeated fields are simply repeated multiple times (instead of using an array) and they do not need to appear\n  consecutively.\n- nested messages are described with `{ ... }` opening a new context and describing their fields recursively\n- scalar values are describes similar to JSON. Single and double quotes are both possible for strings.\n- enum values are referenced by their name\n- built-in messages (such\n  as [google.protobuf.Timestamp](https://protobuf.dev/reference/protobuf/google.protobuf/#timestamp)\n  are described just like user-defined custom messages via `{ ... }` and their message fields\n\nThe text format is defined in the [Protobuf: Text Format Language Specification](https://protobuf.dev/reference/protobuf/textformat-spec/).\n\n## Maintainer\n\nThe project was created and is currently maintained by [GollyTicker](https://github.com/GollyTicker).\n\n[qaware](https://github.com/qaware/) provided initial sponsorship for the project.\n\n## Development\n\nFor development it is recommended to use the a bash-like Terminal either natively (Linux, Mac) or via MinGW on Windows.\n\nAbout the CI/CD tests: [TESTS.md](TESTS.md)\n\nHow to make a release: [RELEASE.md](RELEASE.md)\n\n#### Setup\n\n- As for script utilities, one needs `bash`, `jq`, `zip`, `unzip` and `curl`.\n\nPlease make sure, that docker including the docker compose plugin is installed. The setup works with docker `v26.1.3` and docker compose `v2.27.0`,\n\nRunning the tests will download the protoc binaries on the first invocation automatically.\n\nFor development the `generated-local.Dockerfile` (via [generate-local.Dockerfile.sh](dev/generate-local.Dockerfile.sh)) is used.\nTo build the image simply run `source test/suite/setup.sh` and then `buildProtocurl`\n\n#### Updating Docs after changes\n\nGenerate the main docs (.md files etc.) in bash/WSL via `doc/generate-docs.sh \u003cabsolute-path-to-protocurl-repository\u003e`.\n\nOnce a pull request is ready, run this to generate updated docs.\n\n## Enhancements and Bugs\n\nSee [issues](https://github.com/qaware/protocurl/issues).\n\n## FAQ\n\n- **How is protocurl different from grpccurl?** [grpccurl](https://github.com/fullstorydev/grpcurl) only works with gRPC\n  services with corresponding endpoints. However, classic REST HTTP endpoints with binary Protobuf payloads are only\n  possible with `protocurl`.\n- **Why is the use of a runtime curl recommended with protocurl?** curl is a simple, flexible and mature command line\n  tool to interact with HTTP endpoints. In principle, we could simply use the HTTP implementation provided by the host\n  programming language (Go) - and this is what we do if no curl was found in the PATH. However, as more people use\n  protocurl, they will request for more features - leading to a feature creep in such a 'simple' tool as protocurl. We\n  would like to avoid implementing the plentiful features which are necessary for a proper HTTP CLI tool, because HTTP\n  can be complex. Since is essentially what curl already does, we recommend using curl and all advanced features are\n  only possible with curl.\n- **What are some nice features of protocurl?**\n    - The implementation is well tested with end-2-end approval tests (see [TESTS.md](TESTS.md)). All features are\n      tested based on their effect on the behavior/output. Furthermore, there are also a few cross-platform native CI\n      tests running on Windows and MacOS runners.\n    - The build and release process is optimised for minimal maintenance efforts. During release build, the latest\n      versions of many dependencies are taken automatically (by looking up the release tags via the GitHub API).\n    - The documentation and examples are generated via scripts and enable one to update the examples automatically\n      rather than manually. The consistency of the outputs of the code with the checked in documentation is further\n      tested in CI.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqaware%2Fprotocurl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqaware%2Fprotocurl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqaware%2Fprotocurl/lists"}