{"id":17681748,"url":"https://github.com/jgaskins/grpc","last_synced_at":"2025-04-14T05:35:37.856Z","repository":{"id":54619979,"uuid":"237868364","full_name":"jgaskins/grpc","owner":"jgaskins","description":"Pure-Crystal implementation of gRPC","archived":false,"fork":false,"pushed_at":"2024-06-25T01:12:16.000Z","size":57,"stargazers_count":79,"open_issues_count":9,"forks_count":12,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-02T00:36:48.662Z","etag":null,"topics":["crystal","grpc","protobuf"],"latest_commit_sha":null,"homepage":"","language":"Crystal","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/jgaskins.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-03T02:10:41.000Z","updated_at":"2025-03-25T13:40:45.000Z","dependencies_parsed_at":"2024-10-24T10:56:55.879Z","dependency_job_id":"732af61e-cc90-4fbc-9c3b-e8a97cf1fc03","html_url":"https://github.com/jgaskins/grpc","commit_stats":{"total_commits":39,"total_committers":5,"mean_commits":7.8,"dds":"0.33333333333333337","last_synced_commit":"4535b56ebdfa9c12e7f0af8e865b36212e0796cc"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgaskins%2Fgrpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgaskins%2Fgrpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgaskins%2Fgrpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgaskins%2Fgrpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jgaskins","download_url":"https://codeload.github.com/jgaskins/grpc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248829229,"owners_count":21168174,"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":["crystal","grpc","protobuf"],"created_at":"2024-10-24T09:12:03.609Z","updated_at":"2025-04-14T05:35:37.837Z","avatar_url":"https://github.com/jgaskins.png","language":"Crystal","funding_links":[],"categories":["Crystal"],"sub_categories":[],"readme":"# GRPC\n\nThis project is a pure-Crystal implementation of gRPC.\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n   ```yaml\n   dependencies:\n     grpc:\n       github: jgaskins/grpc\n   ```\n\n2. Run `shards install`\n\n3. Make sure you have Google's `grpc` tools installed\n\n   - macOS: `brew install grpc`\n\n## Usage\n\n1. Write a `protos/hello_world.proto` file that contains a `service` entry and any message types it depends on:\n\n   ```protobuf\n   syntax = \"proto3\";\n\n   service HelloWorld {\n     rpc MethodName (TheRequest) returns (TheResponse) {}\n   }\n\n   message TheRequest {\n     string text = 1;\n   }\n\n   message TheResponse {\n     string data = 1;\n   }\n   ```\n\n2. Compile the `.proto` files. If your messages are defined in `protos/hello_world.proto` and you want your code written out to the app's `src/protobufs` directory, use the following command:\n   \n   ```\n   $ protoc -I protos \\\n       --grpc_out=src/protobufs \\\n       --crystal_out=src/protobufs \\\n       --plugin=protoc-gen-grpc=bin/grpc_crystal \\\n       --plugin=protoc-gen-crystal=bin/protoc-gen-crystal \\\n       protos/hello_world.proto\n   ```\n\n   This compiles both the service and the messages.\n\n## Server\n\nTo handle gRPC requests for the above service definition, we need 3 things:\n\n- One or more service handlers\n- A gRPC server\n- An HTTP/2 server to wrap the gRPC server (gRPC runs on top of HTTP/2)\n\n### Service Handlers\n\nServices are compiled into abstract classes with the `protoc` command above. To implement a handler for a given service, we subclass the generated abstract class, defining the methods with snake_cased names:\n\n```crystal\nrequire \"./protobufs/hello_world_services.pb\"\nrequire \"./protobufs/hello_world.pb\"\n\nclass HelloWorldHandler \u003c HelloWorld\n  # You can define your own initialize method to inject dependencies\n\n  def method_name(request : TheRequest) : TheResponse\n    unless request.text.presence\n      raise GRPC::BadStatus.new(:invalid_argument, \"Text cannot be blank.\")\n    end\n\n    TheResponse.new(data: \"Hello #{request.text}\")\n  end\nend\n```\n\nThe methods defined in the service declaration are required to be implemented by this class. Your program will not compile without them.\n\n### gRPC Server\n\n```crystal\nrequire \"grpc\"\ngrpc = GRPC::Server.new\ngrpc \u003c\u003c HelloWorldHandler.new\n```\n\nYou can add as many service handlers as you like.\n\n### HTTP/2 Server\n\nThe `HTTP2::Server` works similarly to `HTTP::Server`:\n\n```crystal\nrequire \"grpc/http2\"\nserver = HTTP2::ClearTextServer.new([grpc]) # TLS isn't supported yet\nserver.listen \"0.0.0.0\", 50000\n```\n\nAnd now gRPC requests for your `HelloWorld` service will be handled by `HelloWorldHandler`.\n\n## Client\n\nTo write a client to consume the `HelloWorld` service, you simply use a `Stub`:\n\n```crystal\n# Load the service and message definitions\nrequire \"./protobufs/hello_world_services.pb\"\nrequire \"./protobufs/hello_world.pb\"\n\nHelloWorldService = HelloWorld::Stub.new(\"localhost\", 50000)\n\n# from anywhere in your app\npp HelloWorldService.method_name(TheRequest.new(text: \"foo\"))\n# =\u003e TheResponse(@data=\"Hello foo\")\n```\n\n## Limitations\n\nThis implementation currently only supports \"simple gRPC\" — send a synchronous request, get a synchronous response. Streaming is not yet implemented.\n\n## Roadmap\n\n## Development\n\nTODO: Write development instructions here\n\n## Contributing\n\n1. Fork it (\u003chttps://github.com/jgaskins/grpc/fork\u003e)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Jamie Gaskins](https://github.com/jgaskins) - creator and maintainer\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgaskins%2Fgrpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjgaskins%2Fgrpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgaskins%2Fgrpc/lists"}